View Javadoc

1   package org.apache.commons.digester3.plugins;
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.util.Properties;
23  
24  import org.apache.commons.digester3.Digester;
25  import org.apache.commons.digester3.Rule;
26  import org.xml.sax.Attributes;
27  
28  /**
29   * A Digester rule which allows the user to pre-declare a class which is to be referenced later at a plugin point by a
30   * PluginCreateRule.
31   * <p>
32   * Normally, a PluginDeclarationRule is added to a Digester instance with the pattern "{root}/plugin" or "* /plugin"
33   * where {root} is the name of the root tag in the input document.
34   * 
35   * @since 1.6
36   */
37  public class PluginDeclarationRule
38      extends Rule
39  {
40  
41      // ------------------- constructors ---------------------------------------
42  
43      /** constructor */
44      public PluginDeclarationRule()
45      {
46          super();
47      }
48  
49      // ------------------- methods --------------------------------------------
50  
51      /**
52       * Invoked upon reading a tag defining a plugin declaration. The tag must have the following mandatory attributes:
53       * <ul>
54       * <li>id</li>
55       * <li>class</li>
56       * </ul>
57       * 
58       * @param namespace The xml namespace in which the xml element which triggered this rule resides.
59       * @param name The name of the xml element which triggered this rule.
60       * @param attributes The set of attributes on the xml element which triggered this rule.
61       * @exception Exception if any error occurs
62       */
63      @Override
64      public void begin( String namespace, String name, Attributes attributes )
65          throws Exception
66      {
67          int nAttrs = attributes.getLength();
68          Properties props = new Properties();
69          for ( int i = 0; i < nAttrs; ++i )
70          {
71              String key = attributes.getLocalName( i );
72              if ( ( key == null ) || ( key.length() == 0 ) )
73              {
74                  key = attributes.getQName( i );
75              }
76              String value = attributes.getValue( i );
77              props.setProperty( key, value );
78          }
79  
80          try
81          {
82              declarePlugin( getDigester(), props );
83          }
84          catch ( PluginInvalidInputException ex )
85          {
86              throw new PluginInvalidInputException( "Error on element [" + getDigester().getMatch() + "]: "
87                  + ex.getMessage() );
88          }
89      }
90  
91      /**
92       * Helper method to declare a plugin inside the given Digester.
93       *
94       * @param digester The Digester instance to declare plugin
95       * @param props the properties where extracting plugin attributes
96       * @throws PluginException if any error occurs while declaring the plugin
97       */
98      public static void declarePlugin( Digester digester, Properties props )
99          throws PluginException
100     {
101         String id = props.getProperty( "id" );
102         String pluginClassName = props.getProperty( "class" );
103 
104         if ( id == null )
105         {
106             throw new PluginInvalidInputException( "mandatory attribute id not present on plugin declaration" );
107         }
108 
109         if ( pluginClassName == null )
110         {
111             throw new PluginInvalidInputException( "mandatory attribute class not present on plugin declaration" );
112         }
113 
114         Declaration newDecl = new Declaration( pluginClassName );
115         newDecl.setId( id );
116         newDecl.setProperties( props );
117 
118         PluginRules rc = (PluginRules) digester.getRules();
119         PluginManager pm = rc.getPluginManager();
120 
121         newDecl.init( digester, pm );
122         pm.addDeclaration( newDecl );
123 
124         // Note that it is perfectly safe to redeclare a plugin, because
125         // the declaration doesn't add any rules to digester; all it does
126         // is create a RuleLoader instance whch is *capable* of adding the
127         // rules to the digester.
128     }
129 
130 }