org.apache.commons.digester.plugins

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Library » Apache commons digester 1.8 src » org.apache.commons.digester.plugins 
org.apache.commons.digester.plugins
An overview of the Digester Plugins module.

Provides an easy mechanism whereby new digestion rules can be added dynamically during a digestion.

Introduction.

Many applications have xml configuration files which are "extensible". Some examples of this are:
  • Apache log4j allows user-provided "Appender" classes to be specified in its configuration file
  • Apache Avalon allows "components" of a user-specified class
  • Apache Ant allows custom tasks to be defined
The Digester "plugins" module can be used to add this kind of functionality to your own applications.

An Example

Let's start off with an example.

Given the following digester rules in the main "parsing" application:

        Digester digester = new Digester();
        PluginRules rc = new PluginRules();
        digester.setRules(rc);
        
        digester.addObjectCreate("pipeline", Pipeline.class);
        
        digester.addCallMethod("pipeline/source", "setSource", 1);
        digester.addCallParam("pipeline/source", 0, "file");
        
        PluginCreateRule pcr = new PluginCreateRule(Transform.class);
        digester.addRule("pipeline/transform", pcr);
        digester.addSetNext("pipeline/transform", "setTransform");
        
        digester.addCallMethod("pipeline/destination", "setDest", 1);
        digester.addCallParam("pipeline/destination", 0, "file");

        digester.parse(filename);

the following input can be processed:

    <pipeline>
      <source file="input.txt"/>
      <transform plugin-class="SubstituteTransform">
        <from>changeme</from>
        <to>changed</to>
      </transform>
      <destination file="output.txt"/>
    </pipeline>

Note that the "SubstituteTransform" class is not hard-wired into the application, and also that this class is configuring itself from the same configuration file.

The user can specify any class they like here, and (provided that class follows the plugins conventions) it can use any Digester functionality to process the configuration data within the transform tag and its subtags.

The original application simply defined a "plugin point" of "pipeline/transform" at which user classes could be plugged in. However it did not specify what classes were permitted, other than that they must implement the Transform interface. It is the input file which has defined exactly which class should be instantiated when the transform element is encountered, and furthermore the "plugin" class itself has dynamically added rules for parsing elements nested within itself.

A class used as a plugin may dynamically add its own rules to the digester, in order to process its attributes and any subtags in any manner it wishes. This may be done by several mechanisms, including:

  • declaring a method public static void addRules(Digester d, String pattern) on the class being "plugged in", or
  • providing a separate "rule info" class, somewhat in the spirit of "BeanInfo" classes for java beans, or
  • providing an xmlrules file which defines the associated parsing rules.
If a plugin class has a no-parameter constructor, does not expect any subtags, and is satisfied with mapping any attributes on the parent xml tag to bean-property-setter methods on itself, then no rules need to be defined at all; the class can be used as a plugin without any coding.

In the example above, an end user may create their own classes which implement the required Transform interface, then cause these custom classes to be used instead of, or in addition to, classes distributed with the application.

Plugin Declarations

As well as the syntax shown above, where plugin classnames were defined as they were used, plugin classes can be pre-declared (provided the application associates a PluginDeclarationRule with a tag for that purpose). Example:

The plugin class can be declared once:

  <plugin id="widget" class="com.acme.Widget"/>
and later referenced via the short "id" value:
  <sometag plugin-id="widget" ... >

Suggested Applications

Any application where user-specific operations may need to be performed that cannot be known in advance by the initial application developer may benefit from this module. Applications in the style of the Apache projects listed at the top of this page (Log4j, Cocoon, Ant) are examples.

Note also that plugged-in classes can themselves allow user-defined classes to be plugged in within their configuration. This allows a very simple framework to be extended almost without limit by the end user.

Terminology

The term "plugin declaration" refers to an xml element which matches a PluginDeclarationRule, where the user specifies an id-to-class mapping.

The term "plugin point" refers to a pattern associated with a PluginCreateRule. An xml element matching that pattern is expected to have a plugin-id attribute (but see note on "default plugins" elsewhere in this document).

Limitations

The user cannot replace the name of the tag used as the plugin-point; <statement plugin-id="if"> cannot become <if>.

An instance of "PluginRules" must be used as the Rules implementation for the Digester (see example). However a PluginRules can use any other Rules implementation as its rule-matching engine, so this is not a significant issue. Plugged-in classes may only use the default RulesBase matching for the rules they add dynamically.

For technical reasons, a single instance of PluginCreateRule cannot currently be associated with multiple patterns; multiple instances are required. This is not expected to be a problem.

Performance

For patterns which do not involve "plugin points" there is minimal performance impact when adding rules to the Digester, and none when processing input data.

Processing elements which match patterns added dynamically by plugin classes does have a performance impact, but not excessively so.

Alternatives

