View Javadoc
1   package org.codehaus.mojo.jaxb2;
2   
3   import org.apache.maven.plugin.logging.Log;
4   import org.codehaus.mojo.jaxb2.shared.Validate;
5   
6   import java.text.NumberFormat;
7   import java.util.Map;
8   import java.util.SortedMap;
9   import java.util.TreeMap;
10  
11  /**
12   * Trivial Maven Log implementation which stores all logged messages
13   * within a SortedMap for later retrieval.
14   *
15   * @author <a href="mailto:lj@jguru.se">Lennart J&ouml;relid</a>, jGuru Europe AB
16   */
17  public class BufferingLog implements Log {
18  
19      public enum LogLevel {
20          DEBUG,
21          INFO,
22          WARN,
23          ERROR,
24          NONE
25      }
26  
27      // Internal state
28      private static final NumberFormat INTEGER_FORMAT = NumberFormat.getIntegerInstance();
29      private LogLevel minLevel;
30      private final Object lock = new Object();
31      private SortedMap<String, Throwable> logBuffer;
32  
33      static {
34          setMinimumIntegerDigits(3);
35      }
36  
37      public BufferingLog() {
38          this(LogLevel.INFO);
39      }
40  
41      public BufferingLog(final LogLevel minLevel) {
42  
43          // Check sanity
44          Validate.notNull(minLevel, "minLevel");
45  
46          // Assign internal state
47          logBuffer = new TreeMap<String, Throwable>();
48          this.minLevel = minLevel;
49      }
50  
51      /**
52       * @return The minimum LogLevel for which this BufferingLog will record log events.
53       */
54      public LogLevel getMinimumLogLevel() {
55          return minLevel;
56      }
57  
58      /**
59       * @return The LogBuffer holding all log messages, and their corresponding (optional) Throwable.
60       */
61      public SortedMap<String, Throwable> getLogBuffer() {
62          return logBuffer;
63      }
64  
65      /**
66       * Retrieves the current LogBuffer, and resets the internal state of this BufferingLog.
67       *
68       * @return The LogBuffer holding all log messages, and their corresponding (optional) Throwable.
69       */
70      public SortedMap<String, Throwable> getAndResetLogBuffer() {
71  
72          final SortedMap<String, Throwable> toReturn = logBuffer;
73          synchronized (lock) {
74              this.logBuffer = new TreeMap<String, Throwable>();
75          }
76  
77          return toReturn;
78      }
79  
80      /**
81       * Assigns the minimum number of Integer digits in the Log format.
82       *
83       * @param minimumIntegerDigits the minimum number of Integer digits in the Log format.
84       */
85      public static void setMinimumIntegerDigits(final int minimumIntegerDigits) {
86          INTEGER_FORMAT.setMinimumIntegerDigits(minimumIntegerDigits);
87      }
88  
89      /**
90       * @return A Pretty-printed version of the log buffer.
91       */
92      public String getPrettyPrintedLog() {
93  
94          final StringBuilder builder = new StringBuilder();
95          for (Map.Entry<String, Throwable> current : logBuffer.entrySet()) {
96              builder.append("\n").append(current.getKey());
97  
98              final Throwable error = current.getValue();
99              if (error != null) {
100                 builder.append(" [" + error.getMessage() + "]: " + error.getClass().getSimpleName());
101             }
102         }
103 
104         // All done.
105         return builder.toString();
106     }
107 
108     /**
109      * {@inheritDoc}
110      */
111     public void debug(CharSequence content, Throwable error) {
112         addLogEntry(LogLevel.DEBUG, content, error);
113     }
114 
115     /**
116      * {@inheritDoc}
117      */
118     public void debug(CharSequence content) {
119         debug(content, null);
120     }
121 
122     /**
123      * {@inheritDoc}
124      */
125     public void debug(Throwable error) {
126         debug("", error);
127     }
128 
129     /**
130      * {@inheritDoc}
131      */
132     public void info(CharSequence content, Throwable error) {
133         addLogEntry(LogLevel.INFO, content, error);
134     }
135 
136     /**
137      * {@inheritDoc}
138      */
139     public void info(CharSequence content) {
140         info(content, null);
141     }
142 
143     /**
144      * {@inheritDoc}
145      */
146     public void info(Throwable error) {
147         info("", error);
148     }
149 
150     /**
151      * {@inheritDoc}
152      */
153     public void warn(CharSequence content, Throwable error) {
154         addLogEntry(LogLevel.WARN, content, error);
155     }
156 
157     /**
158      * {@inheritDoc}
159      */
160     public void warn(CharSequence content) {
161         warn(content, null);
162     }
163 
164     /**
165      * {@inheritDoc}
166      */
167     public void warn(Throwable error) {
168         warn("", error);
169     }
170 
171     /**
172      * {@inheritDoc}
173      */
174     public void error(final CharSequence content, final Throwable error) {
175         addLogEntry(LogLevel.ERROR, content, error);
176     }
177 
178     /**
179      * {@inheritDoc}
180      */
181     public void error(CharSequence content) {
182         error(content, null);
183     }
184 
185     /**
186      * {@inheritDoc}
187      */
188     public void error(final Throwable error) {
189         error("", error);
190     }
191 
192     /**
193      * {@inheritDoc}
194      */
195     public boolean isDebugEnabled() {
196         return isLogEnabledFor(LogLevel.DEBUG);
197     }
198 
199     /**
200      * {@inheritDoc}
201      */
202     public boolean isInfoEnabled() {
203         return isLogEnabledFor(LogLevel.INFO);
204     }
205 
206     /**
207      * {@inheritDoc}
208      */
209     public boolean isWarnEnabled() {
210         return isLogEnabledFor(LogLevel.WARN);
211     }
212 
213     /**
214      * {@inheritDoc}
215      */
216     public boolean isErrorEnabled() {
217         return isLogEnabledFor(LogLevel.ERROR);
218     }
219 
220     //
221     // Private helpers
222     //
223 
224     private void addLogEntry(final LogLevel level, final CharSequence message, final Throwable throwable) {
225 
226         synchronized (lock) {
227             if (isLogEnabledFor(level)) {
228 
229                 final int index = logBuffer.size();
230                 final String logMessage = "" + INTEGER_FORMAT.format(index) + ": (" + level + ") " + message;
231                 logBuffer.put(logMessage, throwable);
232             }
233         }
234     }
235 
236     private boolean isLogEnabledFor(final LogLevel level) {
237         return level.compareTo(minLevel) >= 0;
238     }
239 }