001/* 002 * $Id: ErrorInfo.java 4170 2012-02-21 14:27:15Z kleopatra $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 022package org.jdesktop.swingx.error; 023 024import java.util.HashMap; 025import java.util.Map; 026import java.util.Properties; 027import java.util.logging.Level; 028 029import javax.swing.SwingUtilities; 030 031/** 032 * <p>A simple class that encapsulates all the information needed 033 * to report a problem using the automated report/processing system.</p> 034 * 035 * <p>All HTML referred to in this API refers to version 3.2 of the HTML 036 * markup specification.</p> 037 * 038 * @status REVIEWED 039 * @author Alexander Zuev 040 * @author rbair 041 */ 042public class ErrorInfo { 043 /** 044 * Short string that will be used as a error title 045 */ 046 private String title; 047 /** 048 * Basic message that describes incident 049 */ 050 private String basicErrorMessage; 051 /** 052 * Message that will fully describe the incident with all the 053 * available details 054 */ 055 private String detailedErrorMessage; 056 /** 057 * A category name, indicating where in the application this incident 058 * occurred. It is recommended that this be the same value as you 059 * would use when logging. 060 */ 061 private String category; 062 /** 063 * Optional Throwable that will be used as a possible source for 064 * additional information 065 */ 066 private Throwable errorException; 067 /** 068 * Used to specify how bad this error was. 069 */ 070 private Level errorLevel; 071 /** 072 * A Map which captures the state of the application 073 * at the time of an exception. This state is then available for error 074 * reports. 075 */ 076 private Map<String,String> state; 077 078 /** 079 * Creates a new ErrorInfo based on the provided data. 080 * 081 * @param title used as a quick reference for the 082 * error (for example, it might be used as the 083 * title of an error dialog or as the subject of 084 * an email message). May be null. 085 * 086 * @param basicErrorMessage short description of the problem. May be null. 087 * 088 * @param detailedErrorMessage full description of the problem. It is recommended, 089 * though not required, that this String contain HTML 090 * to improve the look and layout of the detailed 091 * error message. May be null. 092 * 093 * @param category A category name, indicating where in the application 094 * this incident occurred. It is recommended that 095 * this be the same value as you would use when logging. 096 * May be null. 097 * 098 * @param errorException <code>Throwable</code> that can be used as a 099 * source for additional information such as call 100 * stack, thread name, etc. May be null. 101 * 102 * @param errorLevel any Level (Level.SEVERE, Level.WARNING, etc). 103 * If null, then the level will be set to SEVERE. 104 * 105 * @param state the state of the application at the time the incident occured. 106 * The standard System properties are automatically added to this 107 * state, and thus do not need to be included. This value may be null. 108 * If null, the resulting map will contain only the System properties. 109 * If there is a value in the map with a key that also occurs in the 110 * System properties (for example: sun.java2d.noddraw), then the 111 * developer supplied value will be used. In other words, defined 112 * parameters override standard ones. In addition, the keys 113 * "System.currentTimeMillis" and "isOnEDT" are both defined 114 * automatically. 115 */ 116 public ErrorInfo(String title, String basicErrorMessage, String detailedErrorMessage, 117 String category, Throwable errorException, Level errorLevel, Map<String,String> state) { 118 this.title = title; 119 this.basicErrorMessage = basicErrorMessage; 120 this.detailedErrorMessage = detailedErrorMessage; 121 this.category = category; 122 this.errorException = errorException; 123 this.errorLevel = errorLevel == null ? Level.SEVERE : errorLevel; 124 this.state = new HashMap<String,String>(); 125 126 //first add all the System properties 127 try { 128 //NOTE: This is not thread safe because System.getProperties() does not appear 129 //to create a copy of the map. Thus, another thread could be modifying the System 130 //properties and the "state" at the time of this exception may not be 131 //accurate! 132 Properties props = System.getProperties(); 133 for (Map.Entry<Object, Object> entry : props.entrySet()) { 134 String key = entry.getKey() == null ? null : entry.getKey().toString(); 135 String val = entry.getKey() == null ? null : entry.getValue().toString(); 136 if (key != null) { 137 this.state.put(key, val); 138 } 139 } 140 } catch (SecurityException e) { 141 //probably running in a sandbox, don't worry about this 142 } 143 144 //add the automatically supported properties 145 this.state.put("System.currentTimeMillis", "" + System.currentTimeMillis()); 146 this.state.put("isOnEDT", "" + SwingUtilities.isEventDispatchThread()); 147 148 //now add all the data in the param "state". Thus, if somebody specified a key in the 149 //state map, it overrides whatever was in the System map 150 if (state != null) { 151 for (Map.Entry<String,String> entry : state.entrySet()) { 152 this.state.put(entry.getKey(), entry.getValue()); 153 } 154 } 155 } 156 157 /** 158 * Gets the string to use for a dialog title or other quick reference. Used 159 * as a quick reference for the incident. For example, it might be used as the 160 * title of an error dialog or as the subject of an email message. 161 * 162 * @return quick reference String. May be null. 163 */ 164 public String getTitle() { 165 return title; 166 } 167 168 /** 169 * <p>Gets the basic error message. This message should be clear and user oriented. 170 * This String may have HTML formatting, but any such formatting should be used 171 * sparingly. Generally, such formatting makes sense for making certain words bold, 172 * but should not be used for page layout or other such things.</p> 173 * 174 * <p>For example, the following are perfectly acceptable basic error messages: 175 * <pre> 176 * "Your camera cannot be located. Please make sure that it is powered on 177 * and that it is connected to this computer. Consult the instructions 178 * provided with your camera to make sure you are using the appropriate 179 * cable for attaching the camera to this computer" 180 * 181 * "<html>You are running on <b>reserver</b> battery 182 * power. Please plug into a power source immediately, or your work may 183 * be lost!</html>" 184 * </pre></p> 185 * 186 * @return basic error message or null 187 */ 188 public String getBasicErrorMessage() { 189 return basicErrorMessage; 190 } 191 192 /** 193 * <p>Gets the detailed error message. Unlike {@link #getBasicErrorMessage}, 194 * this method may return a more technical message to the user. However, it 195 * should still be user oriented. This String should be formatted using basic 196 * HTML to improve readability as necessary.</p> 197 * 198 * <p>This method may return null.</p> 199 * 200 * @return detailed error message or null 201 */ 202 public String getDetailedErrorMessage() { 203 return detailedErrorMessage; 204 } 205 206 /** 207 * Gets the category name. This value indicates where in the application 208 * this incident occurred. It is recommended that this be the same value as 209 * you would use when logging. This may be null. 210 * 211 * @return the category. May be null. 212 */ 213 public String getCategory() { 214 return category; 215 } 216 217 /** 218 * Gets the actual exception that generated the error. If this returns a 219 * non null value, then {@link #getBasicErrorMessage} may return a null value. 220 * If this returns a non null value and {@link #getDetailedErrorMessage} returns 221 * a null value, then this returned <code>Throwable</code> may be used as the 222 * basis for the detailed error message (generally by showing the stack trace). 223 * 224 * @return exception or null 225 */ 226 public Throwable getErrorException() { 227 return errorException; 228 } 229 230 /** 231 * Gets the severity of the error. The default level is <code>Level.SEVERE</code>, 232 * but any {@link Level} may be specified when constructing an 233 * <code>ErrorInfo</code>. 234 * 235 * @return the error level. This will never be null 236 */ 237 public Level getErrorLevel() { 238 return errorLevel; 239 } 240 241 /** 242 * <p>Gets a copy of the application state at the time that the incident occured. 243 * This map will never be null. If running with appropriate permissions the 244 * map will contain all the System properties. In addition, it contains two 245 * keys, "System.currentTimeMillis" and "isOnEDT".</p> 246 * 247 * <p>Warning: The System.properties <em>may not</em> contain the exact set 248 * of System properties at the time the exception occured. This is due to the 249 * nature of System.getProperties() and the Properties collection. While they 250 * are property synchronized, it is possible that while iterating the set of 251 * properties in the ErrorInfo constructor that some other code can change 252 * the properties on another thread. This is unlikely to occur, but in some 253 * applications <em>may</em> occur.</p> 254 * 255 * @return a copy of the application state. This will never be null. 256 */ 257 public Map<String,String> getState() { 258 return new HashMap<String,String>(state); 259 } 260}