Source Code Cross Referenced for PatternFormatter.java in  » Net » openfire » org » jivesoftware » util » log » format » 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 » Net » openfire » org.jivesoftware.util.log.format 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (C) The Apache Software Foundation. All rights reserved.
003:         *
004:         * This software is published under the terms of the Apache Software License
005:         * version 1.1, a copy of which has been included with this distribution in
006:         * the LICENSE file.
007:         */
008:        package org.jivesoftware.util.log.format;
009:
010:        import org.jivesoftware.util.FastDateFormat;
011:        import org.jivesoftware.util.log.ContextMap;
012:        import org.jivesoftware.util.log.LogEvent;
013:        import org.jivesoftware.util.log.Priority;
014:
015:        import java.io.StringWriter;
016:        import java.util.Date;
017:        import java.util.Stack;
018:
019:        /**
020:         * This formater formats the LogEvents according to a input pattern
021:         * string.
022:         * <p/>
023:         * The format of each pattern element can be %[+|-][#[.#]]{field:subformat}.
024:         * </p>
025:         * <ul>
026:         * <li>The +|- indicates left or right justify.
027:         * </li>
028:         * <li>The #.# indicates the minimum and maximum size of output.<br>
029:         * You may omit the values and the field will be formatted without size
030:         * restriction.<br>
031:         * You may specify '#', or '#.' to define an minimum size, only.</br>
032:         * You may specify '.#' to define an maximum size only.
033:         * </li>
034:         * <li>
035:         * 'field' indicates which field is to be output and must be one of
036:         * properties of LogEvent.<br>
037:         * Currently following fields are supported:
038:         * <dl>
039:         * <dt>category</dt>
040:         * <dd>Category value of the logging event.</dd>
041:         * <dt>context</dt>
042:         * <dd>Context value of the logging event.</dd>
043:         * <dt>message</dt>
044:         * <dd>Message value of the logging event.</dd>
045:         * <dt>time</dt>
046:         * <dd>Time value of the logging event.</dd>
047:         * <dt>rtime</dt>
048:         * <dd>Relative time value of the logging event.</dd>
049:         * <dt>throwable</dt>
050:         * <dd>Throwable value of the logging event.</dd>
051:         * <dt>priority</dt>
052:         * <dd>Priority value of the logging event.</dd>
053:         * </dl>
054:         * </li>
055:         * <li>'subformat' indicates a particular subformat and is currently only used
056:         * for category context to specify the context map parameter name.
057:         * </li>
058:         * </ul>
059:         * <p>A simple example of a typical PatternFormatter format:
060:         * </p>
061:         * <pre><code>%{time} %5.5{priority}[%-10.10{category}]: %{message}
062:         * </pre></code>
063:         * <p/>
064:         * This format string will format a log event printing first time value of
065:         * of log event with out size restriction, next priority with minum and maximum size 5,
066:         * next category right justified having minmum and maximum size of 10,
067:         * at last the message of the log event without size restriction.
068:         * </p>
069:         * <p>A formatted sample message of the above pattern format:
070:         * </p>
071:         * <pre><code>1000928827905 DEBUG [     junit]: Sample message
072:         * </pre><code>
073:         *
074:         * @author <a href="mailto:peter@apache.org">Peter Donald</a>
075:         * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
076:         * @version CVS $Revision: 1747 $ $Date: 2005-08-04 14:36:36 -0700 (Thu, 04 Aug 2005) $
077:         */
078:        public class PatternFormatter implements  Formatter {
079:            private final static int TYPE_TEXT = 1;
080:            private final static int TYPE_CATEGORY = 2;
081:            private final static int TYPE_CONTEXT = 3;
082:            private final static int TYPE_MESSAGE = 4;
083:            private final static int TYPE_TIME = 5;
084:            private final static int TYPE_RELATIVE_TIME = 6;
085:            private final static int TYPE_THROWABLE = 7;
086:            private final static int TYPE_PRIORITY = 8;
087:
088:            /**
089:             * The maximum value used for TYPEs. Subclasses can define their own TYPEs
090:             * starting at <code>MAX_TYPE + 1</code>.
091:             */
092:            protected final static int MAX_TYPE = TYPE_PRIORITY;
093:
094:            private final static String TYPE_CATEGORY_STR = "category";
095:            private final static String TYPE_CONTEXT_STR = "context";
096:            private final static String TYPE_MESSAGE_STR = "message";
097:            private final static String TYPE_TIME_STR = "time";
098:            private final static String TYPE_RELATIVE_TIME_STR = "rtime";
099:            private final static String TYPE_THROWABLE_STR = "throwable";
100:            private final static String TYPE_PRIORITY_STR = "priority";
101:
102:            private final static String SPACE_16 = "                ";
103:            private final static String SPACE_8 = "        ";
104:            private final static String SPACE_4 = "    ";
105:            private final static String SPACE_2 = "  ";
106:            private final static String SPACE_1 = " ";
107:
108:            private final static String EOL = System.getProperty(
109:                    "line.separator", "\n");
110:
111:            protected static class PatternRun {
112:                public String m_data;
113:                public boolean m_rightJustify;
114:                public int m_minSize;
115:                public int m_maxSize;
116:                public int m_type;
117:                public String m_format;
118:            }
119:
120:            private PatternRun m_formatSpecification[];
121:
122:            private FastDateFormat m_simpleDateFormat;
123:            private final Date m_date = new Date();
124:
125:            /**
126:             * @deprecated Use constructor PatternFormatter(String pattern) as this does not
127:             *             correctly initialize object
128:             */
129:            public PatternFormatter() {
130:            }
131:
132:            public PatternFormatter(final String pattern) {
133:                parse(pattern);
134:            }
135:
136:            /**
137:             * Extract and build a pattern from input string.
138:             *
139:             * @param stack   the stack on which to place patterns
140:             * @param pattern the input string
141:             * @param index   the start of pattern run
142:             * @return the number of characters in pattern run
143:             */
144:            private int addPatternRun(final Stack stack, final char pattern[],
145:                    int index) {
146:                final PatternRun run = new PatternRun();
147:                final int start = index++;
148:
149:                //first check for a +|- sign
150:                if ('+' == pattern[index])
151:                    index++;
152:                else if ('-' == pattern[index]) {
153:                    run.m_rightJustify = true;
154:                    index++;
155:                }
156:
157:                if (Character.isDigit(pattern[index])) {
158:                    int total = 0;
159:                    while (Character.isDigit(pattern[index])) {
160:                        total = total * 10 + (pattern[index] - '0');
161:                        index++;
162:                    }
163:                    run.m_minSize = total;
164:                }
165:
166:                //check for . sign indicating a maximum is to follow
167:                if (index < pattern.length && '.' == pattern[index]) {
168:                    index++;
169:
170:                    if (Character.isDigit(pattern[index])) {
171:                        int total = 0;
172:                        while (Character.isDigit(pattern[index])) {
173:                            total = total * 10 + (pattern[index] - '0');
174:                            index++;
175:                        }
176:                        run.m_maxSize = total;
177:                    }
178:                }
179:
180:                if (index >= pattern.length || '{' != pattern[index]) {
181:                    throw new IllegalArgumentException(
182:                            "Badly formed pattern at character " + index);
183:                }
184:
185:                int typeStart = index;
186:
187:                while (index < pattern.length && pattern[index] != ':'
188:                        && pattern[index] != '}') {
189:                    index++;
190:                }
191:
192:                int typeEnd = index - 1;
193:
194:                final String type = new String(pattern, typeStart + 1, typeEnd
195:                        - typeStart);
196:
197:                run.m_type = getTypeIdFor(type);
198:
199:                if (index < pattern.length && pattern[index] == ':') {
200:                    index++;
201:                    while (index < pattern.length && pattern[index] != '}')
202:                        index++;
203:
204:                    final int length = index - typeEnd - 2;
205:
206:                    if (0 != length) {
207:                        run.m_format = new String(pattern, typeEnd + 2, length);
208:                    }
209:                }
210:
211:                if (index >= pattern.length || '}' != pattern[index]) {
212:                    throw new IllegalArgumentException(
213:                            "Unterminated type in pattern at character "
214:                                    + index);
215:                }
216:
217:                index++;
218:
219:                stack.push(run);
220:
221:                return index - start;
222:            }
223:
224:            /**
225:             * Extract and build a text run  from input string.
226:             * It does special handling of '\n' and '\t' replaceing
227:             * them with newline and tab.
228:             *
229:             * @param stack   the stack on which to place runs
230:             * @param pattern the input string
231:             * @param index   the start of the text run
232:             * @return the number of characters in run
233:             */
234:            private int addTextRun(final Stack stack, final char pattern[],
235:                    int index) {
236:                final PatternRun run = new PatternRun();
237:                final int start = index;
238:                boolean escapeMode = false;
239:
240:                if ('%' == pattern[index])
241:                    index++;
242:
243:                final StringBuffer sb = new StringBuffer();
244:
245:                while (index < pattern.length && pattern[index] != '%') {
246:                    if (escapeMode) {
247:                        if ('n' == pattern[index])
248:                            sb.append(EOL);
249:                        else if ('t' == pattern[index])
250:                            sb.append('\t');
251:                        else
252:                            sb.append(pattern[index]);
253:                        escapeMode = false;
254:                    } else if ('\\' == pattern[index])
255:                        escapeMode = true;
256:                    else
257:                        sb.append(pattern[index]);
258:                    index++;
259:                }
260:
261:                run.m_data = sb.toString();
262:                run.m_type = TYPE_TEXT;
263:
264:                stack.push(run);
265:
266:                return index - start;
267:            }
268:
269:            /**
270:             * Utility to append a string to buffer given certain constraints.
271:             *
272:             * @param sb           the StringBuffer
273:             * @param minSize      the minimum size of output (0 to ignore)
274:             * @param maxSize      the maximum size of output (0 to ignore)
275:             * @param rightJustify true if the string is to be right justified in it's box.
276:             * @param output       the input string
277:             */
278:            private void append(final StringBuffer sb, final int minSize,
279:                    final int maxSize, final boolean rightJustify,
280:                    final String output) {
281:                final int size = output.length();
282:
283:                if (size < minSize) {
284:                    //assert( minSize > 0 );
285:                    if (rightJustify) {
286:                        appendWhiteSpace(sb, minSize - size);
287:                        sb.append(output);
288:                    } else {
289:                        sb.append(output);
290:                        appendWhiteSpace(sb, minSize - size);
291:                    }
292:                } else if (maxSize > 0 && maxSize < size) {
293:                    if (rightJustify) {
294:                        sb.append(output.substring(size - maxSize));
295:                    } else {
296:                        sb.append(output.substring(0, maxSize));
297:                    }
298:                } else {
299:                    sb.append(output);
300:                }
301:            }
302:
303:            /**
304:             * Append a certain number of whitespace characters to a StringBuffer.
305:             *
306:             * @param sb     the StringBuffer
307:             * @param length the number of spaces to append
308:             */
309:            private void appendWhiteSpace(final StringBuffer sb, int length) {
310:                while (length >= 16) {
311:                    sb.append(SPACE_16);
312:                    length -= 16;
313:                }
314:
315:                if (length >= 8) {
316:                    sb.append(SPACE_8);
317:                    length -= 8;
318:                }
319:
320:                if (length >= 4) {
321:                    sb.append(SPACE_4);
322:                    length -= 4;
323:                }
324:
325:                if (length >= 2) {
326:                    sb.append(SPACE_2);
327:                    length -= 2;
328:                }
329:
330:                if (length >= 1) {
331:                    sb.append(SPACE_1);
332:                    length -= 1;
333:                }
334:            }
335:
336:            /**
337:             * Format the event according to the pattern.
338:             *
339:             * @param event the event
340:             * @return the formatted output
341:             */
342:            public String format(final LogEvent event) {
343:                final StringBuffer sb = new StringBuffer();
344:
345:                for (int i = 0; i < m_formatSpecification.length; i++) {
346:                    final PatternRun run = m_formatSpecification[i];
347:
348:                    //treat text differently as it doesn't need min/max padding
349:                    if (run.m_type == TYPE_TEXT) {
350:                        sb.append(run.m_data);
351:                    } else {
352:                        final String data = formatPatternRun(event, run);
353:
354:                        if (null != data) {
355:                            append(sb, run.m_minSize, run.m_maxSize,
356:                                    run.m_rightJustify, data);
357:                        }
358:                    }
359:                }
360:
361:                return sb.toString();
362:            }
363:
364:            /**
365:             * Formats a single pattern run (can be extended in subclasses).
366:             *
367:             * @param run the pattern run to format.
368:             * @return the formatted result.
369:             */
370:            protected String formatPatternRun(final LogEvent event,
371:                    final PatternRun run) {
372:                switch (run.m_type) {
373:                case TYPE_RELATIVE_TIME:
374:                    return getRTime(event.getRelativeTime(), run.m_format);
375:                case TYPE_TIME:
376:                    return getTime(event.getTime(), run.m_format);
377:                case TYPE_THROWABLE:
378:                    return getStackTrace(event.getThrowable(), run.m_format);
379:                case TYPE_MESSAGE:
380:                    return getMessage(event.getMessage(), run.m_format);
381:                case TYPE_CATEGORY:
382:                    return getCategory(event.getCategory(), run.m_format);
383:                case TYPE_PRIORITY:
384:                    return getPriority(event.getPriority(), run.m_format);
385:
386:                case TYPE_CONTEXT:
387:                    //            if( null == run.m_format ||
388:                    //                run.m_format.startsWith( "stack" ) )
389:                    //            {
390:                    //                //Print a warning out to stderr here
391:                    //                //to indicate you are using a deprecated feature?
392:                    //                return getContext( event.getContextStack(), run.m_format );
393:                    //            }
394:                    //            else
395:                    //            {
396:                    return getContextMap(event.getContextMap(), run.m_format);
397:                    //            }
398:
399:                default:
400:                    throw new IllegalStateException(
401:                            "Unknown Pattern specification." + run.m_type);
402:                }
403:            }
404:
405:            /**
406:             * Utility method to format category.
407:             *
408:             * @param category the category string
409:             * @param format   ancilliary format parameter - allowed to be null
410:             * @return the formatted string
411:             */
412:            protected String getCategory(final String category,
413:                    final String format) {
414:                return category;
415:            }
416:
417:            /**
418:             * Get formatted priority string.
419:             */
420:            protected String getPriority(final Priority priority,
421:                    final String format) {
422:                return priority.getName();
423:            }
424:
425:            //    /**
426:            //     * Utility method to format context.
427:            //     *
428:            //     * @param context the context string
429:            //     * @param format ancilliary format parameter - allowed to be null
430:            //     * @return the formatted string
431:            //     * @deprecated Use getContextStack rather than this method
432:            //     */
433:            //    protected String getContext( final ContextStack stack, final String format )
434:            //    {
435:            //        return getContextStack( stack, format );
436:            //    }
437:
438:            //    /**
439:            //     * Utility method to format context.
440:            //     *
441:            //     * @param context the context string
442:            //     * @param format ancilliary format parameter - allowed to be null
443:            //     * @return the formatted string
444:            //     */
445:            //    protected String getContextStack( final ContextStack stack, final String format )
446:            //    {
447:            //        if( null == stack ) return "";
448:            //        return stack.toString( Integer.MAX_VALUE );
449:            //    }
450:
451:            /**
452:             * Utility method to format context map.
453:             *
454:             * @param map    the context map
455:             * @param format ancilliary format parameter - allowed to be null
456:             * @return the formatted string
457:             */
458:            protected String getContextMap(final ContextMap map,
459:                    final String format) {
460:                if (null == map)
461:                    return "";
462:                return map.get(format, "").toString();
463:            }
464:
465:            /**
466:             * Utility method to format message.
467:             *
468:             * @param message the message string
469:             * @param format  ancilliary format parameter - allowed to be null
470:             * @return the formatted string
471:             */
472:            protected String getMessage(final String message,
473:                    final String format) {
474:                return message;
475:            }
476:
477:            /**
478:             * Utility method to format stack trace.
479:             *
480:             * @param throwable the throwable instance
481:             * @param format    ancilliary format parameter - allowed to be null
482:             * @return the formatted string
483:             */
484:            protected String getStackTrace(final Throwable throwable,
485:                    final String format) {
486:                if (null == throwable)
487:                    return "";
488:                final StringWriter sw = new StringWriter();
489:                throwable.printStackTrace(new java.io.PrintWriter(sw));
490:                return sw.toString();
491:            }
492:
493:            /**
494:             * Utility method to format relative time.
495:             *
496:             * @param time   the time
497:             * @param format ancilliary format parameter - allowed to be null
498:             * @return the formatted string
499:             */
500:            protected String getRTime(final long time, final String format) {
501:                return getTime(time, format);
502:            }
503:
504:            /**
505:             * Utility method to format time.
506:             *
507:             * @param time   the time
508:             * @param format ancilliary format parameter - allowed to be null
509:             * @return the formatted string
510:             */
511:            protected String getTime(final long time, final String format) {
512:                if (null == format) {
513:                    return Long.toString(time);
514:                } else {
515:                    synchronized (m_date) {
516:                        if (null == m_simpleDateFormat) {
517:                            m_simpleDateFormat = FastDateFormat
518:                                    .getInstance(format);
519:                        }
520:                        m_date.setTime(time);
521:                        return m_simpleDateFormat.format(m_date);
522:                    }
523:                }
524:            }
525:
526:            /**
527:             * Retrieve the type-id for a particular string.
528:             *
529:             * @param type the string
530:             * @return the type-id
531:             */
532:            protected int getTypeIdFor(final String type) {
533:                if (type.equalsIgnoreCase(TYPE_CATEGORY_STR))
534:                    return TYPE_CATEGORY;
535:                else if (type.equalsIgnoreCase(TYPE_CONTEXT_STR))
536:                    return TYPE_CONTEXT;
537:                else if (type.equalsIgnoreCase(TYPE_MESSAGE_STR))
538:                    return TYPE_MESSAGE;
539:                else if (type.equalsIgnoreCase(TYPE_PRIORITY_STR))
540:                    return TYPE_PRIORITY;
541:                else if (type.equalsIgnoreCase(TYPE_TIME_STR))
542:                    return TYPE_TIME;
543:                else if (type.equalsIgnoreCase(TYPE_RELATIVE_TIME_STR))
544:                    return TYPE_RELATIVE_TIME;
545:                else if (type.equalsIgnoreCase(TYPE_THROWABLE_STR)) {
546:                    return TYPE_THROWABLE;
547:                } else {
548:                    throw new IllegalArgumentException(
549:                            "Unknown Type in pattern - " + type);
550:                }
551:            }
552:
553:            /**
554:             * Parse the input pattern and build internal data structures.
555:             *
556:             * @param patternString the pattern
557:             */
558:            protected final void parse(final String patternString) {
559:                final Stack stack = new Stack();
560:                final int size = patternString.length();
561:                final char pattern[] = new char[size];
562:                int index = 0;
563:
564:                patternString.getChars(0, size, pattern, 0);
565:
566:                while (index < size) {
567:                    if (pattern[index] == '%'
568:                            && !(index != size - 1 && pattern[index + 1] == '%')) {
569:                        index += addPatternRun(stack, pattern, index);
570:                    } else {
571:                        index += addTextRun(stack, pattern, index);
572:                    }
573:                }
574:
575:                final int elementCount = stack.size();
576:
577:                m_formatSpecification = new PatternRun[elementCount];
578:
579:                for (int i = 0; i < elementCount; i++) {
580:                    m_formatSpecification[i] = (PatternRun) stack.elementAt(i);
581:                }
582:            }
583:
584:            /**
585:             * Set the string description that the format is extracted from.
586:             *
587:             * @param format the string format
588:             * @deprecated Parse format in via constructor rather than use this method
589:             */
590:            public void setFormat(final String format) {
591:                parse(format);
592:            }
593:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.