View Javadoc
1   package org.apache.maven.shared.io.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 java.io.PrintWriter;
23  import java.io.StringWriter;
24  import java.util.ArrayList;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  /**
29   * Default Message Holder.
30   *
31   */
32  public class DefaultMessageHolder
33      implements MessageHolder
34  {
35  
36      private List<Message> messages = new ArrayList<Message>();
37  
38      private Message currentMessage;
39  
40      private int defaultMessageLevel = MessageLevels.LEVEL_INFO;
41  
42      private boolean[] messageLevelStates;
43  
44      private MessageSink onDemandSink;
45  
46      /**
47       * Create instance.
48       */
49      public DefaultMessageHolder()
50      {
51          this.messageLevelStates = MessageLevels.getLevelStates( MessageLevels.LEVEL_INFO );
52      }
53  
54      /**
55       * @param maxMessageLevel max message level.
56       * @param defaultMessageLevel default message level.
57       */
58      public DefaultMessageHolder( int maxMessageLevel, int defaultMessageLevel )
59      {
60          this.defaultMessageLevel = defaultMessageLevel;
61          this.messageLevelStates = MessageLevels.getLevelStates( maxMessageLevel );
62      }
63  
64      /**
65       * @param maxMessageLevel max message level.
66       * @param defaultMessageLevel default message level.
67       * @param onDemandSink {@link MessageSink}
68       */
69      public DefaultMessageHolder( int maxMessageLevel, int defaultMessageLevel, MessageSink onDemandSink )
70      {
71          this.defaultMessageLevel = defaultMessageLevel;
72          this.onDemandSink = onDemandSink;
73          this.messageLevelStates = MessageLevels.getLevelStates( maxMessageLevel );
74      }
75  
76      /** {@inheritDoc} */
77      public MessageHolder addMessage( CharSequence messagePart, Throwable error )
78      {
79          return addMessage( defaultMessageLevel, messagePart, error );
80      }
81  
82      /**
83       * @param level Level.
84       * @param messagePart Message part.
85       * @param error {@link Throwable}
86       * @return {@link MessageHolder}
87       */
88      protected MessageHolder addMessage( int level, CharSequence messagePart, Throwable error )
89      {
90          newMessage( level );
91          append( messagePart.toString() );
92          append( error );
93  
94          return this;
95      }
96  
97      /** {@inheritDoc} */
98      public MessageHolder addMessage( CharSequence messagePart )
99      {
100         return addMessage( defaultMessageLevel, messagePart );
101     }
102 
103     /**
104      * @param level level.
105      * @param messagePart message part.
106      * @return {@link MessageHolder}
107      */
108     protected MessageHolder addMessage( int level, CharSequence messagePart )
109     {
110         newMessage( level );
111         append( messagePart.toString() );
112 
113         return this;
114     }
115 
116     /** {@inheritDoc} */
117     public MessageHolder addMessage( Throwable error )
118     {
119         return addMessage( defaultMessageLevel, error );
120     }
121 
122     /**
123      * @param level level.
124      * @param error {@link Throwable}
125      * @return {@link MessageHolder}
126      */
127     protected MessageHolder addMessage( int level, Throwable error )
128     {
129         newMessage( level );
130         append( error );
131 
132         return this;
133     }
134 
135     /** {@inheritDoc} */
136     public MessageHolder append( CharSequence messagePart )
137     {
138         if ( currentMessage == null )
139         {
140             newMessage();
141         }
142 
143         currentMessage.append( messagePart.toString() );
144 
145         return this;
146     }
147 
148     /** {@inheritDoc} */
149     public MessageHolder append( Throwable error )
150     {
151         if ( currentMessage == null )
152         {
153             newMessage();
154         }
155 
156         currentMessage.setError( error );
157 
158         return this;
159     }
160 
161     /** {@inheritDoc} */
162     public boolean isEmpty()
163     {
164         return messages.isEmpty();
165     }
166 
167     /** {@inheritDoc} */
168     public MessageHolder newMessage()
169     {
170         newMessage( defaultMessageLevel );
171 
172         return this;
173     }
174 
175     /**
176      * @param messageLevel message level.
177      */
178     protected void newMessage( int messageLevel )
179     {
180         if ( onDemandSink != null && currentMessage != null )
181         {
182             renderTo( currentMessage, onDemandSink );
183         }
184 
185         currentMessage = new Message( messageLevel, onDemandSink );
186         messages.add( currentMessage );
187     }
188 
189     /** {@inheritDoc} */
190     public String render()
191     {
192         StringBuffer buffer = new StringBuffer();
193 
194         int counter = 1;
195         for ( Iterator<Message> it = messages.iterator(); it.hasNext(); )
196         {
197             Message message = (Message) it.next();
198 
199             int ml = message.getMessageLevel();
200 
201             if ( ml >= messageLevelStates.length || ml < 0 )
202             {
203                 ml = MessageLevels.LEVEL_DEBUG;
204             }
205 
206             if ( !messageLevelStates[ml] )
207             {
208                 continue;
209             }
210 
211             CharSequence content = message.render();
212             String label = MessageLevels.getLevelLabel( message.getMessageLevel() );
213 
214             if ( content.length() > label.length() + 3 )
215             {
216                 buffer.append( '[' ).append( counter++ ).append( "] " );
217                 buffer.append( content.toString() );
218 
219                 if ( it.hasNext() )
220                 {
221                     buffer.append( "\n\n" );
222                 }
223             }
224         }
225 
226         return buffer.toString();
227     }
228 
229     /** {@inheritDoc} */
230     public int size()
231     {
232         return messages.size();
233     }
234 
235     private static final class Message
236     {
237         private StringBuffer message = new StringBuffer();
238 
239         private Throwable error;
240 
241         private final int messageLevel;
242 
243         private final MessageSink onDemandSink;
244 
245         public Message( int messageLevel, MessageSink onDemandSink )
246         {
247             this.messageLevel = messageLevel;
248 
249             this.onDemandSink = onDemandSink;
250         }
251 
252         public Message setError( Throwable pError )
253         {
254             this.error = pError;
255             return this;
256         }
257 
258         public Message append( CharSequence pMessage )
259         {
260             this.message.append( pMessage.toString() );
261             return this;
262         }
263 
264         /**
265          * @return message level.
266          */
267         public int getMessageLevel()
268         {
269             return messageLevel;
270         }
271 
272         /**
273          * @return Sequence.
274          */
275         public CharSequence render()
276         {
277             StringBuffer buffer = new StringBuffer();
278 
279             if ( onDemandSink == null )
280             {
281                 buffer.append( '[' ).append( MessageLevels.getLevelLabel( messageLevel ) ).append( "] " );
282             }
283             if ( message != null && message.length() > 0 )
284             {
285                 buffer.append( message );
286 
287                 if ( error != null )
288                 {
289                     buffer.append( '\n' );
290                 }
291             }
292 
293             if ( error != null )
294             {
295                 buffer.append( "Error:\n" );
296 
297                 StringWriter sw = new StringWriter();
298                 PrintWriter pw = new PrintWriter( sw );
299                 error.printStackTrace( pw );
300 
301                 buffer.append( sw.toString() );
302             }
303 
304             return buffer;
305         }
306     }
307 
308     /** {@inheritDoc} */
309     public MessageHolder addDebugMessage( CharSequence messagePart, Throwable error )
310     {
311         return addMessage( MessageLevels.LEVEL_DEBUG, messagePart, error );
312     }
313 
314     /** {@inheritDoc} */
315     public MessageHolder addDebugMessage( CharSequence messagePart )
316     {
317         return addMessage( MessageLevels.LEVEL_DEBUG, messagePart );
318     }
319 
320     /** {@inheritDoc} */
321     public MessageHolder addDebugMessage( Throwable error )
322     {
323         return addMessage( MessageLevels.LEVEL_DEBUG, error );
324     }
325 
326     /** {@inheritDoc} */
327     public MessageHolder addErrorMessage( CharSequence messagePart, Throwable error )
328     {
329         return addMessage( MessageLevels.LEVEL_ERROR, messagePart, error );
330     }
331 
332     /** {@inheritDoc} */
333     public MessageHolder addErrorMessage( CharSequence messagePart )
334     {
335         return addMessage( MessageLevels.LEVEL_ERROR, messagePart );
336     }
337 
338     /** {@inheritDoc} */
339     public MessageHolder addErrorMessage( Throwable error )
340     {
341         return addMessage( MessageLevels.LEVEL_ERROR, error );
342     }
343 
344     /** {@inheritDoc} */
345     public MessageHolder addInfoMessage( CharSequence messagePart, Throwable error )
346     {
347         return addMessage( MessageLevels.LEVEL_INFO, messagePart, error );
348     }
349 
350     /** {@inheritDoc} */
351     public MessageHolder addInfoMessage( CharSequence messagePart )
352     {
353         return addMessage( MessageLevels.LEVEL_INFO, messagePart );
354     }
355 
356     /** {@inheritDoc} */
357     public MessageHolder addInfoMessage( Throwable error )
358     {
359         return addMessage( MessageLevels.LEVEL_INFO, error );
360     }
361 
362     /** {@inheritDoc} */
363     public MessageHolder addSevereMessage( CharSequence messagePart, Throwable error )
364     {
365         return addMessage( MessageLevels.LEVEL_SEVERE, messagePart, error );
366     }
367 
368     /** {@inheritDoc} */
369     public MessageHolder addSevereMessage( CharSequence messagePart )
370     {
371         return addMessage( MessageLevels.LEVEL_SEVERE, messagePart );
372     }
373 
374     /** {@inheritDoc} */
375     public MessageHolder addSevereMessage( Throwable error )
376     {
377         return addMessage( MessageLevels.LEVEL_SEVERE, error );
378     }
379 
380     /** {@inheritDoc} */
381     public MessageHolder addWarningMessage( CharSequence messagePart, Throwable error )
382     {
383         return addMessage( MessageLevels.LEVEL_WARNING, messagePart, error );
384     }
385 
386     /** {@inheritDoc} */
387     public MessageHolder addWarningMessage( CharSequence messagePart )
388     {
389         return addMessage( MessageLevels.LEVEL_WARNING, messagePart );
390     }
391 
392     /** {@inheritDoc} */
393     public MessageHolder addWarningMessage( Throwable error )
394     {
395         return addMessage( MessageLevels.LEVEL_WARNING, error );
396     }
397 
398     /** {@inheritDoc} */
399     public int countDebugMessages()
400     {
401         return countMessagesOfType( MessageLevels.LEVEL_DEBUG );
402     }
403 
404     /** {@inheritDoc} */
405     public int countErrorMessages()
406     {
407         return countMessagesOfType( MessageLevels.LEVEL_ERROR );
408     }
409 
410     /** {@inheritDoc} */
411     public int countInfoMessages()
412     {
413         return countMessagesOfType( MessageLevels.LEVEL_INFO );
414     }
415 
416     /** {@inheritDoc} */
417     public int countMessages()
418     {
419         return size();
420     }
421 
422     /** {@inheritDoc} */
423     public int countSevereMessages()
424     {
425         return countMessagesOfType( MessageLevels.LEVEL_SEVERE );
426     }
427 
428     /** {@inheritDoc} */
429     public int countWarningMessages()
430     {
431         return countMessagesOfType( MessageLevels.LEVEL_WARNING );
432     }
433 
434     /**
435      * @param messageLevel leve.
436      * @return number of messages.
437      */
438     private int countMessagesOfType( int messageLevel )
439     {
440         int count = 0;
441 
442         for ( Message message : messages )
443         {
444             if ( messageLevel == message.getMessageLevel() )
445             {
446                 count++;
447             }
448         }
449 
450         return count;
451     }
452 
453     /** {@inheritDoc} */
454     public boolean isDebugEnabled()
455     {
456         return messageLevelStates[MessageLevels.LEVEL_DEBUG];
457     }
458 
459     /** {@inheritDoc} */
460     public boolean isErrorEnabled()
461     {
462         return messageLevelStates[MessageLevels.LEVEL_ERROR];
463     }
464 
465     /** {@inheritDoc} */
466     public boolean isInfoEnabled()
467     {
468         return messageLevelStates[MessageLevels.LEVEL_INFO];
469     }
470 
471     /** {@inheritDoc} */
472     public boolean isSevereEnabled()
473     {
474         return messageLevelStates[MessageLevels.LEVEL_SEVERE];
475     }
476 
477     /** {@inheritDoc} */
478     public boolean isWarningEnabled()
479     {
480         return messageLevelStates[MessageLevels.LEVEL_WARNING];
481     }
482 
483     /** {@inheritDoc} */
484     public MessageHolder newDebugMessage()
485     {
486         if ( isDebugEnabled() )
487         {
488             newMessage( MessageLevels.LEVEL_DEBUG );
489         }
490 
491         return this;
492     }
493 
494     /** {@inheritDoc} */
495     public MessageHolder newErrorMessage()
496     {
497         if ( isErrorEnabled() )
498         {
499             newMessage( MessageLevels.LEVEL_ERROR );
500         }
501 
502         return this;
503     }
504 
505     /** {@inheritDoc} */
506     public MessageHolder newInfoMessage()
507     {
508         if ( isInfoEnabled() )
509         {
510             newMessage( MessageLevels.LEVEL_INFO );
511         }
512 
513         return this;
514     }
515 
516     /** {@inheritDoc} */
517     public MessageHolder newSevereMessage()
518     {
519         if ( isSevereEnabled() )
520         {
521             newMessage( MessageLevels.LEVEL_SEVERE );
522         }
523 
524         return this;
525     }
526 
527     /** {@inheritDoc} */
528     public MessageHolder newWarningMessage()
529     {
530         if ( isWarningEnabled() )
531         {
532             newMessage( MessageLevels.LEVEL_WARNING );
533         }
534 
535         return this;
536     }
537 
538     /** {@inheritDoc} */
539     public void setDebugEnabled( boolean enabled )
540     {
541         messageLevelStates[MessageLevels.LEVEL_DEBUG] = enabled;
542     }
543 
544     /** {@inheritDoc} */
545     public void setErrorEnabled( boolean enabled )
546     {
547         messageLevelStates[MessageLevels.LEVEL_ERROR] = enabled;
548     }
549 
550     /** {@inheritDoc} */
551     public void setInfoEnabled( boolean enabled )
552     {
553         messageLevelStates[MessageLevels.LEVEL_INFO] = enabled;
554     }
555 
556     /** {@inheritDoc} */
557     public void setSevereEnabled( boolean enabled )
558     {
559         messageLevelStates[MessageLevels.LEVEL_SEVERE] = enabled;
560     }
561 
562     /** {@inheritDoc} */
563     public void setWarningEnabled( boolean enabled )
564     {
565         messageLevelStates[MessageLevels.LEVEL_WARNING] = enabled;
566     }
567 
568     /** {@inheritDoc} */
569     public void flush()
570     {
571         if ( onDemandSink != null && currentMessage != null )
572         {
573             renderTo( currentMessage, onDemandSink );
574             currentMessage = null;
575         }
576     }
577 
578     /** {@inheritDoc} */
579     public void render( MessageSink sink )
580     {
581         for ( Message message : messages )
582         {
583             renderTo( message, sink );
584         }
585     }
586 
587     /**
588      * @param message {@link Message}
589      * @param sink {@link MessageSink}
590      */
591     protected void renderTo( Message message, MessageSink sink )
592     {
593         switch ( message.getMessageLevel() )
594         {
595             case ( MessageLevels.LEVEL_SEVERE ):
596                 sink.severe( message.render().toString() );
597                 break;
598 
599             case ( MessageLevels.LEVEL_ERROR ):
600                 sink.error( message.render().toString() );
601                 break;
602 
603             case ( MessageLevels.LEVEL_WARNING ):
604                 sink.warning( message.render().toString() );
605                 break;
606 
607             case ( MessageLevels.LEVEL_INFO ):
608                 sink.info( message.render().toString() );
609                 break;
610 
611             default:
612                 sink.debug( message.render().toString() );
613         }
614     }
615 
616 }