001: /*
002: * $Id:$
003: * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
004: *
005: * http://www.izforge.com/izpack/
006: * http://izpack.codehaus.org/
007: *
008: * Copyright 2006 Elmar Grom
009: *
010: * Licensed under the Apache License, Version 2.0 (the "License");
011: * you may not use this file except in compliance with the License.
012: * You may obtain a copy of the License at
013: *
014: * http://www.apache.org/licenses/LICENSE-2.0
015: *
016: * Unless required by applicable law or agreed to in writing, software
017: * distributed under the License is distributed on an "AS IS" BASIS,
018: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019: * See the License for the specific language governing permissions and
020: * limitations under the License.
021: */
022:
023: package com.izforge.izpack.util;
024:
025: import java.util.*;
026: import java.text.MessageFormat;
027: import java.io.File;
028: import java.io.FileWriter;
029: import java.text.SimpleDateFormat;
030: import java.text.DateFormatSymbols;
031: import javax.swing.JOptionPane;
032: import javax.swing.JFileChooser;
033:
034: import com.izforge.izpack.installer.AutomatedInstallData;
035:
036: /*---------------------------------------------------------------------------*/
037: /**
038: * This class handles informing the user about unusual events during the installation process and
039: * therefore about the possibility that the installation may not have succeeded at all or may have
040: * succeeded only partially. Because the logger represents a single resource it is implemented as
041: * singleton.
042: *
043: * <h1>Usage</h1>
044: * To add a message to the install log call one of the <code>addMessage()</code> methods, using
045: * the appropriate message index. If the message contains placeholders for variables, provide a
046: * <code>String</code> array that supplies the necessary variable text. Calling
047: * <code>addMessage()</code> will add an informative message to the log. These may be used to
048: * indicate actions taken by the installer throughout the progression of the install. Calling
049: * <code>addWarning()</code> will not only add the requested warning message to the log but also
050: * cause the user to be alerted about the fact that the install might not have succeeded completely.
051: * <code>addError()</code> goes one step further, by alerting the user that the installation has
052: * failed.
053: *
054: * <h1>Adding Messages</h1>
055: * Messages are divided into three categories:
056: * <ol>
057: * <li>informative/general messages
058: * <li>warning messages
059: * <li>error messages
060: * </ol>
061: * To add a message, define the text resource in the language packs. Then add a new constant for the
062: * message, along with a brief description of the purpose of the message. If the message contains
063: * place holders for variable text add an ordered list to the description, that lists all variables
064: * in proper order, so that other programmers have no difficulty to form a correct call for the
065: * message. The constants are defined in the individual interfaces <code>LogMessage</code>,
066: * <code>LogWarning</code> and <code>LogError</code>.
067: * <p>
068: * To derive a correct integer value for the message index add a new value to either
069: * <code>MESSAGE_BASE</code>, <code>WARNING_BASE</code> or <code>ERROR_BASE</code>,
070: * depending on the message category. Next, increment the MAX_ constant for the message category, to
071: * ensure that the add... methods actually allow the message to be added. The key for the text
072: * resource must be named either <code>log.message_</code>, <code>log.warning_</code> or
073: * <code>log.error_</code> in accordance with the chosen index base. In addition, the key must be
074: * appended by the message index (without the base, since this implementation will automatically
075: * subtract the base). Variable place holders must conform to the specification for
076: * <code>java.text.MessageFormat</code>.
077: *
078: * <h1>Debug Messages</h1>
079: * The output of debug messages is controlled through system properties. These properties may be set
080: * using the -D command line option. Please note, that the -D option is a command line switch for
081: * the VM, not for IzPack. In order for this to work, these options must be listed on the command
082: * line before IzPack!
083: *
084: * <h2>Turning Debug On</h2>
085: * In order to receive debug output, it is necessary to turn this feature on explicitely. This is
086: * done with the command line otprion:
087: *
088: * <pre>
089: * -DIzPack.debug=on
090: * </pre>
091: *
092: * <h2>Selecting Debug Channels</h2>
093: * Setting the list of specific debug channels to trace is accomplished with the following command
094: * line option:
095: *
096: * <pre>
097: * -DIzPack.debug.channel=<channelA,channelB,...>
098: * </pre>
099: *
100: * The parameter is a comma separated list of one or more channel identifiers.
101: *
102: * <h2>Dumping a List of Debug Channels</h2>
103: *
104: * <pre>
105: * -DIzPack.debug.dumpList=on
106: * </pre>
107: *
108: * To turn debug messages on
109: *
110: * @version 0.0.1 / 11/20/06
111: * @author Elmar Grom
112: */
113: /*---------------------------------------------------------------------------*/
114:
115: public class Log implements LogError, LogWarning, LogMessage {
116:
117: // --------------------------------------------------------------------------
118: // Constant Definitions
119: // --------------------------------------------------------------------------
120: /** The prefix for all text resources related to this class */
121: private static final String RESOURCE_PREFIX = "log.";
122:
123: /** The formatting used for the report time stamp */
124: private static final String DATE_FORMAT = RESOURCE_PREFIX
125: + "timeStamp";
126:
127: /** The prefix for building message keys */
128: private static final String MESSAGE_PREFIX = RESOURCE_PREFIX
129: + "message_";
130:
131: /** The prefix for building warning message keys */
132: private static final String WARNING_PREFIX = RESOURCE_PREFIX
133: + "warning_";
134:
135: /** The prefix for building error message keys */
136: private static final String ERROR_PREFIX = RESOURCE_PREFIX
137: + "error_";
138:
139: /** System property to turn debug output on */
140: private static final String DEBUG_SWITCH = "IzPack.debug";
141:
142: /** System property to set the debug channels to trace */
143: private static final String CHANNEL_SPEC = "IzPack.debug.channel";
144:
145: /**
146: * System property to enable dumping of the list of debug channels that did record messages
147: */
148: private static final String CHANNEL_LIST = "IzPack.debug.dumpList";
149:
150: // --------------------------------------------------------------------------
151: // Variable Declarations
152: // --------------------------------------------------------------------------
153: /** The only instance of <code>Messenger</code> */
154: private static Log me = null;
155:
156: /** The system dependent newline character sequence */
157: private String newline = System.getProperty("line.separator");
158:
159: /** Access to the installation information and the localized text resources */
160: private AutomatedInstallData installData = null;
161:
162: /** The collection of installation messages */
163: private ArrayList<Record> messages = new ArrayList<Record>();
164:
165: /** The collection of warning messages */
166: private ArrayList<Record> warnings = new ArrayList<Record>();
167:
168: /** The collection of error messages */
169: private ArrayList<Record> errors = new ArrayList<Record>();
170:
171: /** The collection of debug messages */
172: private ArrayList<Record> debug = new ArrayList<Record>();
173:
174: /**
175: * The list of channels requested for debug output. A <code>Vector</code> must be used for
176: * this purpose, since this is the only class that explicitly specifies that the
177: * <code>equals()</code> method is used for determining if a particular object is contained.
178: */
179: private Vector<String> channels = null;
180:
181: /**
182: * This map keeps track of all channels that are recorded. It is used for information purposes.
183: */
184: private Hashtable<String, String> recordedChannels = null;
185:
186: /** This flag signals if debug messages should be recorded */
187: private boolean debugActive = false;
188:
189: /**
190: * This flag signals that the identifiers of the recorded debug channels should be dumped
191: */
192: private boolean dumpChannels = false;
193:
194: /*--------------------------------------------------------------------------*/
195: /**
196: * This class is installed as singleton. Therefore the constructor is declared private. Use
197: * <code>getInstance()</code> to get an instance.
198: */
199: /*--------------------------------------------------------------------------*/
200: private Log() {
201: // ----------------------------------------------------
202: // gain access to the install data
203: // ----------------------------------------------------
204: installData = AutomatedInstallData.getInstance();
205:
206: // ----------------------------------------------------
207: // get the debug setting
208: // ----------------------------------------------------
209: String temp = System.getProperty(DEBUG_SWITCH);
210: if ((temp != null) && (temp.toUpperCase().equals("ON"))) {
211: debugActive = true;
212: }
213:
214: if (debugActive) {
215: // ----------------------------------------------------
216: // get the list of debug channels requested
217: // ----------------------------------------------------
218: recordedChannels = new Hashtable<String, String>();
219: channels = new Vector<String>();
220: temp = System.getProperty(CHANNEL_LIST);
221: if ((temp != null) && (temp.toUpperCase().equals("ON"))) {
222: dumpChannels = true;
223: }
224:
225: // ----------------------------------------------------
226: // get the list of debug channels requested
227: // ----------------------------------------------------
228: temp = System.getProperty(CHANNEL_SPEC);
229: if (temp != null) {
230: String[] channelList = temp.split(",");
231:
232: channels.addAll(Arrays.asList(channelList));
233: }
234: }
235: }
236:
237: /*--------------------------------------------------------------------------*/
238: /**
239: * Returns the only instance of <code>Log</code>
240: * @return the only instance of <code>Log</code>
241: */
242: /*--------------------------------------------------------------------------*/
243: public static Log getInstance() {
244: if (me == null) {
245: me = new Log();
246: }
247:
248: return (me);
249: }
250:
251: /*--------------------------------------------------------------------------*/
252: /**
253: * This method records general installation message
254: *
255: * @param message the numeric identifier of the message to add, as defined in
256: * {@link com.izforge.izpack.util.LogMessage <code>LogMessage</code>}
257: * @param detail a string array of variable fields that should be inserted into the message text
258: */
259: /*--------------------------------------------------------------------------*/
260: public void addMessage(int message, String[] detail) {
261: if ((message >= LogMessage.MESSAGE_BASE)
262: && (message < LogMessage.MAX_MESSAGE)) {
263: messages.add(new Record(message, detail));
264: }
265: }
266:
267: /*--------------------------------------------------------------------------*/
268: /**
269: * This method records a general installation message, using a custom text template. It allows
270: * cusom code to insert message text that is not defined in IzPack. IzPack internal code should
271: * use the parallel version based on the message index.
272: *
273: * @param template the basic template of the message
274: * @param detail a string array of variable fields that should be inserted into the message
275: * text. Each array element will be inserted into the text template, replacing a marker.
276: *
277: * @see java.text.MessageFormat#format(java.lang.String, java.lang.Object[])
278: */
279: /*--------------------------------------------------------------------------*/
280: public void addCustomMessage(String template, String[] detail) {
281: messages.add(new Record(template, detail));
282: }
283:
284: /*--------------------------------------------------------------------------*/
285: /**
286: * This method records a warning message to the list of messages
287: *
288: * @param message the numeric identifier of the message to add, as defined in
289: * {@link com.izforge.izpack.util.LogWarning <code>LogWarning</code>}
290: * @param detail a string array of variable fields that should be inserted into the message
291: * text. Each array element will be inserted into the text template, replacing a marker.
292: * @param exception the exception associated with the event or <code>null</code> if there was
293: * none.
294: *
295: * @see java.text.MessageFormat#format(java.lang.String, java.lang.Object[])
296: */
297: /*--------------------------------------------------------------------------*/
298: public void addWarning(int message, String[] detail,
299: Throwable exception) {
300: if ((message >= LogWarning.WARNING_BASE)
301: && (message < LogWarning.MAX_WARNING)) {
302: warnings.add(new Record(message, detail, exception));
303: }
304: }
305:
306: /*--------------------------------------------------------------------------*/
307: /**
308: * This method records a warning message, using a custom text template. It allows cusom code to
309: * insert message text that is not defined in IzPack. IzPack internal code should use the
310: * parallel version based on the message index.
311: *
312: * @param template the basic template for the message
313: * @param detail a string array of variable fields that should be inserted into the message
314: * text. Each array element will be inserted into the text template, replacing a marker.
315: * @param exception the exception associated with the event or <code>null</code> if there was
316: * none.
317: *
318: * @see java.text.MessageFormat#format(java.lang.String, java.lang.Object[])
319: */
320: /*--------------------------------------------------------------------------*/
321: public void addCustomWarning(String template, String[] detail,
322: Throwable exception) {
323: warnings.add(new Record(template, detail, exception));
324: }
325:
326: /*--------------------------------------------------------------------------*/
327: /**
328: * This method records an error message to the list of messages
329: *
330: * @param message the numeric identifier of the message to add, as defined in
331: * {@link com.izforge.izpack.util.LogError <code>LogError</code>}
332: * @param detail a string array of variable fields that should be inserted into the message
333: * text. Each array element will be inserted into the text template, replacing a marker.
334: * @param exception the exception associated with the event or <code>null</code> if there was
335: * none.
336: *
337: * @see java.text.MessageFormat#format(java.lang.String, java.lang.Object[])
338: */
339: /*--------------------------------------------------------------------------*/
340: public void addError(int message, String[] detail,
341: Throwable exception) {
342: if ((message >= LogError.ERROR_BASE)
343: && (message < LogError.MAX_ERROR)) {
344: errors.add(new Record(message, detail, exception));
345: installData.installSuccess = false;
346: }
347: }
348:
349: /*--------------------------------------------------------------------------*/
350: /**
351: * This method records an error message, using a custom text template. It allows cusom code to
352: * insert message text that is not defined in IzPack. IzPack internal code should use the
353: * parallel version based on the message index.
354: *
355: * @param template the basic template for the message
356: * @param detail a string array of variable fields that should be inserted into the message
357: * text. Each array element will be inserted into the text template, replacing a marker.
358: * @param exception the exception associated with the event or <code>null</code> if there was
359: * none.
360: *
361: * @see java.text.MessageFormat#format(java.lang.String, java.lang.Object[])
362: */
363: /*--------------------------------------------------------------------------*/
364: public void addCustomError(String template, String[] detail,
365: Throwable exception) {
366: errors.add(new Record(template, detail, exception));
367: }
368:
369: /*--------------------------------------------------------------------------*/
370: /**
371: * This method provides a channel for debugging messages in IzPack development. Note that debug
372: * messages are used solely for this purpose. Adding debug messages does not trigger user
373: * notification. If the user should be notified about a specific situation, please also call the
374: * appropriate (message, warning, error) method. Debug messages are not localized, please use
375: * English only.
376: * <p>
377: * In order to prevent flooding developers with messages that are generally of no interest, each
378: * message may be associated with a specific channel. A message is associated with a channel
379: * simply by providing a channel identifier as call parameter. There is no need for registering
380: * channels beforehand. If <code>null</code> or an empty string is used as channel identifier
381: * the message will be output, regardless of the channel filter applied. Please use this option
382: * sparingly, just for really impotant messages of general interest.
383: * <p>
384: * To receive output for select channels, start IzPack with the command line option
385: * -DIzPack.debug.channel=, followed by a comma separated list of channel identifiers.
386: *
387: * @param template the basic template for the message
388: * @param detail a string array of variable fields that should be inserted into the message
389: * text. Each array element will be inserted into the text template, replacing a marker.
390: * @param channel the debug channel the message is associated with.
391: * @param exception the exception associated with the event or <code>null</code> if there was
392: * none.
393: */
394: /*--------------------------------------------------------------------------*/
395: public void addDebugMessage(String template, String[] detail,
396: String channel, Throwable exception) {
397: if (debugActive) {
398: recordedChannels.put(channel, channel);
399:
400: if ((channel == null) || (channel.length() == 0)
401: || channels.contains(channel)) {
402: Record record = new Record(template, detail, exception,
403: channel);
404:
405: debug.add(record);
406: System.out.println(buildDebug(record));
407: }
408: }
409: }
410:
411: /*--------------------------------------------------------------------------*/
412: /**
413: * Reports if any messages have been recorded.
414: *
415: * @return true if any messages have been recorded
416: */
417: /*--------------------------------------------------------------------------*/
418: public boolean messagesRecorded() {
419: return (!messages.isEmpty());
420: }
421:
422: /*--------------------------------------------------------------------------*/
423: /**
424: * Reports if any warnings have been recorded.
425: *
426: * @return true if any warnings have been recorded
427: */
428: /*--------------------------------------------------------------------------*/
429: public boolean warningsRecorded() {
430: return (!warnings.isEmpty());
431: }
432:
433: /*--------------------------------------------------------------------------*/
434: /**
435: * Reports if any errors have been recorded.
436: *
437: * @return true if any errors have been recorded
438: */
439: /*--------------------------------------------------------------------------*/
440: public boolean errorsRecorded() {
441: return (!errors.isEmpty());
442: }
443:
444: /*--------------------------------------------------------------------------*/
445: /**
446: * Displays a dialog that informs the user about the fact that one or more unusual events have
447: * occurred during installation. If nothing has been recorded, this method returns immediately.
448: */
449: /*--------------------------------------------------------------------------*/
450: public void informUser() {
451: String message = "";
452: int messageType = JOptionPane.WARNING_MESSAGE;
453:
454: // ----------------------------------------------------
455: // fins out if there are any warnings or errors,
456: // otherwise return with no action
457: // ----------------------------------------------------
458: if (errorsRecorded()) {
459: messageType = JOptionPane.ERROR_MESSAGE;
460: message = installData.langpack.getString(RESOURCE_PREFIX
461: + "informUserFail");
462: } else if (warningsRecorded()) {
463: messageType = JOptionPane.WARNING_MESSAGE;
464: message = installData.langpack.getString(RESOURCE_PREFIX
465: + "informUserPartial");
466: } else {
467: return;
468: }
469:
470: // ----------------------------------------------------
471: // present the warning message
472: // ----------------------------------------------------
473: int userChoice = JOptionPane.showConfirmDialog(null, message,
474: installData.langpack.getString(RESOURCE_PREFIX
475: + "informUserTitle"),
476: JOptionPane.YES_NO_OPTION, messageType);
477:
478: // ----------------------------------------------------
479: // if the user has elected to write the report, present
480: // the file selection dialog.
481: // ----------------------------------------------------
482: if (userChoice == JOptionPane.OK_OPTION) {
483: writeReport();
484: }
485: }
486:
487: /*--------------------------------------------------------------------------*/
488: /**
489: * Presents the user with a dialog to select a file and location for the installation report and
490: * writes a report contianing all messages to the user selected file.
491: */
492: /*--------------------------------------------------------------------------*/
493: public void writeReport() {
494: JFileChooser fileChooser = new JFileChooser();
495: fileChooser.setDialogTitle(installData.langpack
496: .getString(RESOURCE_PREFIX + "saveLogTitle"));
497: fileChooser.setSelectedFile(new File(installData.langpack
498: .getString(RESOURCE_PREFIX + "LogFileName")));
499: int choice = fileChooser.showSaveDialog(null);
500:
501: if (choice == JFileChooser.APPROVE_OPTION) {
502: writeReport(fileChooser.getSelectedFile().getAbsolutePath());
503: }
504: }
505:
506: /*--------------------------------------------------------------------------*/
507: /**
508: * Writes a report contianing all messages to the indicated file.
509: *
510: * @param file the fully qualifies name of the file to write to.
511: */
512: /*--------------------------------------------------------------------------*/
513: public void writeReport(String file) {
514: try {
515: FileWriter writer = new FileWriter(file);
516: String text = compileReport();
517:
518: writer.write(text, 0, text.length());
519:
520: writer.flush();
521: writer.close();
522: } catch (Throwable exception) {
523: try {
524: JOptionPane.showMessageDialog(null,
525: installData.langpack.getString(
526: (RESOURCE_PREFIX + "reportWriteError"),
527: new String[] { file }),
528: installData.langpack.getString(RESOURCE_PREFIX
529: + "reportWriteErrorTitle"),
530: JOptionPane.ERROR_MESSAGE);
531: } catch (Throwable exception2) {
532: // What todo if writing log report fails?? We can ignore
533: // or write it exceptionally on stderr.
534: exception2.printStackTrace();
535: }
536: }
537: }
538:
539: /*--------------------------------------------------------------------------*/
540: /**
541: * Prepares an installation report from the recorded information
542: *
543: * @return the installation report
544: */
545: /*--------------------------------------------------------------------------*/
546: private String compileReport() {
547: StringBuffer report = new StringBuffer();
548: String dateFormat = installData.langpack.getString(DATE_FORMAT);
549: int count;
550:
551: // ----------------------------------------------------
552: // insert header
553: // ----------------------------------------------------
554: report
555: .append("-------------------------------------------------------------------------------");
556: report.append(newline);
557: report.append(installData.langpack.getString(RESOURCE_PREFIX
558: + "reportHeading"));
559: report.append(newline);
560: report
561: .append("-------------------------------------------------------------------------------");
562: report.append(newline);
563:
564: // ----------------------------------------------------
565: // insert a general warning message if appropriate
566: // ----------------------------------------------------
567: if (errorsRecorded()) {
568: report.append(newline);
569: report.append(installData.langpack
570: .getString(RESOURCE_PREFIX + "installFailed"));
571: report.append(newline);
572: } else if (warningsRecorded()) {
573: report.append(newline);
574: report.append(installData.langpack
575: .getString(RESOURCE_PREFIX + "partialInstall"));
576: report.append(newline);
577: }
578:
579: // ----------------------------------------------------
580: // insert general information about the installation
581: // ----------------------------------------------------
582: report.append(newline);
583: report.append(installData.langpack.getString(RESOURCE_PREFIX
584: + "messageCount", new String[] {
585: Integer.toString(messages.size()),
586: Integer.toString(warnings.size()),
587: Integer.toString(errors.size()) }));
588: report.append(newline);
589: report.append(newline);
590:
591: report.append(installData.langpack.getString(RESOURCE_PREFIX
592: + "application", new String[] {
593: installData.info.getAppName(),
594: installData.info.getAppVersion() }));
595: report.append(newline);
596: report.append(installData.langpack.getString(RESOURCE_PREFIX
597: + "timePrefix",
598: new String[] { new SimpleDateFormat(dateFormat,
599: new DateFormatSymbols()).format(new Date()) }));
600:
601: report.append(newline);
602: report.append(installData.langpack.getString(RESOURCE_PREFIX
603: + "pathPrefix", new String[] { installData
604: .getInstallPath() }));
605: report.append(newline);
606:
607: // ----------------------------------------------------
608: // insert the recorded mnessages
609: // ----------------------------------------------------
610: if (messagesRecorded()) {
611: report.append(newline);
612: report.append(installData.langpack
613: .getString(RESOURCE_PREFIX + "messageHeading"));
614: report.append(newline);
615: report.append(newline);
616:
617: count = messages.size();
618:
619: for (int i = 0; i < count; i++) {
620: report.append(buildMessage(i));
621: }
622: }
623: // ----------------------------------------------------
624: // insert the recorded warning messages
625: // ----------------------------------------------------
626: if (warningsRecorded()) {
627: report.append(newline);
628: report.append(installData.langpack
629: .getString(RESOURCE_PREFIX + "warningHeading"));
630: report.append(newline);
631: report.append(newline);
632:
633: count = warnings.size();
634:
635: for (int i = 0; i < count; i++) {
636: report.append(buildWarning(i));
637: }
638: }
639: // ----------------------------------------------------
640: // insert the recorded error messages
641: // ----------------------------------------------------
642: if (errorsRecorded()) {
643: report.append(newline);
644: report.append(installData.langpack
645: .getString(RESOURCE_PREFIX + "errorHeading"));
646: report.append(newline);
647: report.append(newline);
648:
649: count = errors.size();
650:
651: for (int i = 0; i < count; i++) {
652: report.append(buildError(i));
653: }
654: }
655:
656: // ----------------------------------------------------
657: // insert the debug messages
658: // ----------------------------------------------------
659: if (debugActive) {
660: report.append(newline);
661: report.append(installData.langpack
662: .getString(RESOURCE_PREFIX + "debugHeading"));
663: report.append(newline);
664: report.append(newline);
665:
666: count = errors.size();
667:
668: for (int i = 0; i < count; i++) {
669: report.append(buildDebug(i));
670: }
671: }
672:
673: report
674: .append("-------------------------------------------------------------------------------");
675: report.append(newline);
676:
677: return (report.toString());
678: }
679:
680: /*--------------------------------------------------------------------------*/
681: /**
682: * Builds a general installation message from the information contained in the indicated record
683: *
684: * @param index the index of the requested message entry
685: */
686: /*--------------------------------------------------------------------------*/
687: private String buildMessage(int index) {
688: Record record = messages.get(index);
689: StringBuffer message = new StringBuffer();
690:
691: // ----------------------------------------------------
692: // append the message text
693: // ----------------------------------------------------
694: message.append(installData.langpack.getString(RESOURCE_PREFIX
695: + "messagePrefix", new String[] { Integer
696: .toString(index) }));
697:
698: if (record.message >= 0) {
699: message.append(installData.langpack.getString(
700: MESSAGE_PREFIX + Integer.toString(record.message),
701: record.variables));
702: } else {
703: message.append(MessageFormat.format(record.template,
704: new Object[] { record.variables }));
705: }
706:
707: message.append(newline);
708: return (message.toString());
709: }
710:
711: /*--------------------------------------------------------------------------*/
712: /**
713: * Builds a warning message from the information contained in the indicated warning record
714: *
715: * @param index the index of the requested warning entry
716: */
717: /*--------------------------------------------------------------------------*/
718: private String buildWarning(int index) {
719: Record record = warnings.get(index);
720: StringBuffer message = new StringBuffer();
721:
722: // ----------------------------------------------------
723: // append the message text
724: // ----------------------------------------------------
725: message.append(installData.langpack.getString(RESOURCE_PREFIX
726: + "warningPrefix", new String[] { Integer
727: .toString(index) }));
728:
729: if (record.message >= 0) {
730: message.append(installData.langpack.getString(
731: WARNING_PREFIX
732: + Integer.toString(record.message
733: - LogWarning.WARNING_BASE),
734: record.variables));
735: } else {
736: message.append(MessageFormat.format(record.template,
737: new Object[] { record.variables }));
738: }
739:
740: // ----------------------------------------------------
741: // append the exception
742: // ----------------------------------------------------
743: if (record.exception != null) {
744: message.append(newline);
745: message.append(installData.langpack.getString(
746: RESOURCE_PREFIX + "exceptionPrefix",
747: new String[] { record.exception.toString() }));
748: }
749:
750: message.append(newline);
751: return (message.toString());
752: }
753:
754: /*--------------------------------------------------------------------------*/
755: /**
756: * Builds an error message from the information contained in the indicated error record
757: *
758: * @param index the index of the requested error entry
759: */
760: /*--------------------------------------------------------------------------*/
761: private String buildError(int index) {
762: Record record = errors.get(index);
763: StringBuffer message = new StringBuffer();
764:
765: // ----------------------------------------------------
766: // append the message text
767: // ----------------------------------------------------
768: message.append(installData.langpack.getString(RESOURCE_PREFIX
769: + "errorPrefix",
770: new String[] { Integer.toString(index) }));
771:
772: if (record.message >= 0) {
773: message.append(installData.langpack.getString(ERROR_PREFIX
774: + Integer.toString(record.message
775: - LogError.ERROR_BASE), record.variables));
776: } else {
777: message.append(MessageFormat.format(record.template,
778: new Object[] { record.variables }));
779: }
780:
781: // ----------------------------------------------------
782: // append the exception
783: // ----------------------------------------------------
784: if (record.exception != null) {
785: message.append(newline);
786: message.append(installData.langpack.getString(
787: RESOURCE_PREFIX + "exceptionPrefix",
788: new String[] { record.exception.toString() }));
789: }
790:
791: message.append(newline);
792: return (message.toString());
793: }
794:
795: /*--------------------------------------------------------------------------*/
796: /**
797: * Builds a debug message from the information contained in the indicated debug record
798: *
799: * @param index the index of the requested debug entry
800: */
801: /*--------------------------------------------------------------------------*/
802: private String buildDebug(int index) {
803: Record record = debug.get(index);
804:
805: return (buildDebug(record));
806: }
807:
808: /*--------------------------------------------------------------------------*/
809: /**
810: * Builds a debug message from the information contained in a specific debug record
811: *
812: * @param record the debug record
813: */
814: /*--------------------------------------------------------------------------*/
815: private String buildDebug(Record record) {
816: StringBuffer message = new StringBuffer();
817:
818: // ----------------------------------------------------
819: // append the message text
820: // ----------------------------------------------------
821: if ((record.channel == null) || (record.channel.length() == 0)) {
822: message.append("Debug - general: ");
823: } else {
824: message.append("Debug - ").append(record.channel).append(
825: ": ");
826: }
827:
828: message.append(MessageFormat.format(record.template,
829: new Object[] { record.variables }));
830:
831: // ----------------------------------------------------
832: // append the exception
833: // ----------------------------------------------------
834: if (record.exception != null) {
835: message.append(newline);
836: message.append(installData.langpack.getString(
837: RESOURCE_PREFIX + "exceptionPrefix",
838: new String[] { record.exception.toString() }));
839: }
840:
841: message.append(newline);
842: return (message.toString());
843: }
844:
845: /*--------------------------------------------------------------------------*/
846: /**
847: * Dumps the list of debug channels to stdout that have recorded messages
848: */
849: /*--------------------------------------------------------------------------*/
850: public void dumpRecordedChannels() {
851: if (debugActive && dumpChannels) {
852: System.out.println();
853: System.out
854: .println("The following debug channels did record messages:");
855: System.out.println();
856:
857: Enumeration<String> list = recordedChannels.keys();
858:
859: while (list.hasMoreElements()) {
860: System.out.println(" - "
861: + list.nextElement().toString());
862: }
863:
864: System.out.println();
865: }
866: }
867:
868: // --------------------------------------------------------------------------
869: // class definition to handle individual entries
870: // --------------------------------------------------------------------------
871: private class Record {
872:
873: String channel;
874:
875: String template;
876:
877: int message;
878:
879: String[] variables;
880:
881: Throwable exception;
882:
883: // ----------------------------------------------------
884: // Constructors
885: // ----------------------------------------------------
886: Record(int message, String[] variables) {
887: this .message = message;
888: this .variables = variables;
889: }
890:
891: Record(String template, String[] variables) {
892: this .message = -1;
893: this .template = template;
894: this .variables = variables;
895: }
896:
897: Record(int message, String[] variables, Throwable exception) {
898: this .message = message;
899: this .variables = variables;
900: this .exception = exception;
901: }
902:
903: Record(String template, String[] variables, Throwable exception) {
904: this .message = -1;
905: this .template = template;
906: this .variables = variables;
907: this .exception = exception;
908: }
909:
910: Record(String template, String[] variables,
911: Throwable exception, String channel) {
912: this .message = -1;
913: this .template = template;
914: this .variables = variables;
915: this .exception = exception;
916: this .channel = channel;
917: }
918: }
919: }
920: /*---------------------------------------------------------------------------*/
|