View Javadoc
1   package org.codehaus.mojo.jaxb2.shared.environment.logging;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.plugin.logging.Log;
23  import org.codehaus.mojo.jaxb2.shared.Validate;
24  
25  import java.io.UnsupportedEncodingException;
26  import java.util.Arrays;
27  import java.util.List;
28  import java.util.logging.Filter;
29  import java.util.logging.Handler;
30  import java.util.logging.Level;
31  import java.util.logging.LogRecord;
32  import java.util.logging.SimpleFormatter;
33  
34  /**
35   * Handler implementation which delegates its actual logging to an internal Maven log.
36   *
37   * @author <a href="mailto:lj@jguru.se">Lennart J&ouml;relid</a>, jGuru Europe AB
38   * @since 2.0
39   */
40  public class MavenLogHandler extends Handler {
41  
42      // Internal state
43      private Log log;
44      private String prefix;
45  
46      /**
47       * Creates a new MavenLogHandler which adapts a Handler to emit log messages onto a Maven Log.
48       *
49       * @param log                       The Maven Log to emit log messages to.
50       * @param prefix                    An optional prefix used to prefix any log message.
51       * @param encoding                  The encoding which should be used.
52       * @param acceptedLogRecordPrefixes A non-null list of prefixes holding LogRecord logger names for
53       *                                  permitted/accepted LogRecords.
54       */
55      public MavenLogHandler(final Log log,
56                             final String prefix,
57                             final String encoding,
58                             final String[] acceptedLogRecordPrefixes) {
59  
60          // Check sanity
61          Validate.notNull(log, "log");
62          Validate.notNull(prefix, "prefix");
63          Validate.notEmpty(encoding, "encoding");
64  
65          // Assign internal state
66          this.log = log;
67          this.prefix = prefix.isEmpty() ? "" : "[" + prefix + "]: ";
68  
69          setFormatter(new SimpleFormatter());
70          setLevel(getJavaUtilLoggingLevelFor(log));
71          try {
72              setEncoding(encoding);
73          } catch (UnsupportedEncodingException e) {
74              log.error("Could not use encoding '" + encoding + "'", e);
75          }
76  
77          if (acceptedLogRecordPrefixes != null && acceptedLogRecordPrefixes.length > 0) {
78              setFilter(getLoggingFilter(acceptedLogRecordPrefixes));
79          }
80      }
81  
82      /**
83       * {@inheritDoc}
84       */
85      @Override
86      public void publish(final LogRecord record) {
87  
88          if (this.isLoggable(record)) {
89  
90              final Level level = record.getLevel();
91              final String message = prefix + getFormatter().format(record);
92  
93              if (Level.SEVERE.equals(level)) {
94                  log.error(message);
95              } else if (Level.WARNING.equals(level)) {
96                  log.warn(message);
97              } else if (Level.INFO.equals(level)) {
98                  log.info(message);
99              } else {
100                 log.debug(message);
101             }
102         }
103     }
104 
105     /**
106      * {@inheritDoc}
107      */
108     @Override
109     public void flush() {
110         // Do nothing.
111     }
112 
113     /**
114      * {@inheritDoc}
115      */
116     @Override
117     public void close() throws SecurityException {
118         // Do nothing.
119     }
120 
121     /**
122      * Retrieves the JUL Level matching the supplied Maven Log.
123      *
124      * @param mavenLog A non-null Maven Log.
125      * @return The Corresponding JUL Level.
126      */
127     public static Level getJavaUtilLoggingLevelFor(final Log mavenLog) {
128 
129         // Check sanity
130         Validate.notNull(mavenLog, "mavenLog");
131 
132         Level toReturn = Level.SEVERE;
133 
134         if (mavenLog.isDebugEnabled()) {
135             toReturn = Level.FINER;
136         } else if (mavenLog.isInfoEnabled()) {
137             toReturn = Level.INFO;
138         } else if (mavenLog.isWarnEnabled()) {
139             toReturn = Level.WARNING;
140         }
141 
142         // All Done.
143         return toReturn;
144     }
145 
146     /**
147      * Retrieves a java.util.Logging filter used to ensure that only LogRecords whose
148      * logger names start with any of the required prefixes are logged.
149      *
150      * @param requiredPrefixes A non-null list of prefixes to be matched with the LogRecord logger names.
151      * @return A java.util.logging Filter that only permits logging LogRecords whose
152      * logger names start with any of the required prefixes.
153      */
154     public static Filter getLoggingFilter(final String... requiredPrefixes) {
155 
156         // Check sanity
157         Validate.notNull(requiredPrefixes, "requiredPrefixes");
158 
159         // All done.
160         return new Filter() {
161 
162             // Internal state
163             private List<String> requiredPrefs = Arrays.asList(requiredPrefixes);
164 
165             @Override
166             public boolean isLoggable(final LogRecord record) {
167 
168                 final String loggerName = record.getLoggerName();
169                 for (String current : requiredPrefs) {
170                     if (loggerName.startsWith(current)) {
171                         return true;
172                     }
173                 }
174 
175                 // No matches found.
176                 return false;
177             }
178         };
179     }
180 }