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 }