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