The "xmlrules" digester module allows modification of parsing rules without code changes or recompilation. However this feature is aimed at the developer, not the end user of an application. The differences between xmlrules functionality and plugins functionality are:
  • With xmlrules, the full set of parsing rules for the whole configuration file is exposed. This is good for developers, but in most cases both too complex and too dangerous to require end users to edit directly.
  • Using xmlrules requires a fair level of knowledge of the Apache Digester. How an end user (not a plugin developer) can use plugins can be explained in about 3 paragraphs.

How to write plugin classes

In order to be useful, the problem domain needs to involve a base class or interface which can have multiple implementations. This section assumes that this is the case, that you have already created a concrete implementation of that base class or interface, and are wondering what changes need to be made to that class to make it suitable for a "plugin".

Well, if the class has a no-argument constuctor, and only simple configuration needs that can be met by a SetPropertiesRule, then no changes need to be made at all.

In other circumstances, you may either define an "addRules" method on the class which adds any necessary rules to the digester, a separate class containing that information, or write an xmlrules-format file defining the necessary rules. In the "separate rule info class" approach, the class containing the rule info may have any name of your choice, but the original class + "RuleInfo" is recommended.

Here is the addRules method on class SubstituteTransform, from the example:

    public static void addRules(Digester d, String pathPrefix) {
        d.addCallMethod(pathPrefix+"/from", "setFrom", 0);
        d.addCallMethod(pathPrefix+"/to", "setTo", 0);
    }
A "rule info" class consists of nothing but a static method defined as above.

If a plugin class does not define an "addRules" method, and the plugin declaration does not associate a rule info class with it, then the plugins module will define a "SetPropertiesRule" by default. However if any custom rules are defined for the plugin class, then that implementation is required to define a SetPropertiesRule for itself if it desires one.

Note that when adding any rules, the pattern passed to the digester must start with the pathPrefix provided. A plugin cannot define rules with absolute paths. And as defined in the limitations, the pattern should not include any wildcard characters.

Other features

Multiple plugin declarations are permitted; the latest simply overrides earlier ones.

In situations where a user might want to specify a custom class, but will often want "default" behaviour, a PluginCreateRule can specify a default class. If the user then omits the "plugin-id" attribute on the matching xml element, an instance of the default class will be created.

Java Source File NameTypeComment
Declaration.javaClass Represents a Class that can be instantiated by a PluginCreateRule, plus info on how to load custom digester rules for mapping xml into that plugged-in class.
InitializableRule.javaInterface Defines an interface that a Rule class can implement if it wishes to get an initialisation callback after the rule has been added to the set of Rules within a PluginRules instance.
LogUtils.javaClass Simple utility class to assist in logging.

This class is intended only for the use of the code in the plugins packages.

PluginAssertionFailure.javaClass Thrown when a bug is detected in the plugins code.

This class is intended to be used in assertion statements, similar to the way that java 1.4's native assertion mechanism is used.

PluginConfigurationException.javaClass Thrown when an error occurs due to the way the calling application uses the plugins module.
PluginContext.javaClass Provides data and services which should exist only once per digester.

This class holds a number of useful items which should be shared by all plugin objects.

PluginCreateRule.javaClass Allows the original rules for parsing the configuration file to define points at which plugins are allowed, by configuring a PluginCreateRule with the appropriate pattern.
PluginDeclarationRule.javaClass A Digester rule which allows the user to pre-declare a class which is to be referenced later at a plugin point by a PluginCreateRule.
PluginException.javaClass Thrown when some plugin-related error has occurred, and none of the other exception types are appropriate.
PluginInvalidInputException.javaClass Thrown when an error occurs due to bad data in the file being parsed.
PluginManager.javaClass Coordinates between PluginDeclarationRule and PluginCreateRule objects, providing a place to share data between instances of these rules.
PluginRules.javaClass A custom digester Rules manager which must be used as the Rules object when using the plugins module functionality.

During parsing, a linked list of PluginCreateRule instances develop, and this list also acts like a stack.

RuleFinder.javaClass Each concrete implementation of RuleFinder is an algorithm for locating a source of digester rules for a plugin.
RuleLoader.javaClass Interface for classes which can dynamically load custom plugin rules associated with a user's plugin class.

Each plugin declaration has an associated RuleLoader instance, and that instance's addRules method is invoked each time the input xml specifies that an instance of that plugged-in class is to be created.

This is an abstract class rather than an interface in order to make it possible to enhance this class in future without breaking binary compatibility; it is possible to add methods to an abstract class, but not to an interface.

RulesFactory.javaClass Whenever the scope of a plugin tag is entered, the PluginRules class creates a new Rules instance and configures it with the appropriate parsing rules for the plugged-in class.

Users of the plugins module can specify a subclass of this one to control the creation of that Rules object.

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.