001    /* $Id: PluginDeclarationRule.java 992060 2010-09-02 19:09:47Z simonetripodi $
002     *
003     * Licensed to the Apache Software Foundation (ASF) under one or more
004     * contributor license agreements.  See the NOTICE file distributed with
005     * this work for additional information regarding copyright ownership.
006     * The ASF licenses this file to You under the Apache License, Version 2.0
007     * (the "License"); you may not use this file except in compliance with
008     * the License.  You may obtain a copy of the License at
009     *
010     *      http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package org.apache.commons.digester.plugins;
020    
021    import java.util.Properties;
022    
023    import org.apache.commons.digester.Digester;
024    import org.apache.commons.digester.Rule;
025    
026    /**
027     * A Digester rule which allows the user to pre-declare a class which is to
028     * be referenced later at a plugin point by a PluginCreateRule.
029     * <p>
030     * Normally, a PluginDeclarationRule is added to a Digester instance with
031     * the pattern "{root}/plugin" or "* /plugin" where {root} is the name of 
032     * the root tag in the input document.
033     *
034     * @since 1.6
035     */
036    
037    public class PluginDeclarationRule extends Rule {
038    
039        //------------------- constructors ---------------------------------------
040    
041        /** constructor  */
042        public PluginDeclarationRule() {
043            super();
044        }
045    
046        //------------------- methods --------------------------------------------
047    
048        /**
049         * Invoked upon reading a tag defining a plugin declaration. The tag
050         * must have the following mandatory attributes:
051         * <ul>
052         *   <li> id </li>
053         *   <li> class </li>
054         * </ul>
055         *
056         *@param namespace The xml namespace in which the xml element which
057         * triggered this rule resides.
058         *@param name The name of the xml element which triggered this rule.
059         *@param attributes The set of attributes on the xml element which
060         * triggered this rule.
061         *@exception java.lang.Exception
062         */
063    
064        @Override
065        public void begin(String namespace, String name,
066                          org.xml.sax.Attributes attributes)
067                          throws java.lang.Exception {
068                     
069            int nAttrs = attributes.getLength();
070            Properties props = new Properties();
071            for(int i=0; i<nAttrs; ++i) {
072                String key = attributes.getLocalName(i);
073                if ((key == null) || (key.length() == 0)) {
074                    key = attributes.getQName(i);
075                }
076                String value = attributes.getValue(i);
077                props.setProperty(key, value);
078            }
079            
080            try {
081                declarePlugin(digester, props);
082            } catch(PluginInvalidInputException ex) {
083                throw new PluginInvalidInputException(
084                    "Error on element [" + digester.getMatch() + 
085                    "]: " + ex.getMessage());
086            }
087        }
088        
089        public static void declarePlugin(Digester digester, Properties props)
090        throws PluginException {
091            
092            String id = props.getProperty("id");
093            String pluginClassName = props.getProperty("class");
094            
095            if (id == null) {
096                throw new PluginInvalidInputException(
097                    "mandatory attribute id not present on plugin declaration");
098            }
099    
100            if (pluginClassName == null) {
101                throw new PluginInvalidInputException(
102                    "mandatory attribute class not present on plugin declaration");
103            }
104    
105            Declaration newDecl = new Declaration(pluginClassName);
106            newDecl.setId(id);
107            newDecl.setProperties(props);
108    
109            PluginRules rc = (PluginRules) digester.getRules();
110            PluginManager pm = rc.getPluginManager();
111    
112            newDecl.init(digester, pm);
113            pm.addDeclaration(newDecl);
114            
115            // Note that it is perfectly safe to redeclare a plugin, because
116            // the declaration doesn't add any rules to digester; all it does
117            // is create a RuleLoader instance whch is *capable* of adding the
118            // rules to the digester.
119        }
120    }
121