Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libTools / src / org / gvsig / tools / exception / BaseException.java @ 23743

History | View | Annotate | Download (9.28 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Gobernment (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 */
26
package org.gvsig.tools.exception;
27

    
28
import java.lang.reflect.Method;
29
import java.util.Iterator;
30
import java.util.Map;
31

    
32
/**
33
 * 
34
 * Esta clase esta pensada para actuar como clase base para las excepciones que
35
 * se lanzan dentro del proyecto de gvSIG.
36
 * 
37
 * A?ade la implementacion necesaria para disponer de mensajes de error
38
 * internacionalizables, a traves del metodo getLocalizedMessage, asi como una
39
 * serie de metodos que nos permiten obtener los mesanes de error de la cadena
40
 * de excepciones enlazadas a traves de su "causa", asi como utilidades que
41
 * permitan recorrer de forma comoda esta cadena de excepciones por medio de un
42
 * Iterador.
43
 * 
44
 * @author Equipo de desarrollo de gvSIG.
45
 * 
46
 */
47
public abstract class BaseException extends Exception implements IBaseException {
48
        private final static String BLANKS ="                                                                                                     ";
49
        private static IExceptionTranslator translator= null;
50

    
51
        protected String messageKey;
52

    
53
        /**
54
     * TODO: remove the variable, use the Exception get/setMessage() instead.
55
     */
56
        protected String formatString;
57

    
58
        /**
59
         * Unique code of error.
60
         */
61
        protected long code;
62
        
63
    /**
64
     * Empty constructor, don't use it anymore.
65
     * 
66
     * @deprecated
67
     */
68
    public BaseException() {
69
    }
70

    
71
    /**
72
     * Constructs a BaseException with a default message format, a key to find a
73
     * localized message format, and a unique code to identify the exception.
74
     * 
75
     * @param message
76
     *            the default messageFormat to describe the exception
77
     * @param key
78
     *            the key to use to search a localized messageFormnata
79
     * @param code
80
     *            the unique code to identify the exception
81
     */
82
    public BaseException(String message, String key, long code) {
83
        super(message);
84
        this.formatString = message;
85
        this.messageKey = key;
86
        this.code = code;
87
    }
88

    
89
    /**
90
     * Constructs a BaseException with a default message format, a key to find a
91
     * localized message format, and a unique code to identify the exception.
92
     * 
93
     * @param message
94
     *            the default messageFormat to describe the exception
95
     * @param cause
96
     *            the original cause of the exception
97
     * @param key
98
     *            the key to use to search a localized messageFormnata
99
     * @param code
100
     *            the unique code to identify the exception
101
     */
102
    public BaseException(String message, Throwable cause, String key, long code) {
103
        super(message, cause);
104
        this.formatString = message;
105
        this.messageKey = key;
106
        this.code = code;
107
    }
108

    
109
        /**
110
     * Returns the format string received in the parameter with its keys
111
     * replaced with the corresponding values of the map.
112
     * 
113
     * @param formatString
114
     * @param values
115
     *            map
116
     * @return string formatted
117
     */
118
    private String format(String formatString, Map values) {
119
        if (values != null) {
120

    
121
            // If there is no message format, create a text with the values.
122
            if (formatString == null) {
123
                return "values = ".concat(values.toString());
124
            } else {
125
                // Replace the keys as variables with the values in the Map
126
                Iterator keys = values.keySet().iterator();
127
                String message = formatString;
128
                while (keys.hasNext()) {
129
                    String key = (String) keys.next();
130
                    String varName = "%\\(".concat(key).concat("\\)");
131
                    message = message.replaceAll(varName, (String) values
132
                            .get(key));
133
                }
134
                return message;
135
            }
136
        }
137
        // Return the original format message in any other case
138
        return formatString;
139
    }
140

    
141
        /* (non-Javadoc)
142
         * @see java.lang.Throwable#getMessage()
143
         */
144
        public String getMessage() {
145
                return format(this.formatString, values());
146
        }
147

    
148
        public String getMessage(int indent) {
149
                return insertBlanksAtStart(format(formatString, values()),indent);
150
        }
151

    
152
        public String getLocalizedMessage() {
153
                return getLocalizedMessage(translator,0);
154
        }
155

    
156
        public String getLocalizedMessage(IExceptionTranslator translator, int indent){
157

    
158
                String fmt;
159
                if (translator == null){
160
                        translator = BaseException.translator;
161
                }
162
                if (translator == null){
163
                        fmt = getFormatString();
164
                } else {
165
                        fmt = getMessageKey();
166
                        if (fmt == null){
167
                                fmt = getFormatString();
168
                        } else {
169
                                fmt = translator.getText(fmt);
170
                        }
171
                }
172
                return insertBlanksAtStart(format(fmt,values()),indent);
173
        }
174

    
175
        public String getMessageStack() {
176
                return getMessageStack(0);
177
        }
178

    
179
        public String getMessageStack(int indent) {
180
                Iterator iter = this.iterator();
181
                StringBuffer msgBuffer = new StringBuffer();
182
                int i = 1;
183
                while (iter.hasNext()){
184
                    Exception ex = ((Exception) iter.next());
185
                        
186
            if (msgBuffer.length() > 0) {
187
                msgBuffer.append("\n");
188
            }
189
                        
190
                        if ( ex instanceof BaseException ) {
191
                                BaseException bex = (BaseException) ex;
192
                                msgBuffer.append(bex.getMessage(indent * i));
193
                        } else {
194
                            msgBuffer.append(insertBlanksAtStart(ex.getMessage(), indent
195
                        * i));
196
                        }
197
                        
198
                        i++;
199
                }
200
                return msgBuffer.toString();
201
        }
202

    
203

    
204
        public String getLocalizedMessageStack() {
205
                return getLocalizedMessageStack(BaseException.translator,0);
206
        }
207

    
208
        public String getLocalizedMessageStack(IExceptionTranslator translator, int indent) {
209
                Iterator iter = this.iterator();
210
        StringBuffer msgBuffer = new StringBuffer();
211
        Exception ex;
212
        while (iter.hasNext()) {
213
            ex = ((Exception) iter.next());
214
            if (msgBuffer.length() > 0) {
215
                msgBuffer.append("\n");
216
            }
217

    
218
            if (ex instanceof BaseException) {
219
                BaseException bex = (BaseException) ex;
220
                msgBuffer.append(bex.getLocalizedMessage(translator, indent));
221
            } else {
222
                msgBuffer.append(ex.getLocalizedMessage());
223
            }
224
        }
225
        return msgBuffer.toString();
226
        }
227

    
228
        /**
229
         * Inserts blanks at the start of a string.
230
         *
231
         * @param str A string.
232
         * @param len Quantity of blanks to insert at the start of str.
233
         * @return A string compund by the quantity of blanks that
234
         *         len indicates and str.
235
         */
236
        static String insertBlanksAtStart(String str, int len){
237
        int blanksLen = len > BLANKS.length() ? BLANKS.length() : (len < 0 ? 0
238
                : len);
239

    
240
        return BLANKS.substring(0, blanksLen) + str;
241
        }
242

    
243
        public long getCode() {
244
                return this.code;
245
        }
246

    
247
        /**
248
         * Sets the exception's code.
249
         */
250
        public void setCode(long code) {
251
                this.code = code;
252
        }
253

    
254
        public String getFormatString() {
255
                return this.formatString;
256
        }
257

    
258
        /**
259
         * Sets the format string.
260
         *
261
         * @param formatString
262
         */
263
        public void setFormatString(String formatString) {
264
                this.formatString = formatString;
265
        }
266

    
267
        public String getMessageKey() {
268
                return this.messageKey;
269
        }
270

    
271
        /**
272
         * Sets the property messageKey.
273
         *
274
         * @param messageKey
275
         */
276
        public void setMessageKey(String messageKey) {
277
                this.messageKey = messageKey;
278
        }
279

    
280
        public Iterator iterator() {
281
                return new BaseExceptionIterator(this);
282
        }
283

    
284
        /**
285
         * @return A map that serves to replace in the format string
286
         * the keys with the corresponding values.
287
         */
288
        abstract protected Map values();
289

    
290
        /**
291
         * Sets the property translator.
292
         * @param translator It(He,She) is used to translate
293
         *        the messages associated with the exceptions.
294
         */
295
        public static void setTranslator(IExceptionTranslator translator){
296
                BaseException.translator = translator;
297
        }
298

    
299
        public static void setTranslator(Object translator){
300
                BaseException.translator = new TranslatorWraper(translator);
301
        }
302

    
303
        public String toString(){
304
                return format(this.formatString, values());
305
        }
306

    
307
}
308

    
309
class TranslatorWraper implements IExceptionTranslator {
310

    
311
        private Object translator = null;
312
        private Method method = null;
313

    
314
        public TranslatorWraper(Object translator) {
315
                Class theClass = translator.getClass();
316
                String s = "";
317

    
318
                this.translator = translator;
319
                try {
320
                        method = theClass.getMethod("getText",new Class[] { s.getClass() });
321
                } catch (Exception e) {
322
                        throw new RuntimeException("El objeto translator suministrado no tiene el metodo getText apropiado.", e);
323
                }
324

    
325
        }
326

    
327
        public String getText(String key) {
328
                try {
329
                        return (String)(method.invoke(translator,new String[] { key }));
330
                } catch (Exception e) {
331
                        return key;
332
                }
333
        }
334

    
335
}