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.AbstractJaxbMojo;
24  import org.codehaus.mojo.jaxb2.shared.Validate;
25  import org.codehaus.mojo.jaxb2.shared.environment.AbstractLogAwareFacet;
26  
27  import java.util.ArrayList;
28  import java.util.List;
29  import java.util.logging.Handler;
30  import java.util.logging.Level;
31  import java.util.logging.Logger;
32  
33  /**
34   * EnvironmentFacet for replacing Handlers from Java Util Logging with a Maven Log.
35   *
36   * @author <a href="mailto:lj@jguru.se">Lennart J&ouml;relid</a>, jGuru Europe AB
37   * @since 2.1
38   */
39  public class LoggingHandlerEnvironmentFacet extends AbstractLogAwareFacet {
40  
41      /**
42       * Standard logger names/categories for the java.util.Logger.
43       */
44      public static final String[] DEFAULT_LOGGER_NAMES = new String[]{"com.sun", "javax.xml", "javax.tools"};
45  
46      // Internal state
47      private boolean restored;
48      private Logger rootLogger;
49      private Level originalRootLoggerLevel;
50      private List<Handler> originalHandlers;
51      private MavenLogHandler mavenLogHandler;
52  
53      private String logPrefix;
54      private String encoding;
55      private String[] loggerNamePrefixes;
56  
57      /**
58       * Creates a new JavaLoggingEnvironment, using the supplied variables to set up a MavenLogHandler.
59       * The MavenLogHandler is then assigned to the root logger.
60       *
61       * @param logPrefix          The prefix to use for the logger, indicating which tool is used by the log. Example: "XJC"
62       *                           or "SchemaGen".
63       * @param mavenLog           The active Maven Log.
64       * @param encoding           The configured encoding.
65       * @param loggerNamePrefixes The prefixes of the Logger names to be permitted logging.
66       */
67      public LoggingHandlerEnvironmentFacet(final String logPrefix,
68                                            final Log mavenLog,
69                                            final String encoding,
70                                            final String[] loggerNamePrefixes) {
71  
72          super(mavenLog);
73  
74          // Check sanity
75          Validate.notEmpty(encoding, "encoding");
76          Validate.notNull(loggerNamePrefixes, "loggerNamePrefixes");
77  
78          // Assign internal state
79          this.originalHandlers = new ArrayList<Handler>();
80          this.logPrefix = logPrefix;
81          rootLogger = Logger.getLogger("");
82          originalRootLoggerLevel = rootLogger.getLevel();
83          this.encoding = encoding;
84          this.loggerNamePrefixes = loggerNamePrefixes;
85      }
86  
87      /**
88       * {@inheritDoc}
89       * <p>Redirects JUL logging statements to the Maven Log.</p>
90       */
91      @Override
92      public void setup() {
93  
94          // Redirect the JUL Logging statements to the Maven Log.
95          rootLogger.setLevel(MavenLogHandler.getJavaUtilLoggingLevelFor(log));
96          this.mavenLogHandler = new MavenLogHandler(log, logPrefix, encoding, loggerNamePrefixes);
97  
98          for (Handler current : rootLogger.getHandlers()) {
99  
100             // Stash the original handlers from the RootLogger.
101             originalHandlers.add(current);
102 
103             // Remove the original handler from the RootLogger.
104             rootLogger.removeHandler(current);
105         }
106 
107         // Add the new Maven Log handler.
108         rootLogger.addHandler(this.mavenLogHandler);
109     }
110 
111     /**
112      * Restores the original root Logger state, including Level and Handlers.
113      */
114     public void restore() {
115 
116         if (!restored) {
117 
118             // Remove the extra Handler from the RootLogger
119             rootLogger.removeHandler(mavenLogHandler);
120 
121             // Restore the original state to the Root logger
122             rootLogger.setLevel(originalRootLoggerLevel);
123             for (Handler current : originalHandlers) {
124                 rootLogger.addHandler(current);
125             }
126 
127             // All done.
128             restored = true;
129         }
130     }
131 
132     /**
133      * Factory method creating a new LoggingHandlerEnvironmentFacet wrapping the supplied properties.
134      *
135      * @param mavenLog The active Maven Log.
136      * @param caller   The AbstractJaxbMojo subclass which invoked this LoggingHandlerEnvironmentFacet factory method.
137      * @param encoding The encoding used by the Maven Mojo subclass.
138      * @return A fully set up LoggingHandlerEnvironmentFacet
139      */
140     public static LoggingHandlerEnvironmentFacet create(final Log mavenLog,
141                                                         final Class<? extends AbstractJaxbMojo> caller,
142                                                         final String encoding) {
143 
144         // Check sanity
145         Validate.notNull(mavenLog, "mavenLog");
146         Validate.notNull(caller, "caller");
147         Validate.notEmpty(encoding, "encoding");
148 
149         // Find the standard log prefix for the tool in question.
150         final String logPrefix = caller.getClass().getCanonicalName().toUpperCase().contains("XJC")
151                 ? "XJC"
152                 : "SchemaGen";
153 
154         // All done.
155         return new LoggingHandlerEnvironmentFacet(logPrefix, mavenLog, encoding, DEFAULT_LOGGER_NAMES);
156     }
157 }