View Javadoc
1   /*
2    * #%L
3    * JulLog.java - mongodb-async-driver - Allanbank Consulting, Inc.
4    * %%
5    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.allanbank.mongodb.util.log;
21  
22  import java.util.logging.Level;
23  import java.util.logging.LogRecord;
24  import java.util.logging.Logger;
25  
26  /**
27   * JulLog is the simplified logging implementation for Java Util Logging.
28   * 
29   * @api.no This class is <b>NOT</b> part of the drivers API. This class may be
30   *         mutated in incompatible ways between any two releases of the driver.
31   * @copyright 2014, Allanbank Consulting, Inc., All Rights Reserved
32   */
33  public class JulLog extends AbstractLog {
34  
35      /** The delegate for the log to a {@link Logger}. */
36      private final Logger myDelegate;
37  
38      /**
39       * Creates a new {@link JulLog}.
40       * 
41       * @param clazz
42       *            The class for the logger.
43       */
44      protected JulLog(final Class<?> clazz) {
45          myDelegate = Logger.getLogger(clazz.getName());
46      }
47  
48      /**
49       * {@inheritDoc}
50       * <p>
51       * Overridden to create a {@link LogRecord} based on the log information.
52       * </p>
53       * 
54       * @see Log#log(Level, Throwable, String, Object[])
55       */
56      @Override
57      protected final void doLog(final Level level, final Throwable thrown,
58              final String template, final Object... args) {
59          if (myDelegate.isLoggable(level)) {
60  
61              final Thread currentThread = Thread.currentThread();
62              final LogRecord record = new LogRecord(level,
63                      format(template, args));
64              record.setLoggerName(myDelegate.getName());
65              record.setThrown(thrown);
66              record.setThreadID((int) Thread.currentThread().getId());
67  
68              // Note the name of the class is the AbstractLog which is where all
69              // of
70              // the public log methods are implemented.
71              boolean lookingForThisClass = true;
72              for (final StackTraceElement element : currentThread
73                      .getStackTrace()) {
74                  final String className = element.getClassName();
75  
76                  // Find this method (and maybe others from this class).
77                  if (lookingForThisClass) {
78                      lookingForThisClass = !CLASS_NAME.equals(className);
79                  }
80                  else {
81                      // And back until we are past this class.
82                      if (!CLASS_NAME.equals(className)) {
83                          record.setSourceClassName(className);
84                          record.setSourceMethodName(element.getMethodName());
85                          break;
86                      }
87                  }
88              }
89  
90              // Finally - log it.
91              myDelegate.log(record);
92          }
93      }
94  
95      /**
96       * Formats the message to be logged.
97       * 
98       * @param template
99       *            The template for the message.
100      * @param args
101      *            The arguments to use to replace the {@value #REPLACE_TOKEN}
102      *            entries in the template.
103      * @return The formatted message.
104      */
105     private String format(final String template, final Object[] args) {
106         String result = template;
107         if ((args != null) && (args.length > 0)
108                 && (template.indexOf(REPLACE_TOKEN) >= 0)) {
109 
110             final StringBuilder builder = new StringBuilder(template.length());
111             for (final Object arg : args) {
112                 final int index = result.indexOf(REPLACE_TOKEN);
113                 if (index < 0) {
114                     break;
115                 }
116 
117                 builder.append(result.substring(0, index));
118                 builder.append(arg);
119                 result = result.substring(index + 2);
120             }
121 
122             builder.append(result);
123             result = builder.toString();
124         }
125         return result;
126     }
127 
128 }