Source Code Cross Referenced for MonolineFormatter.java in  » GIS » GeoTools-2.4.1 » org » geotools » util » logging » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.util.logging 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
005:         *    (C) 2001, Institut de Recherche pour le Développement
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:        package org.geotools.util.logging;
018:
019:        import java.io.IOException;
020:        import java.io.StringWriter;
021:        import java.text.FieldPosition;
022:        import java.text.SimpleDateFormat;
023:        import java.util.Date;
024:        import java.util.TimeZone;
025:        import java.util.logging.ConsoleHandler;
026:        import java.util.logging.Formatter;
027:        import java.util.logging.Handler;
028:        import java.util.logging.Level;
029:        import java.util.logging.LogManager;
030:        import java.util.logging.LogRecord;
031:        import java.util.logging.Logger;
032:        import java.util.logging.SimpleFormatter;
033:
034:        import org.geotools.io.LineWriter;
035:        import org.geotools.resources.Utilities;
036:
037:        /**
038:         * A formatter writting log messages on a single line. Compared to {@link SimpleFormatter}, this
039:         * formatter uses only one line per message instead of two. For example a message formatted by
040:         * {@code MonolineFormatter} looks like:
041:         *
042:         * <blockquote><pre>
043:         * FINE core - A log message logged with level FINE from the "org.geotools.core" logger.
044:         * </pre></blockquote>
045:         *
046:         * By default, {@code MonolineFormatter} displays only the level and the message. Additional
047:         * fields can be formatted if {@link #setTimeFormat} or {@link #setSourceFormat} methods are
048:         * invoked with a non-null argument. The format can also be set from the
049:         * {@code jre/lib/logging.properties} file. For example, user can cut and paste the following
050:         * properties into {@code logging.properties}:
051:         *
052:         * <blockquote><pre>
053:         * ############################################################
054:         * # Properties for the Geotools's MonolineFormatter.
055:         * # By default, the monoline formatter display only the level
056:         * # and the message. Additional fields can be specified here:
057:         * #
058:         * #   time:  If set, writes the time ellapsed since the initialization.
059:         * #          The argument specifies the output pattern. For example, the
060:         * #          pattern HH:mm:ss.SSSS displays the hours, minutes, seconds
061:         * #          and milliseconds.
062:         * #
063:         * #  source: If set, writes the source logger or the source class name.
064:         * #          The argument specifies the type of source to display. Valid
065:         * #          values are none, logger:short, logger:long, class:short and
066:         * #          class:long.
067:         * ############################################################
068:         * org.geotools.util.logging.MonolineFormatter.time = HH:mm:ss.SSS
069:         * org.geotools.util.logging.MonolineFormatter.source = class:short
070:         * </pre></blockquote>
071:         *
072:         * The example below set the {@code MonolineFormatter} for the whole system
073:         * with level FINE and "Cp850" page encoding (which is appropriate for some
074:         * DOS command lines on Windows).
075:         *
076:         * <blockquote><pre>
077:         * java.util.logging.ConsoleHandler.formatter = org.geotools.util.logging.MonolineFormatter
078:         * java.util.logging.ConsoleHandler.encoding = Cp850
079:         * java.util.logging.ConsoleHandler.level = FINE
080:         * </pre></blockquote>
081:         *
082:         * @since 2.0
083:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/util/logging/MonolineFormatter.java $
084:         * @version $Id: MonolineFormatter.java 27848 2007-11-12 13:10:32Z desruisseaux $
085:         * @author Martin Desruisseaux
086:         */
087:        public class MonolineFormatter extends Formatter {
088:            /**
089:             * The string to write at the begining of all log headers (e.g. "[FINE core]")
090:             */
091:            private static final String PREFIX = "";
092:
093:            /**
094:             * The string to write at the end of every log header (e.g. "[FINE core]").
095:             * It should includes the spaces between the header and the message body.
096:             */
097:            private static final String SUFFIX = " - ";
098:
099:            /**
100:             * The default header width.
101:             */
102:            private static final int DEFAULT_WIDTH = 9;
103:
104:            /** Do not format source class name.       */
105:            private static final int NO_SOURCE = 0;
106:            /** Explicit value for 'none'.             */
107:            private static final int NO_SOURCE_EX = 1;
108:            /** Format the source logger without base. */
109:            private static final int LOGGER_SHORT = 2;
110:            /** Format the source logger only.         */
111:            private static final int LOGGER_LONG = 3;
112:            /** Format the class name without package. */
113:            private static final int CLASS_SHORT = 4;
114:            /** Format the fully qualified class name. */
115:            private static final int CLASS_LONG = 5;
116:
117:            /**
118:             * The label to use in the {@code logging.properties} for setting the source format.
119:             */
120:            private static String[] FORMAT_LABELS = new String[6];
121:            static {
122:                FORMAT_LABELS[NO_SOURCE_EX] = "none";
123:                FORMAT_LABELS[LOGGER_SHORT] = "logger:short";
124:                FORMAT_LABELS[LOGGER_LONG] = "logger:long";
125:                FORMAT_LABELS[CLASS_SHORT] = "class:short";
126:                FORMAT_LABELS[CLASS_LONG] = "class:long";
127:            }
128:
129:            /**
130:             * The line separator. This is the value of the "line.separator"
131:             * property at the time the {@code MonolineFormatter} was created.
132:             */
133:            private final String lineSeparator = System.getProperty(
134:                    "line.separator", "\n");
135:
136:            /**
137:             * The line separator for the message body. This line always begin with
138:             * {@link #lineSeparator}, followed by some amount of spaces in order to
139:             * align the message.
140:             */
141:            private String bodyLineSeparator = lineSeparator;
142:
143:            /**
144:             * The minimum amount of spaces to use for writting level and module name
145:             * before the message.  For example if this value is 12, then a message from
146:             * module "org.geotools.core" with level FINE would be formatted as
147:             * "<code>[core&nbsp;&nbsp;FINE]</code> <cite>the message</cite>"
148:             * (i.e. the whole <code>[&nbsp;]</code> part is 12 characters wide).
149:             */
150:            private final int margin;
151:
152:            /**
153:             * Time of {@code MonolineFormatter} creation,
154:             * in milliseconds ellapsed since January 1, 1970.
155:             */
156:            private final long startMillis;
157:
158:            /**
159:             * The format to use for formatting ellapsed time,
160:             * or {@code null} if there is none.
161:             */
162:            private SimpleDateFormat timeFormat = null;
163:
164:            /**
165:             * One of the following constants: {@link #NO_SOURCE},
166:             * {@link #LOGGER_SHORT}, {@link #LOGGER_LONG},
167:             * {@link #CLASS_SHORT} or {@link #CLASS_LONG}.
168:             */
169:            private int sourceFormat = NO_SOURCE;
170:
171:            /**
172:             * Buffer for formatting messages. We will reuse this
173:             * buffer in order to reduce memory allocations.
174:             */
175:            private final StringBuffer buffer;
176:
177:            /**
178:             * The line writer. This object transform all "\r", "\n" or "\r\n" occurences
179:             * into a single line separator. This line separator will include space for
180:             * the marging, if needed.
181:             */
182:            private final LineWriter writer;
183:
184:            /**
185:             * Constructs a default {@code MonolineFormatter}.
186:             */
187:            public MonolineFormatter() {
188:                this .startMillis = System.currentTimeMillis();
189:                this .margin = DEFAULT_WIDTH;
190:                StringWriter str = new StringWriter();
191:                writer = new LineWriter(str);
192:                buffer = str.getBuffer();
193:                buffer.append(PREFIX);
194:
195:                // Configure this formatter
196:                final LogManager manager = LogManager.getLogManager();
197:                final String classname = MonolineFormatter.class.getName();
198:                try {
199:                    setTimeFormat(manager.getProperty(classname + ".time"));
200:                } catch (IllegalArgumentException exception) {
201:                    // Can't use the logging framework, since we are configuring it.
202:                    // Display the exception name only, not the trace.
203:                    System.err.println(exception);
204:                }
205:                try {
206:                    setSourceFormat(manager.getProperty(classname + ".source"));
207:                } catch (IllegalArgumentException exception) {
208:                    System.err.println(exception);
209:                }
210:            }
211:
212:            /**
213:             * Sets the format for displaying ellapsed time. The pattern must matches
214:             * the format specified in {@link SimpleDateFormat}. For example, the
215:             * pattern <code>"HH:mm:ss.SSS"</code> will display the ellapsed time
216:             * in hours, minutes, seconds and milliseconds.
217:             *
218:             * @param pattern The time patter, or {@code null} to disable time formatting.
219:             */
220:            public synchronized void setTimeFormat(final String pattern) {
221:                if (pattern == null) {
222:                    timeFormat = null;
223:                } else if (timeFormat == null) {
224:                    timeFormat = new SimpleDateFormat(pattern);
225:                    timeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
226:                } else {
227:                    timeFormat.applyPattern(pattern);
228:                }
229:            }
230:
231:            /**
232:             * Returns the format for displaying ellapsed time. This is the pattern specified
233:             * to the last call to {@link #setTimeFormat}, or the patten specified in the
234:             * {@code org.geotools.MonolineFormater.time} property in the
235:             * {@code jre/lib/logging.properties} file.
236:             *
237:             * @return The time pattern, or {@code null} if time is not formatted.
238:             */
239:            public synchronized String getTimeFormat() {
240:                return (timeFormat != null) ? timeFormat.toPattern() : null;
241:            }
242:
243:            /**
244:             * Sets the format for displaying the source. The pattern may be one of the following:
245:             *
246:             * <code>"none"</code>,
247:             * <code>"logger:short"</code>,  <code>"class:short"</code>,
248:             * <code>"logger:long"</code> or <code>"class:long"</code>.
249:             *
250:             * The difference between a {@code null} and <code>"none"</code> is that {@code null}
251:             * may be replaced by a default value, while <code>"none"</code> means that the user
252:             * explicitly requested no source.
253:             *
254:             * @param format The format for displaying the source.
255:             */
256:            public synchronized void setSourceFormat(String format) {
257:                if (format != null) {
258:                    format = format.trim().toLowerCase();
259:                }
260:                for (int i = 0; i < FORMAT_LABELS.length; i++) {
261:                    if (Utilities.equals(FORMAT_LABELS[i], format)) {
262:                        sourceFormat = i;
263:                        return;
264:                    }
265:                }
266:                throw new IllegalArgumentException(format);
267:            }
268:
269:            /**
270:             * Returns the format for displaying the source. This is the pattern specified
271:             * to the last call to {@link #setSourceFormat}, or the patten specified in the
272:             * {@code org.geotools.MonolineFormater.source} property in the
273:             * {@code jre/lib/logging.properties} file.
274:             *
275:             * @return The source pattern, or {@code null} if source is not formatted.
276:             */
277:            public String getSourceFormat() {
278:                return FORMAT_LABELS[sourceFormat];
279:            }
280:
281:            /**
282:             * Formats the given log record and return the formatted string.
283:             *
284:             * @param  record the log record to be formatted.
285:             * @return a formatted log record
286:             */
287:            public synchronized String format(final LogRecord record) {
288:                buffer.setLength(PREFIX.length());
289:                /*
290:                 * Formats the time (e.g. "00:00:12.365").  The time pattern can be set
291:                 * either programmatically with a call to setTimeFormat(String), or in
292:                 * the logging.properties file with the
293:                 * "org.geotools.util.logging.MonolineFormatter.time" property.
294:                 */
295:                if (timeFormat != null) {
296:                    Date time = new Date(Math.max(0, record.getMillis()
297:                            - startMillis));
298:                    timeFormat.format(time, buffer, new FieldPosition(0));
299:                    buffer.append(' ');
300:                }
301:                /*
302:                 * Formats the level (e.g. "FINE"). We do not provide
303:                 * the option to turn level off for now.
304:                 */
305:                if (true) {
306:                    int offset = buffer.length();
307:                    buffer.append(record.getLevel().getLocalizedName());
308:                    offset = buffer.length() - offset;
309:                    buffer.append(Utilities.spaces(margin - offset));
310:                }
311:                /*
312:                 * Adds the source. It may be either the source logger or the source class name.
313:                 */
314:                String logger = record.getLoggerName();
315:                String classname = record.getSourceClassName();
316:                switch (sourceFormat) {
317:                case LOGGER_SHORT: {
318:                    int pos = logger.lastIndexOf('.');
319:                    if (pos >= 0) {
320:                        logger = logger.substring(pos);
321:                    }
322:                    // fall through
323:                }
324:                case LOGGER_LONG: {
325:                    buffer.append(' ');
326:                    buffer.append(logger);
327:                    break;
328:                }
329:                case CLASS_SHORT: {
330:                    int dot = classname.lastIndexOf('.');
331:                    if (dot >= 0) {
332:                        classname = classname.substring(dot + 1);
333:                    }
334:                    classname = classname.replace('$', '.');
335:                    // fall through
336:                }
337:                case CLASS_LONG: {
338:                    buffer.append(' ');
339:                    buffer.append(classname);
340:                    break;
341:                }
342:                }
343:                buffer.append(SUFFIX);
344:                /*
345:                 * Now format the message. We will use a line separator made of the
346:                 * usual EOL ("\r", "\n", or "\r\n", which is plateform specific)
347:                 * following by some amout of space in order to align message body.
348:                 */
349:                final int margin = buffer.length();
350:                assert margin >= this .margin;
351:                if (bodyLineSeparator.length() != lineSeparator.length()
352:                        + margin) {
353:                    bodyLineSeparator = lineSeparator
354:                            + Utilities.spaces(margin);
355:                }
356:                try {
357:                    writer.setLineSeparator(bodyLineSeparator);
358:                    writer.write(String.valueOf(formatMessage(record)));
359:                    writer.setLineSeparator(lineSeparator);
360:                    writer.write('\n');
361:                    writer.flush();
362:                } catch (IOException exception) {
363:                    // Should never happen, since we are writting into a StringBuffer.
364:                    throw new AssertionError(exception);
365:                }
366:                return buffer.toString();
367:            }
368:
369:            /**
370:             * Setup a {@code MonolineFormatter} for the specified logger and its children. This method
371:             * search for all instances of {@link ConsoleHandler} using the {@link SimpleFormatter}. If
372:             * such instances are found, they are replaced by a single instance of {@code MonolineFormatter}.
373:             * If no such {@link ConsoleHandler} are found, then a new one is created with this
374:             * {@code MonolineFormatter}.
375:             * <p>
376:             * In addition, this method can set the handler levels. If the level is non-null, then all
377:             * {@link Handler}s using the monoline formatter will be set to the specified level. This
378:             * is provided for convenience, but non-null {@code level} argument should be avoided as
379:             * much as possible because it overrides user's level settings. A user trying to configure
380:             * his logging properties file may find confusing to see his setting ignored.
381:             *
382:             * @param  logger The base logger to apply the change on.
383:             * @param  level The desired level, or {@code null} if no level should be set.
384:             * @return The registered {@code MonolineFormatter} (never {@code null}).
385:             *         The formatter output can be configured using the {@link #setTimeFormat}
386:             *         and {@link #setSourceFormat} methods.
387:             */
388:            public static MonolineFormatter configureConsoleHandler(
389:                    final Logger logger, final Level level) {
390:                MonolineFormatter monoline = null;
391:                boolean foundConsoleHandler = false;
392:                Handler[] handlers = logger.getHandlers();
393:                for (int i = 0; i < handlers.length; i++) {
394:                    final Handler handler = handlers[i];
395:                    if (handler.getClass().equals(ConsoleHandler.class)) {
396:                        foundConsoleHandler = true;
397:                        final Formatter formatter = handler.getFormatter();
398:                        if (formatter instanceof  MonolineFormatter) {
399:                            /*
400:                             * A MonolineFormatter already existed. Sets the level only for the first
401:                             * instance (only one instance should exists anyway) for consistency with
402:                             * the fact that this method returns only one MonolineFormatter for further
403:                             * configuration.
404:                             */
405:                            if (monoline == null) {
406:                                monoline = (MonolineFormatter) formatter;
407:                                if (level != null) {
408:                                    handler.setLevel(level);
409:                                }
410:                            }
411:                        } else if (formatter.getClass().equals(
412:                                SimpleFormatter.class)) {
413:                            /*
414:                             * A ConsoleHandler using the SimpleFormatter has been found. Replaces
415:                             * the SimpleFormatter by MonolineFormatter, creating it if necessary.
416:                             * If the handler setting fail with an exception, then we will continue
417:                             * to use the old J2SE handler instead.
418:                             */
419:                            if (monoline == null) {
420:                                monoline = new MonolineFormatter();
421:                            }
422:                            try {
423:                                handler.setFormatter(monoline);
424:                                if (level != null) {
425:                                    handler.setLevel(level);
426:                                }
427:                            } catch (SecurityException exception) {
428:                                unexpectedException(exception);
429:                            }
430:                        }
431:                    }
432:                }
433:                /*
434:                 * If the logger uses parent handlers, copy them to the logger that we are initializing,
435:                 * because we will not use parent handlers anymore at the end of this method.
436:                 */
437:                for (Logger parent = logger; parent.getUseParentHandlers();) {
438:                    parent = parent.getParent();
439:                    if (parent == null) {
440:                        break;
441:                    }
442:                    handlers = parent.getHandlers();
443:                    for (int i = 0; i < handlers.length; i++) {
444:                        Handler handler = handlers[i];
445:                        if (handler.getClass().equals(ConsoleHandler.class)) {
446:                            if (!foundConsoleHandler) {
447:                                // We have already set a ConsoleHandler and we don't want a second one.
448:                                continue;
449:                            }
450:                            foundConsoleHandler = true;
451:                            final Formatter formatter = handler.getFormatter();
452:                            if (formatter.getClass().equals(
453:                                    SimpleFormatter.class)) {
454:                                monoline = addHandler(logger, level);
455:                                continue;
456:                            }
457:                        }
458:                        logger.addHandler(handler);
459:                    }
460:                }
461:                logger.setUseParentHandlers(false);
462:                if (!foundConsoleHandler) {
463:                    monoline = addHandler(logger, level);
464:                }
465:                return monoline;
466:            }
467:
468:            /**
469:             * Adds to the specified logger a {@link Handler} using a {@code MonolineFormatter}
470:             * set at the specified level. The formatter is returned for convenience.
471:             */
472:            private static MonolineFormatter addHandler(final Logger logger,
473:                    final Level level) {
474:                final MonolineFormatter monoline = new MonolineFormatter();
475:                try {
476:                    final Handler handler = new ConsoleHandler();
477:                    handler.setFormatter(monoline);
478:                    if (level != null) {
479:                        handler.setLevel(level);
480:                    }
481:                    logger.addHandler(handler);
482:                } catch (SecurityException exception) {
483:                    unexpectedException(exception);
484:                    /*
485:                     * Returns without any change to the J2SE configuration. Note that the returned
486:                     * MonolineFormatter is really a dummy one, since we failed to register it.  It
487:                     * will not prevent to program to work; just produces different logging outputs.
488:                     */
489:                }
490:                return monoline;
491:            }
492:
493:            /**
494:             * Invoked when an error occurs during the initialization.
495:             */
496:            private static void unexpectedException(final Exception exception) {
497:                Logging.unexpectedException("org.geotools.util.logging",
498:                        MonolineFormatter.class, "configureConsoleHandler",
499:                        exception);
500:            }
501:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.