View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.assembly.io;
20  
21  import java.io.PrintWriter;
22  import java.io.StringWriter;
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  /**
28   * Default Message Holder.
29   *
30   */
31  class DefaultMessageHolder implements MessageHolder {
32  
33      private List<Message> messages = new ArrayList<>();
34  
35      private Message currentMessage;
36  
37      private int defaultMessageLevel = MessageLevels.LEVEL_INFO;
38  
39      private boolean[] messageLevelStates;
40  
41      private MessageSink onDemandSink;
42  
43      /**
44       * Create instance.
45       */
46      DefaultMessageHolder() {
47          this.messageLevelStates = MessageLevels.getLevelStates(MessageLevels.LEVEL_INFO);
48      }
49  
50      /** {@inheritDoc} */
51      public MessageHolder addMessage(CharSequence messagePart, Throwable error) {
52          return addMessage(defaultMessageLevel, messagePart, error);
53      }
54  
55      /**
56       * @param level Level.
57       * @param messagePart Message part.
58       * @param error {@link Throwable}
59       * @return {@link MessageHolder}
60       */
61      MessageHolder addMessage(int level, CharSequence messagePart, Throwable error) {
62          newMessage(level);
63          append(messagePart.toString());
64          append(error);
65  
66          return this;
67      }
68  
69      /** {@inheritDoc} */
70      public MessageHolder addMessage(CharSequence messagePart) {
71          return addMessage(defaultMessageLevel, messagePart);
72      }
73  
74      /**
75       * @param level level.
76       * @param messagePart message part.
77       * @return {@link MessageHolder}
78       */
79      protected MessageHolder addMessage(int level, CharSequence messagePart) {
80          newMessage(level);
81          append(messagePart.toString());
82  
83          return this;
84      }
85  
86      /** {@inheritDoc} */
87      public MessageHolder addMessage(Throwable error) {
88          return addMessage(defaultMessageLevel, error);
89      }
90  
91      /**
92       * @param level level.
93       * @param error {@link Throwable}
94       * @return {@link MessageHolder}
95       */
96      protected MessageHolder addMessage(int level, Throwable error) {
97          newMessage(level);
98          append(error);
99  
100         return this;
101     }
102 
103     /** {@inheritDoc} */
104     public MessageHolder append(CharSequence messagePart) {
105         if (currentMessage == null) {
106             newMessage();
107         }
108 
109         currentMessage.append(messagePart.toString());
110 
111         return this;
112     }
113 
114     /** {@inheritDoc} */
115     public MessageHolder append(Throwable error) {
116         if (currentMessage == null) {
117             newMessage();
118         }
119 
120         currentMessage.setError(error);
121 
122         return this;
123     }
124 
125     /** {@inheritDoc} */
126     public boolean isEmpty() {
127         return messages.isEmpty();
128     }
129 
130     /** {@inheritDoc} */
131     public MessageHolder newMessage() {
132         newMessage(defaultMessageLevel);
133 
134         return this;
135     }
136 
137     /**
138      * @param messageLevel message level.
139      */
140     protected void newMessage(int messageLevel) {
141         if (onDemandSink != null && currentMessage != null) {
142             renderTo(currentMessage, onDemandSink);
143         }
144 
145         currentMessage = new Message(messageLevel, onDemandSink);
146         messages.add(currentMessage);
147     }
148 
149     /** {@inheritDoc} */
150     public String render() {
151         StringBuilder buffer = new StringBuilder();
152 
153         int counter = 1;
154         for (Iterator<Message> it = messages.iterator(); it.hasNext(); ) {
155             Message message = it.next();
156 
157             int ml = message.getMessageLevel();
158 
159             if (ml >= messageLevelStates.length || ml < 0) {
160                 ml = MessageLevels.LEVEL_DEBUG;
161             }
162 
163             if (!messageLevelStates[ml]) {
164                 continue;
165             }
166 
167             CharSequence content = message.render();
168             String label = MessageLevels.getLevelLabel(message.getMessageLevel());
169 
170             if (content.length() > label.length() + 3) {
171                 buffer.append('[').append(counter++).append("] ");
172                 buffer.append(content);
173 
174                 if (it.hasNext()) {
175                     buffer.append("\n\n");
176                 }
177             }
178         }
179 
180         return buffer.toString();
181     }
182 
183     /** {@inheritDoc} */
184     public int size() {
185         return messages.size();
186     }
187 
188     private static final class Message {
189         private StringBuffer message = new StringBuffer();
190 
191         private Throwable error;
192 
193         private final int messageLevel;
194 
195         private final MessageSink onDemandSink;
196 
197         Message(int messageLevel, MessageSink onDemandSink) {
198             this.messageLevel = messageLevel;
199 
200             this.onDemandSink = onDemandSink;
201         }
202 
203         public Message setError(Throwable pError) {
204             this.error = pError;
205             return this;
206         }
207 
208         public Message append(CharSequence pMessage) {
209             this.message.append(pMessage.toString());
210             return this;
211         }
212 
213         /**
214          * @return message level.
215          */
216         public int getMessageLevel() {
217             return messageLevel;
218         }
219 
220         /**
221          * @return Sequence.
222          */
223         public CharSequence render() {
224             StringBuffer buffer = new StringBuffer();
225 
226             if (onDemandSink == null) {
227                 buffer.append('[')
228                         .append(MessageLevels.getLevelLabel(messageLevel))
229                         .append("] ");
230             }
231             if (message != null && message.length() > 0) {
232                 buffer.append(message);
233 
234                 if (error != null) {
235                     buffer.append('\n');
236                 }
237             }
238 
239             if (error != null) {
240                 buffer.append("Error:\n");
241 
242                 StringWriter sw = new StringWriter();
243                 PrintWriter pw = new PrintWriter(sw);
244                 error.printStackTrace(pw);
245 
246                 buffer.append(sw);
247             }
248 
249             return buffer;
250         }
251     }
252 
253     /** {@inheritDoc} */
254     public MessageHolder addDebugMessage(CharSequence messagePart, Throwable error) {
255         return addMessage(MessageLevels.LEVEL_DEBUG, messagePart, error);
256     }
257 
258     /** {@inheritDoc} */
259     public MessageHolder addDebugMessage(CharSequence messagePart) {
260         return addMessage(MessageLevels.LEVEL_DEBUG, messagePart);
261     }
262 
263     /** {@inheritDoc} */
264     public MessageHolder addDebugMessage(Throwable error) {
265         return addMessage(MessageLevels.LEVEL_DEBUG, error);
266     }
267 
268     /** {@inheritDoc} */
269     public MessageHolder addErrorMessage(CharSequence messagePart, Throwable error) {
270         return addMessage(MessageLevels.LEVEL_ERROR, messagePart, error);
271     }
272 
273     /** {@inheritDoc} */
274     public MessageHolder addErrorMessage(CharSequence messagePart) {
275         return addMessage(MessageLevels.LEVEL_ERROR, messagePart);
276     }
277 
278     /** {@inheritDoc} */
279     public MessageHolder addErrorMessage(Throwable error) {
280         return addMessage(MessageLevels.LEVEL_ERROR, error);
281     }
282 
283     /** {@inheritDoc} */
284     public MessageHolder addInfoMessage(CharSequence messagePart, Throwable error) {
285         return addMessage(MessageLevels.LEVEL_INFO, messagePart, error);
286     }
287 
288     /** {@inheritDoc} */
289     public MessageHolder addInfoMessage(CharSequence messagePart) {
290         return addMessage(MessageLevels.LEVEL_INFO, messagePart);
291     }
292 
293     /** {@inheritDoc} */
294     public MessageHolder addInfoMessage(Throwable error) {
295         return addMessage(MessageLevels.LEVEL_INFO, error);
296     }
297 
298     /** {@inheritDoc} */
299     public MessageHolder addSevereMessage(CharSequence messagePart, Throwable error) {
300         return addMessage(MessageLevels.LEVEL_SEVERE, messagePart, error);
301     }
302 
303     /** {@inheritDoc} */
304     public MessageHolder addSevereMessage(CharSequence messagePart) {
305         return addMessage(MessageLevels.LEVEL_SEVERE, messagePart);
306     }
307 
308     /** {@inheritDoc} */
309     public MessageHolder addSevereMessage(Throwable error) {
310         return addMessage(MessageLevels.LEVEL_SEVERE, error);
311     }
312 
313     /** {@inheritDoc} */
314     public MessageHolder addWarningMessage(CharSequence messagePart, Throwable error) {
315         return addMessage(MessageLevels.LEVEL_WARNING, messagePart, error);
316     }
317 
318     /** {@inheritDoc} */
319     public MessageHolder addWarningMessage(CharSequence messagePart) {
320         return addMessage(MessageLevels.LEVEL_WARNING, messagePart);
321     }
322 
323     /** {@inheritDoc} */
324     public MessageHolder addWarningMessage(Throwable error) {
325         return addMessage(MessageLevels.LEVEL_WARNING, error);
326     }
327 
328     /** {@inheritDoc} */
329     public int countDebugMessages() {
330         return countMessagesOfType(MessageLevels.LEVEL_DEBUG);
331     }
332 
333     /** {@inheritDoc} */
334     public int countErrorMessages() {
335         return countMessagesOfType(MessageLevels.LEVEL_ERROR);
336     }
337 
338     /** {@inheritDoc} */
339     public int countInfoMessages() {
340         return countMessagesOfType(MessageLevels.LEVEL_INFO);
341     }
342 
343     /** {@inheritDoc} */
344     public int countMessages() {
345         return size();
346     }
347 
348     /** {@inheritDoc} */
349     public int countSevereMessages() {
350         return countMessagesOfType(MessageLevels.LEVEL_SEVERE);
351     }
352 
353     /** {@inheritDoc} */
354     public int countWarningMessages() {
355         return countMessagesOfType(MessageLevels.LEVEL_WARNING);
356     }
357 
358     /**
359      * @param messageLevel leve.
360      * @return number of messages.
361      */
362     private int countMessagesOfType(int messageLevel) {
363         int count = 0;
364 
365         for (Message message : messages) {
366             if (messageLevel == message.getMessageLevel()) {
367                 count++;
368             }
369         }
370 
371         return count;
372     }
373 
374     /** {@inheritDoc} */
375     public boolean isDebugEnabled() {
376         return messageLevelStates[MessageLevels.LEVEL_DEBUG];
377     }
378 
379     /** {@inheritDoc} */
380     public boolean isErrorEnabled() {
381         return messageLevelStates[MessageLevels.LEVEL_ERROR];
382     }
383 
384     /** {@inheritDoc} */
385     public boolean isInfoEnabled() {
386         return messageLevelStates[MessageLevels.LEVEL_INFO];
387     }
388 
389     /** {@inheritDoc} */
390     public boolean isSevereEnabled() {
391         return messageLevelStates[MessageLevels.LEVEL_SEVERE];
392     }
393 
394     /** {@inheritDoc} */
395     public boolean isWarningEnabled() {
396         return messageLevelStates[MessageLevels.LEVEL_WARNING];
397     }
398 
399     /** {@inheritDoc} */
400     public MessageHolder newDebugMessage() {
401         if (isDebugEnabled()) {
402             newMessage(MessageLevels.LEVEL_DEBUG);
403         }
404 
405         return this;
406     }
407 
408     /** {@inheritDoc} */
409     public MessageHolder newErrorMessage() {
410         if (isErrorEnabled()) {
411             newMessage(MessageLevels.LEVEL_ERROR);
412         }
413 
414         return this;
415     }
416 
417     /** {@inheritDoc} */
418     public MessageHolder newInfoMessage() {
419         if (isInfoEnabled()) {
420             newMessage(MessageLevels.LEVEL_INFO);
421         }
422 
423         return this;
424     }
425 
426     /** {@inheritDoc} */
427     public MessageHolder newSevereMessage() {
428         if (isSevereEnabled()) {
429             newMessage(MessageLevels.LEVEL_SEVERE);
430         }
431 
432         return this;
433     }
434 
435     /** {@inheritDoc} */
436     public MessageHolder newWarningMessage() {
437         if (isWarningEnabled()) {
438             newMessage(MessageLevels.LEVEL_WARNING);
439         }
440 
441         return this;
442     }
443 
444     /** {@inheritDoc} */
445     public void setDebugEnabled(boolean enabled) {
446         messageLevelStates[MessageLevels.LEVEL_DEBUG] = enabled;
447     }
448 
449     /** {@inheritDoc} */
450     public void setErrorEnabled(boolean enabled) {
451         messageLevelStates[MessageLevels.LEVEL_ERROR] = enabled;
452     }
453 
454     /** {@inheritDoc} */
455     public void setInfoEnabled(boolean enabled) {
456         messageLevelStates[MessageLevels.LEVEL_INFO] = enabled;
457     }
458 
459     /** {@inheritDoc} */
460     public void setSevereEnabled(boolean enabled) {
461         messageLevelStates[MessageLevels.LEVEL_SEVERE] = enabled;
462     }
463 
464     /** {@inheritDoc} */
465     public void setWarningEnabled(boolean enabled) {
466         messageLevelStates[MessageLevels.LEVEL_WARNING] = enabled;
467     }
468 
469     /** {@inheritDoc} */
470     public void flush() {
471         if (onDemandSink != null && currentMessage != null) {
472             renderTo(currentMessage, onDemandSink);
473             currentMessage = null;
474         }
475     }
476 
477     /** {@inheritDoc} */
478     public void render(MessageSink sink) {
479         for (Message message : messages) {
480             renderTo(message, sink);
481         }
482     }
483 
484     /**
485      * @param message {@link Message}
486      * @param sink {@link MessageSink}
487      */
488     protected void renderTo(Message message, MessageSink sink) {
489         switch (message.getMessageLevel()) {
490             case (MessageLevels.LEVEL_SEVERE):
491                 sink.severe(message.render().toString());
492                 break;
493 
494             case (MessageLevels.LEVEL_ERROR):
495                 sink.error(message.render().toString());
496                 break;
497 
498             case (MessageLevels.LEVEL_WARNING):
499                 sink.warning(message.render().toString());
500                 break;
501 
502             case (MessageLevels.LEVEL_INFO):
503                 sink.info(message.render().toString());
504                 break;
505 
506             default:
507                 sink.debug(message.render().toString());
508         }
509     }
510 }