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