001 package org.apache.commons.digester3.plugins;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.util.Properties;
023
024 import org.apache.commons.digester3.Digester;
025 import org.apache.commons.digester3.Rule;
026 import org.xml.sax.Attributes;
027
028 /**
029 * A Digester rule which allows the user to pre-declare a class which is to be referenced later at a plugin point by a
030 * PluginCreateRule.
031 * <p>
032 * Normally, a PluginDeclarationRule is added to a Digester instance with the pattern "{root}/plugin" or "* /plugin"
033 * where {root} is the name of the root tag in the input document.
034 *
035 * @since 1.6
036 */
037 public class PluginDeclarationRule
038 extends Rule
039 {
040
041 // ------------------- constructors ---------------------------------------
042
043 /** constructor */
044 public PluginDeclarationRule()
045 {
046 super();
047 }
048
049 // ------------------- methods --------------------------------------------
050
051 /**
052 * Invoked upon reading a tag defining a plugin declaration. The tag must have the following mandatory attributes:
053 * <ul>
054 * <li>id</li>
055 * <li>class</li>
056 * </ul>
057 *
058 * @param namespace The xml namespace in which the xml element which triggered this rule resides.
059 * @param name The name of the xml element which triggered this rule.
060 * @param attributes The set of attributes on the xml element which triggered this rule.
061 * @exception Exception if any error occurs
062 */
063 @Override
064 public void begin( String namespace, String name, Attributes attributes )
065 throws Exception
066 {
067 int nAttrs = attributes.getLength();
068 Properties props = new Properties();
069 for ( int i = 0; i < nAttrs; ++i )
070 {
071 String key = attributes.getLocalName( i );
072 if ( ( key == null ) || ( key.length() == 0 ) )
073 {
074 key = attributes.getQName( i );
075 }
076 String value = attributes.getValue( i );
077 props.setProperty( key, value );
078 }
079
080 try
081 {
082 declarePlugin( getDigester(), props );
083 }
084 catch ( PluginInvalidInputException ex )
085 {
086 throw new PluginInvalidInputException( "Error on element [" + getDigester().getMatch() + "]: "
087 + ex.getMessage() );
088 }
089 }
090
091 /**
092 * Helper method to declare a plugin inside the given Digester.
093 *
094 * @param digester The Digester instance to declare plugin
095 * @param props the properties where extracting plugin attributes
096 * @throws PluginException if any error occurs while declaring the plugin
097 */
098 public static void declarePlugin( Digester digester, Properties props )
099 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 }