1 /*
2 * Copyright (c) 2003-2008 by Cosylab d. d.
3 *
4 * This file is part of Java-Common.
5 *
6 * Java-Common is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Java-Common 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 Java-Common. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package com.cosylab.util;
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import javax.swing.Action;
26
27
28 /**
29 * This is the basic checked exceptions for the Java projects. In addition to
30 * normal Java checked exceptions it provides information about the computer
31 * where the exception has occured, as well as instance information about the
32 * object, throwing the exception. It also contains hooks for integration with
33 * other Java or framework serviecs, in the form of JavaHelp ID string and
34 * list of available Swing actions. Several important parameters that are
35 * determined at construction time, such as message, instance that is throwing
36 * the exception and the possible exception cause (if the exceptions are
37 * chained). Other parameters (such as helpID and actions) can be set after
38 * construction with their respective property setter methods. Most of the
39 * parameters are automatically set in the constructors of
40 * <code>CommonException</code>. If the derived exception wishes to override
41 * the parameters (such as thread, username, host etc), it may reset them in
42 * the derived constructor.
43 */
44 public class CommonException extends Exception implements CommonThrowable
45 {
46 protected static String host = null;
47 protected Thread thread = null;
48 protected Object instance = null;
49 protected HashMap values = new HashMap();
50 protected long timestamp = 0;
51 protected String helpID = null;
52 protected Action[] actions = null;
53 protected String username = null;
54
55 /** DOCUMENT ME! */
56 public String caughtIn = null;
57
58 /**
59 * Create a new instance of <code>CommonException</code>. This constructor
60 * should normally not be used since it carries no additional exception
61 * data.
62 */
63 protected CommonException()
64 {
65 super();
66 initialize();
67 }
68
69 /**
70 * Create an instance of <code>CommonException</code> with a with a
71 * specified message string. The construction is delegated to
72 * <code>super</code>.
73 *
74 * @param instance identifier of the instance throwing this exception
75 * @param s message to be printed together with the exception type when
76 * the <code>toString()</code> is called.
77 *
78 * @throws NullPointerException DOCUMENT ME!
79 */
80 public CommonException(Object instance, String s)
81 {
82 super(s);
83
84 if (instance == null) {
85 throw new NullPointerException("instance");
86 }
87
88 this.instance = instance;
89
90 /* must call initialize after the construction completes */
91 initialize();
92 }
93
94 /**
95 * Create an instance of <code>CommonException</code> by specifying both
96 * the string message and a <code>Throwable</code> object that represents
97 * the nested exception.
98 *
99 * @param instance identifier of the instance throwing this exception
100 * @param message a string message passed to <code>super</code>
101 * @param t an instance of <code>Throwable</code> that caused this to be
102 * thrown, can be <code>null</code>
103 *
104 * @throws NullPointerException DOCUMENT ME!
105 */
106 public CommonException(Object instance, String message, Throwable t)
107 {
108 super(message);
109
110 if (instance == null) {
111 throw new NullPointerException("instance");
112 }
113
114 this.instance = instance;
115
116 if (t != null) {
117 initCause(t);
118 }
119
120 /* must call initialize after the construction completes */
121 initialize();
122 }
123
124 /**
125 * Call this method if the exception is caught. Provides additional
126 * debugging info.
127 *
128 * @param target Object in which this exception was caught
129 * @param method method name without parenthesis of prefixed class name
130 */
131 public void caughtIn(Object target, String method)
132 {
133 assert (target != null);
134 assert (method != null);
135
136 if (target instanceof Class) {
137 caughtIn = ((Class)target).getName() + "::" + method;
138 } else {
139 caughtIn = target.getClass().getName() + "::" + method;
140 }
141 }
142
143 /**
144 * Returns the string description of where the exception has been caught or
145 * <code>null</code> if it has not been caught.
146 *
147 * @return String "className::method" of where exception has been caught
148 */
149 public String getCaughtIn()
150 {
151 return caughtIn;
152 }
153
154 /**
155 * Return the host this exception was generated on, if the JVM has access
156 * to such data.
157 *
158 * @return host name
159 */
160 public String getHost()
161 {
162 return host;
163 }
164
165 /**
166 * Return the parent exception that caused this exception to be thrown.
167 *
168 * @return parent exception
169 */
170 public Throwable getParent()
171 {
172 return getCause();
173 }
174
175 /**
176 * Returns the thread of execution in which the constructor of this
177 * exception was invoked. It is presupposed that exception is thrown in
178 * the same thread in which it was instantiated.
179 *
180 * @return thread in which this exception was instantiated
181 */
182 public Thread getThread()
183 {
184 return thread;
185 }
186
187 /**
188 * Returns the timestamp of the instantiation of this exception. Value is
189 * in the format returned by Java <code>System.currentTimeMillis()</code>.
190 *
191 * @return exception creation timestamp
192 */
193 public long getTimestamp()
194 {
195 return timestamp;
196 }
197
198 /**
199 * Returns a hashmap that can hold any key-value pairs that contain
200 * internal state of the system or specifically the <code>Object</code>
201 * instance raising this exception. Such data may help in debugging.
202 *
203 * <p>
204 * <b>Note!</b> Try to store serialized vaues not to introduce memory
205 * leaks.
206 * </p>
207 *
208 * @return additional data
209 */
210 public Map getValues()
211 {
212 return values;
213 }
214
215 /**
216 * Initializes the exception by filling in the host, timestamp, username,
217 * thread information. Subclasses should override this method (but still
218 * call it from the overridden version) to provide specialized
219 * initialization.
220 */
221 protected void initialize()
222 {
223 if (host == null) {
224 try {
225 host = java.net.InetAddress.getLocalHost().getHostName();
226 } catch (Exception ex) {
227 host = "N/A";
228 }
229 }
230
231 timestamp = System.currentTimeMillis();
232 thread = Thread.currentThread();
233
234 if (username == null) {
235 username = System.getProperty("user.name");
236 }
237 }
238
239 /**
240 * A shortcut to <code>getValues().put(Object key, Object value)</code>.
241 * Convenience method. Also converts value to string, not to produce
242 * memory leak.
243 *
244 * @param key key under which the value will be stored in the hashtable
245 * @param value value for the key, should have <code>toString()</code>
246 * overriden to allow for a more informative display
247 */
248 public void putValue(String key, Object value)
249 {
250 getValues().put(key, String.valueOf(value));
251 }
252
253 /**
254 * @see com.cosylab.util.CommonThrowable#getActions()
255 */
256 public Action[] getActions()
257 {
258 return actions;
259 }
260
261 /**
262 * @see com.cosylab.util.CommonThrowable#getHelpID()
263 */
264 public String getHelpID()
265 {
266 return helpID;
267 }
268
269 /**
270 * @see com.cosylab.util.CommonThrowable#getInstance()
271 */
272 public Object getInstance()
273 {
274 return instance;
275 }
276
277 /**
278 * @see com.cosylab.util.CommonThrowable#getUsername()
279 */
280 public String getUsername()
281 {
282 return username;
283 }
284
285 /**
286 * @see com.cosylab.util.CommonThrowable#getValue(String)
287 */
288 public Object getValue(String key)
289 {
290 return values.get(key);
291 }
292
293 /**
294 * Sets the actions returned by this exception. Such actions will be
295 * displayed in the GUI when the exception is caught and handled.
296 *
297 * @param actions actions to display
298 */
299 public void setActions(Action[] actions)
300 {
301 assert (actions != null);
302 this.actions = actions;
303 }
304
305 /**
306 * Sets the JavaHelp id under which the help for this specific exception
307 * instance may be looked up. This can be set for exceptions that happen
308 * more frequently (such as some improper configuration etc) to enable the
309 * users to get step-by-step help.
310 *
311 * @param helpID the JavaHelp identification
312 */
313 public void setHelpID(String helpID)
314 {
315 this.helpID = helpID;
316 }
317 }
318
319 /* __oOo__ */