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ö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 }