    001    /* $Id: PluginDeclarationRule.java 472837 2006-11-09 10:07:51Z skitching $
    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        public void begin(String namespace, String name,
    065                          org.xml.sax.Attributes attributes)
    066                          throws java.lang.Exception {
    067
    068            int nAttrs = attributes.getLength();
    069            Properties props = new Properties();
    070            for(int i=0; i<nAttrs; ++i) {
    071                String key = attributes.getLocalName(i);
    072                if ((key == null) || (key.length() == 0)) {
    073                    key = attributes.getQName(i);
    074                }
    075                String value = attributes.getValue(i);
    076                props.setProperty(key, value);
    077            }
    078
    079            try {
    080                declarePlugin(digester, props);
    081            } catch(PluginInvalidInputException ex) {
    082                throw new PluginInvalidInputException(
    083                    "Error on element [" + digester.getMatch() +
    084                    "]: " + ex.getMessage());
    085            }
    086        }
    087
    088        public static void declarePlugin(Digester digester, Properties props)
    089        throws PluginException {
    090
    091            String id = props.getProperty("id");
    092            String pluginClassName = props.getProperty("class");
    093
    094            if (id == null) {
    095                throw new PluginInvalidInputException(
    096                    "mandatory attribute id not present on plugin declaration");
    097            }
    098
    099            if (pluginClassName == null) {
    100                throw new PluginInvalidInputException(
    101                    "mandatory attribute class not present on plugin declaration");
    102            }
    103
    104            Declaration newDecl = new Declaration(pluginClassName);
    105            newDecl.setId(id);
    106            newDecl.setProperties(props);
    107
    108            PluginRules rc = (PluginRules) digester.getRules();
    109            PluginManager pm = rc.getPluginManager();
    110
    111            newDecl.init(digester, pm);
    112            pm.addDeclaration(newDecl);
    113
    114            // Note that it is perfectly safe to redeclare a plugin, because
    115            // the declaration doesn't add any rules to digester; all it does
    116            // is create a RuleLoader instance whch is *capable* of adding the
    117            // rules to the digester.
    118        }
    119    }
    120