View Javadoc

1   package net.sf.logdistiller;
2   
3   /*
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  import java.io.*;
18  import java.util.*;
19  
20  import org.apache.commons.lang.ArrayUtils;
21  import org.jdom.Element;
22  
23  import net.sf.logdistiller.util.FormatUtil;
24  
25  /**
26   * A LogDistiller configuration.
27   *
28   * @see LogDistillation
29   * @see net.sf.logdistiller.xml.DOMConfigurator
30   */
31  public class LogDistiller
32      implements Serializable
33  {
34      private static final long serialVersionUID = 1730313287821721822L;
35  
36      private final String id;
37  
38      private final String description;
39  
40      private LogType logtype;
41  
42      /** @since 0.7 */
43      private final Output output;
44  
45      private final Category[] categories;
46  
47      private final Group[] groups;
48  
49      /** @since 0.7 */
50      private final List warnings = new ArrayList();
51  
52      private final boolean old;
53  
54      public LogDistiller( String id, String description, LogType logtype, Output output, Category[] categories,
55                           Group[] groups, boolean old )
56      {
57          this.id = id;
58          this.description = description;
59          this.logtype = logtype;
60          this.output = output;
61          this.categories = (Category[]) ArrayUtils.clone( categories );
62          this.groups = (Group[]) ArrayUtils.clone( groups );
63          this.old = old;
64          updateRef();
65      }
66  
67      public LogDistiller( String id, String description, LogType logtype, Output output, Category[] categories,
68                           Group[] groups )
69      {
70          this( id, description, logtype, output, categories, groups, false );
71      }
72  
73      /**
74       * Update the references from internal objects to their parent LogDistiller instance and other referenced object not
75       * initialized at creation time.
76       */
77      public void updateRef()
78      {
79          output.updateRef( this );
80          int len = categories.length;
81          for ( int i = 0; i < len; i++ )
82          {
83              categories[i].updateRef( this );
84          }
85          len = groups.length;
86          for ( int i = 0; i < len; i++ )
87          {
88              groups[i].updateRef( this );
89          }
90      }
91  
92      private void readObject( ObjectInputStream in )
93          throws IOException, ClassNotFoundException
94      {
95          in.defaultReadObject();
96          if ( output != null )
97          {
98              // TODO: do better with deserialization of an old instance
99              updateRef();
100         }
101     }
102 
103     public String getId()
104     {
105         return id;
106     }
107 
108     public String getDescription()
109     {
110         return description;
111     }
112 
113     public LogType getLogType()
114     {
115         return logtype;
116     }
117 
118     /**
119      * is this LogDistiller read from an old configuration file (DTD older than 1.3)?
120      */
121     public boolean isOld()
122     {
123         return old;
124     }
125 
126     /**
127      * To keep old rules configuration files running (without logtype element), create a LogType instance from the type
128      * provided. Parameters from the logtype are extracted from global parameters: every <code>logevent.myParam</code>
129      * global parameter is inserted as <code>myParam</code>.
130      *
131      * @param type String the log type to consider
132      */
133     public void buildCompatibilityLogType( String type )
134     {
135         Map logtypeParams = new HashMap();
136         Map params = output.getParams();
137         Iterator iter = params.entrySet().iterator();
138         while ( iter.hasNext() )
139         {
140             Map.Entry entry = (Map.Entry) iter.next();
141             String key = (String) entry.getKey();
142             if ( key.startsWith( "logevent." ) )
143             {
144                 logtypeParams.put( key.substring( 9 ), entry.getValue() );
145             }
146         }
147         String paramAttributes = (String)logtypeParams.get( "attributes" );
148         logtype = new LogDistiller.LogType( type, logtypeParams, new Attributes( paramAttributes, new Attributes.Extension[0] ) );
149     }
150 
151     public Output getOutput()
152     {
153         return output;
154     }
155 
156     public Category[] getCategories()
157     {
158         return (Category[]) ArrayUtils.clone( categories );
159     }
160 
161     public Group[] getGroups()
162     {
163         return (Group[]) ArrayUtils.clone( groups );
164     }
165 
166     public List getWarnings()
167     {
168         return Collections.unmodifiableList( warnings );
169     }
170 
171     public void addWarning( String msg )
172     {
173         warnings.add( msg );
174     }
175 
176     public void checkLogtypeAttributes( net.sf.logdistiller.LogType.Description description )
177     {
178         String attributes = ( logtype.getAttributes() == null ) ? null : logtype.getAttributes().getAttributes();
179         String attributesReference = FormatUtil.join( ",", description.getAttributeNames() );
180 
181         if ( attributes == null )
182         {
183             addWarning( "<logtype><attributes> element should contain <provided>" + attributesReference
184                 + "</provided>" );
185         }
186         else if ( !attributesReference.equals( attributes ) )
187         {
188             addWarning( "bad value for <logtype><attributes><provided> element, should be " + attributesReference );
189         }
190     }
191 
192     public static String getVersion()
193     {
194         Package pkg = LogDistiller.class.getPackage();
195         String version = ( pkg == null ) ? null : pkg.getSpecificationVersion();
196         return ( version == null ) ? "SNAPSHOT" : version;
197     }
198 
199     /**
200      * Definition of the log type used for this logdistiller configuration, with its parameters.
201      */
202     public static class LogType
203         implements Serializable
204     {
205         private static final long serialVersionUID = 1486393526172179950L;
206 
207         private final String id;
208 
209         private final Map params;
210 
211         /**
212          * @since 1.1
213          */
214         private final Attributes attributes;
215 
216         public LogType( String id, Map params, Attributes attributes )
217         {
218             this.id = id;
219             this.params = params;
220             this.attributes = attributes;
221         }
222 
223         public String getId()
224         {
225             return id;
226         }
227 
228         public Map getParams()
229         {
230             return params;
231         }
232 
233         public String getParam( String name )
234         {
235             return (String) params.get( name );
236         }
237 
238         public String getParam( String name, String defaultValue )
239         {
240             String value = getParam( name );
241             return ( value == null ) ? defaultValue : value;
242         }
243 
244         /**
245          * @return extensions (not <code>null</code>)
246          *  @since 1.1
247          */
248         public Attributes.Extension[] getExtensions()
249         {
250             return ( attributes == null ) ? Attributes.NO_EXTENSIONS : attributes.getExtensions();
251         }
252 
253         /** @since 1.1 */
254         public int getExtensionsCount()
255         {
256             return ( attributes == null ) ? 0 : attributes.getExtensionsCount();
257         }
258 
259         /** @since 1.1 */
260         public Attributes getAttributes()
261         {
262             return attributes;
263         }
264     }
265 
266     /**
267      * Definition of the global output.
268      *
269      * @since 0.7
270      */
271     public static class Output
272         implements Serializable
273     {
274         private static final long serialVersionUID = 1707510377356801400L;
275 
276         private String directory;
277 
278         private String content;
279 
280         private final String url;
281 
282         private String skip;
283 
284         private final Map params;
285 
286         private final Report[] reports;
287 
288         private transient LogDistiller logdistiller;
289 
290         public Output( String directory, String url, String content, String skip, Map params, Report[] reports )
291         {
292             this.directory = directory;
293             this.url = url;
294             this.content = content;
295             this.skip = skip;
296             this.params = params;
297             this.reports = (Report[]) ArrayUtils.clone( reports );
298         }
299 
300         public LogDistiller getLogdistiller()
301         {
302             return logdistiller;
303         }
304 
305         private void updateRef( LogDistiller logdistiller )
306         {
307             this.logdistiller = logdistiller;
308             int len = reports.length;
309             for ( int i = 0; i < len; i++ )
310             {
311                 reports[i].updateRef( this );
312             }
313         }
314 
315         /**
316          * Gets the <code>id</code> that will identify the output reports.
317          *
318          * @return the <code>id</code> param if set, or global logdistiller id.
319          */
320         public String getId()
321         {
322             return getParam( "id", logdistiller.getId() );
323         }
324 
325         public Map getParams()
326         {
327             return params;
328         }
329 
330         public String getParam( String name )
331         {
332             return (String) params.get( name );
333         }
334 
335         public String getParam( String name, String defaultValue )
336         {
337             String value = getParam( name );
338             return ( value == null ) ? defaultValue : value;
339         }
340 
341         public Report[] getReports()
342         {
343             return (Report[]) ArrayUtils.clone( reports );
344         }
345 
346         public void setDirectory( String directory )
347         {
348             this.directory = directory;
349         }
350 
351         public String getDirectory()
352         {
353             return directory;
354         }
355 
356         public void setContent( String content )
357         {
358             this.content = content;
359         }
360 
361         public String getContent()
362         {
363             return content;
364         }
365 
366         public String getSkip()
367         {
368             return skip;
369         }
370 
371         public void updateCompatibility( File directory, String content, String skip )
372         {
373             this.directory = directory.getAbsolutePath();
374             this.content = content;
375             this.skip = skip;
376         }
377 
378         public String getUrl()
379         {
380             return url;
381         }
382 
383         public String getUrl( String file )
384         {
385             return ( url == null ) ? null : ( url + '/' + file );
386         }
387     }
388 
389     /**
390      * Definition of a report, with its publisher, formant and other params.
391      */
392     public static class Report
393         implements Serializable
394     {
395         private static final long serialVersionUID = 1669156992489095268L;
396 
397         private final String publisher;
398 
399         private final String format;
400 
401         private final Map params;
402 
403         private transient Output output;
404 
405         private transient Group group;
406 
407         public Report( String publisher, String format, Map params )
408         {
409             this.publisher = publisher;
410             this.format = format;
411             this.params = params;
412         }
413 
414         private void updateRef( Output output )
415         {
416             this.output = output;
417             this.group = null;
418         }
419 
420         private void updateRef( Group group )
421         {
422             this.group = group;
423             this.output = group.getLogdistiller().getOutput();
424         }
425 
426         public Output getOutput()
427         {
428             return output;
429         }
430 
431         public Group getGroup()
432         {
433             return group;
434         }
435 
436         public Map getParams()
437         {
438             return params;
439         }
440 
441         public String getFormat()
442         {
443             return format;
444         }
445 
446         public String getParam( String name )
447         {
448             return (String) params.get( name );
449         }
450 
451         public String getParam( String name, String defaultValue )
452         {
453             String value = getParam( name );
454             return ( value != null ) ? value : output.getParam( publisher + '.' + name, defaultValue );
455         }
456 
457         public String getPublisher()
458         {
459             return publisher;
460         }
461     }
462 
463     /**
464      * Definition of a group of events: events corresponding to its conditions will be collected in it.
465      */
466     public static class Group
467         implements Serializable
468     {
469         private static final long serialVersionUID = 6647633346412959286L;
470 
471         private final String id;
472 
473         private final String description;
474 
475         private final boolean continueProcessing;
476 
477         private final boolean save;
478 
479         private final Map params;
480 
481         private final Condition[] conditions;
482 
483         private final Report[] reports;
484 
485         private final Category category;
486 
487         private final Plugin[] plugins;
488 
489         private transient LogDistiller logdistiller;
490 
491         public Group( String id, String description, boolean continueProcessing, boolean save, Map params,
492                       Condition[] conditions, Report[] reports, Plugin[] plugins, Category category )
493         {
494             this.id = id;
495             this.description = description;
496             this.continueProcessing = continueProcessing;
497             this.save = save;
498             this.params = params;
499             this.conditions = (Condition[]) ArrayUtils.clone( conditions );
500             this.reports = (Report[]) ArrayUtils.clone( reports );
501             this.plugins = (Plugin[]) ArrayUtils.clone( plugins );
502             this.category = category;
503         }
504 
505         private void updateRef( LogDistiller logdistiller )
506         {
507             this.logdistiller = logdistiller;
508             if ( id == null )
509             {
510                 // for unknown reason, deserialization of a LogDistillation instance does not fully deserialize
511                 // LogDistiller's
512                 // instance
513                 return;
514             }
515             if ( category != null )
516             {
517                 this.category.addGroup( this );
518             }
519             int len = reports.length;
520             for ( int i = 0; i < len; i++ )
521             {
522                 reports[i].updateRef( this );
523             }
524             len = plugins.length;
525             for ( int i = 0; i < len; i++ )
526             {
527                 plugins[i].updateRef( this );
528             }
529         }
530 
531         public LogDistiller getLogdistiller()
532         {
533             return logdistiller;
534         }
535 
536         public Map getParams()
537         {
538             return params;
539         }
540 
541         public String getParam( String name )
542         {
543             return (String) params.get( name );
544         }
545 
546         public String getParam( String name, String defaultValue )
547         {
548             String value = getParam( name );
549             return ( value != null ) ? value : logdistiller.getOutput().getParam( name, defaultValue );
550         }
551 
552         /**
553          * Check if given LogEvent meet one of the conditions defined.
554          *
555          * @param le LogEvent the LogEvent to check
556          * @return Condition the condition which matched the log event, or <code>null</code>
557          */
558         public Condition accept( LogEvent le )
559         {
560             int count = conditions.length;
561             if ( count == 0 )
562             {
563                 // no condition => accepts all log events
564                 return Condition.ACCEPT_ALL;
565             }
566             for ( int i = 0; i < count; i++ )
567             {
568                 if ( conditions[i].match( le ) )
569                 {
570                     return conditions[i];
571                 }
572             }
573             return null;
574         }
575 
576         public String getId()
577         {
578             return id;
579         }
580 
581         public Element dumpConditions( Element parent )
582         {
583             int count = conditions.length;
584             for ( int i = 0; i < count; i++ )
585             {
586                 parent.addContent( conditions[i].dump() );
587             }
588             return parent;
589         }
590 
591         public String getDescription()
592         {
593             return description;
594         }
595 
596         /**
597          * @return boolean in case a LogEvent is added to the current group, must classification be continued further to
598          *         match other groups?
599          */
600         public boolean continueProcessing()
601         {
602             return continueProcessing;
603         }
604 
605         public boolean getSave()
606         {
607             return save;
608         }
609 
610         public Category getCategory()
611         {
612             return category;
613         }
614 
615         public Report[] getReports()
616         {
617             return (Report[]) ArrayUtils.clone( reports );
618         }
619 
620         public Plugin[] getPlugins()
621         {
622             return (Plugin[]) ArrayUtils.clone( plugins );
623         }
624     }
625 
626     /**
627      * Definition of a category, which will contain groups.
628      */
629     public static class Category
630         implements Serializable
631     {
632         private static final long serialVersionUID = 3036838205912907804L;
633 
634         private final String id;
635 
636         private final String description;
637 
638         private transient LogDistiller logdistiller;
639 
640         private transient List groups;
641 
642         public Category( String id, String description )
643         {
644             this.id = id;
645             this.description = description;
646         }
647 
648         private void updateRef( LogDistiller logdistiller )
649         {
650             this.logdistiller = logdistiller;
651             this.groups = new ArrayList();
652         }
653 
654         private void addGroup( Group group )
655         {
656             this.groups.add( group );
657         }
658 
659         public LogDistiller getLogdistiller()
660         {
661             return logdistiller;
662         }
663 
664         public String getId()
665         {
666             return id;
667         }
668 
669         public String getDescription()
670         {
671             return description;
672         }
673 
674         public List getGroups()
675         {
676             return groups;
677         }
678     }
679 
680     public static class Plugin
681         implements Serializable
682     {
683         private static final long serialVersionUID = 7948111042518186219L;
684 
685         private final String type;
686 
687         private final Map params;
688 
689         private final boolean globalReport;
690 
691         private final boolean groupReport;
692 
693         private transient Group group;
694 
695         public Plugin( String type, boolean globalReport, boolean groupReport, Map params )
696         {
697             this.type = type;
698             this.params = params;
699             this.globalReport = globalReport;
700             this.groupReport = groupReport;
701         }
702 
703         private void updateRef( Group group )
704         {
705             this.group = group;
706         }
707 
708         public Group getGroup()
709         {
710             return group;
711         }
712 
713         public String getType()
714         {
715             return type;
716         }
717 
718         public boolean isGlobalReportEnabled()
719         {
720             return globalReport;
721         }
722 
723         public boolean isGroupReportEnabled()
724         {
725             return groupReport;
726         }
727 
728         public Map getParams()
729         {
730             return params;
731         }
732 
733         public String getParam( String name )
734         {
735             return (String) params.get( name );
736         }
737 
738         public String getParam( String name, String defaultValue )
739         {
740             String value = getParam( name );
741             return ( value == null ) ? defaultValue : value;
742         }
743     }
744 }