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