001 package net.sf.logdistiller;
002
003 /*
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 import java.io.*;
018 import java.util.*;
019
020 import org.apache.commons.lang.ArrayUtils;
021 import org.jdom.Element;
022
023 import net.sf.logdistiller.util.FormatUtil;
024
025 /**
026 * A LogDistiller configuration.
027 *
028 * @see LogDistillation
029 * @see net.sf.logdistiller.xml.DOMConfigurator
030 */
031 public class LogDistiller
032 implements Serializable
033 {
034 private static final long serialVersionUID = 1730313287821721822L;
035
036 private final String id;
037
038 private final String description;
039
040 private LogType logtype;
041
042 /** @since 0.7 */
043 private final Output output;
044
045 private final Category[] categories;
046
047 private final Group[] groups;
048
049 /** @since 0.7 */
050 private final List warnings = new ArrayList();
051
052 private final boolean old;
053
054 public LogDistiller( String id, String description, LogType logtype, Output output, Category[] categories,
055 Group[] groups, boolean old )
056 {
057 this.id = id;
058 this.description = description;
059 this.logtype = logtype;
060 this.output = output;
061 this.categories = (Category[]) ArrayUtils.clone( categories );
062 this.groups = (Group[]) ArrayUtils.clone( groups );
063 this.old = old;
064 updateRef();
065 }
066
067 public LogDistiller( String id, String description, LogType logtype, Output output, Category[] categories,
068 Group[] groups )
069 {
070 this( id, description, logtype, output, categories, groups, false );
071 }
072
073 /**
074 * Update the references from internal objects to their parent LogDistiller instance and other referenced object not
075 * initialized at creation time.
076 */
077 public void updateRef()
078 {
079 output.updateRef( this );
080 int len = categories.length;
081 for ( int i = 0; i < len; i++ )
082 {
083 categories[i].updateRef( this );
084 }
085 len = groups.length;
086 for ( int i = 0; i < len; i++ )
087 {
088 groups[i].updateRef( this );
089 }
090 }
091
092 private void readObject( ObjectInputStream in )
093 throws IOException, ClassNotFoundException
094 {
095 in.defaultReadObject();
096 if ( output != null )
097 {
098 // TODO: do better with deserialization of an old instance
099 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 }