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 }