001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.chain.config;
018
019import org.apache.commons.digester.Digester;
020import org.apache.commons.digester.RuleSetBase;
021
022/**
023 * Digester {@code RuleSet} for configuring <em>Chain of
024 * Responsibility</em> command chains, and adding them to an appropriate
025 * {@link org.apache.commons.chain.Catalog}. The following properties
026 * may be configured prior to executing the {@code addRuleInstance()}
027 * method in order to influence the rules that get added, with default
028 * values in square brackets:
029 * <ul>
030 * <li><strong>catalogClass</strong> -- Fully qualified name of the
031 *     implementation class used to create new
032 *     {@link org.apache.commons.chain.Catalog} instances.
033 *     If not specified, the default value is
034 *     {@code org.apache.commons.chain.impl.CatalogBase}.</li>
035 * <li><strong>catalogElement</strong> -- Name of the XML element representing
036 *     the addition of a {@link org.apache.commons.chain.Catalog}.
037 *     Any such catalog that is created will be registered with the
038 *     {@link org.apache.commons.chain.CatalogFactory} instance for our
039 *     application, under the name specified by the {@code nameAttribute}
040 *     attribute (if present), or as the default {@link org.apache.commons.chain.Catalog}.
041 *     If not specified, the default value is {@code catalog}.</li>
042 * <li><strong>chainClass</strong> -- Fully qualified name of the implementation
043 *     class used to create new {@link org.apache.commons.chain.Chain} instances.
044 *     If not specified, the default value is
045 *     {@code org.apache.commons.chain.impl.ChainBase}.
046 *     </li>
047 * <li><strong>chainElement</strong> -- Name of the XML element representing
048 *     the addition of a {@link org.apache.commons.chain.Chain}. A chain
049 *     element has the same functionality as a command element, except that
050 *     it defaults the implementation class to
051 *     {@code org.apache.commons.chain.impl.ChainBase}. [chain]</li>
052 * <li><strong>classAttribute</strong> -- Attribute on a chain (optional) or
053 *     command (required) element that specifies the fully qualified class
054 *     name of the implementation class that should be instantiated.
055 *     [className]</li>
056 * <li><strong>commandElement</strong> -- Name of the XML element
057 *     representing the addition of a {@link org.apache.commons.chain.Command}.
058 *     An implementation class name must be provided on the attribute named by the
059 *     {@code classAttribute} property. [command]</li>
060 * <li><strong>defineElement</strong> -- Name of the XML element
061 *     that associates the element specified by the {@code nameAttribute}
062 *     attributes with a {@link org.apache.commons.chain.Command} or
063 *     {@link org.apache.commons.chain.Chain} implementation class
064 *     named by the {@code classAttribute} attribute. [define]</li>
065 * <li><strong>nameAttribute</strong> -- Attribute on an outermost chain or
066 *     command element that will be used to register this command with the
067 *     associated {@link org.apache.commons.chain.Catalog} instance on the stack.
068 *     [name]</li>
069 * <li><strong>namespaceURI</strong> -- The XML namespace URI with which these
070 *     rules will be associated, or {@code null} for no namespace.
071 *     [null]</li>
072 * </ul>
073 *
074 * @author Craig R. McClanahan
075 * @version $Revision$ $Date$
076 */
077public class ConfigRuleSet extends RuleSetBase {
078
079    // ----------------------------------------------------- Instance Variables
080
081    private String catalogClass = "org.apache.commons.chain.impl.CatalogBase";
082    private String catalogElement = "catalog";
083    private String chainClass = "org.apache.commons.chain.impl.ChainBase";
084    private String chainElement = "chain";
085    private String classAttribute = "className";
086    private String commandElement = "command";
087    private String defineElement = "define";
088    private String nameAttribute = "name";
089
090    // ----------------------------------------------------------- Constructors
091
092    /**
093     * The Default-Constructor for this class.
094     */
095    public ConfigRuleSet() {
096    }
097
098    // ------------------------------------------------------------- Properties
099
100    /**
101     * Return the fully qualified {@link org.apache.commons.chain.Catalog}
102     * implementation class.
103     *
104     * @return The Catalog's class name.
105     */
106    public String getCatalogClass() {
107        return this.catalogClass;
108    }
109
110    /**
111     * Set the fully qualified {@link org.apache.commons.chain.Catalog}
112     * implementation class.
113     *
114     * @param catalogClass The new {@link org.apache.commons.chain.Catalog}
115     *        implementation class
116     */
117    public void setCatalogClass(String catalogClass) {
118        this.catalogClass = catalogClass;
119    }
120
121    /**
122     * Return the element name of a catalog element.
123     *
124     * @return The element name of a catalog element.
125     */
126    public String getCatalogElement() {
127        return this.catalogElement;
128    }
129
130    /**
131     * Set the element name of a catalog element.
132     *
133     * @param catalogElement The new element name
134     */
135    public void setCatalogElement(String catalogElement) {
136        this.catalogElement = catalogElement;
137    }
138
139    /**
140     * Return the fully qualified {@link org.apache.commons.chain.Chain}
141     * implementation class.
142     *
143     * @return The Chain's class name.
144     */
145    public String getChainClass() {
146        return this.chainClass;
147    }
148
149    /**
150     * Set the fully qualified {@link org.apache.commons.chain.Chain}
151     * implementation class.
152     *
153     * @param chainClass The new {@link org.apache.commons.chain.Chain}
154     *        implementation class
155     */
156    public void setChainClass(String chainClass) {
157        this.chainClass = chainClass;
158    }
159
160    /**
161     * Return the element name of a chain element.
162     *
163     * @return The element name of a catalog element.
164     */
165    public String getChainElement() {
166        return this.chainElement;
167    }
168
169    /**
170     * Set the element name of a chain element.
171     *
172     * @param chainElement The new element name
173     */
174    public void setChainElement(String chainElement) {
175        this.chainElement = chainElement;
176    }
177
178    /**
179     * Return the attribute name of a class attribute.
180     *
181     * @return The attribute name of a class attribute.
182     */
183    public String getClassAttribute() {
184        return this.classAttribute;
185    }
186
187    /**
188     * Set the attribute name of a class attribute.
189     *
190     * @param classAttribute The new attribute name
191     */
192    public void setClassAttribute(String classAttribute) {
193        this.classAttribute = classAttribute;
194    }
195
196    /**
197     * Return the element name of a command element.
198     *
199     * @return The element name of a command element.
200     */
201    public String getCommandElement() {
202        return this.commandElement;
203    }
204
205    /**
206     * Set the element name of a command element.
207     *
208     * @param commandElement The new element name
209     */
210    public void setCommandElement(String commandElement) {
211        this.commandElement = commandElement;
212    }
213
214    /**
215     * Return the element name of a define element.
216     *
217     * @return The element name of a define element.
218     */
219    public String getDefineElement() {
220        return this.defineElement;
221    }
222
223    /**
224     * Set the element name of a define element.
225     *
226     * @param defineElement The new element name
227     */
228    public void setDefineElement(String defineElement) {
229        this.defineElement = defineElement;
230    }
231
232    /**
233     * Return the attribute name of a name attribute.
234     *
235     * @return The attribute name of an attribute element.
236     */
237    public String getNameAttribute() {
238        return this.nameAttribute;
239    }
240
241    /**
242     * Set the attribute name of a name attribute.
243     *
244     * @param nameAttribute The new attribute name
245     */
246    public void setNameAttribute(String nameAttribute) {
247        this.nameAttribute = nameAttribute;
248    }
249
250    // --------------------------------------------------------- Public Methods
251
252    /**
253     * Add the set of Rule instances defined in this RuleSet to the
254     * specified {@code Digester} instance, associating them with
255     * our namespace URI (if any). This method should only be called
256     * by a Digester instance.
257     *
258     * @param digester Digester instance to which the new Rule instances
259     *        should be added.
260     */
261    @Override
262    public void addRuleInstances(Digester digester) {
263        // Add rules for a catalog element
264        digester.addRule("*/" + getCatalogElement(),
265                         new ConfigCatalogRule(nameAttribute, catalogClass));
266        digester.addSetProperties("*/" + getCatalogElement());
267
268        // Add rules for a chain element
269        digester.addObjectCreate("*/" + getChainElement(),
270                                 getChainClass(),
271                                 getClassAttribute());
272        digester.addSetProperties("*/" + getChainElement());
273        digester.addRule("*/" + getChainElement(),
274                         new ConfigRegisterRule(nameAttribute));
275
276        // Add rules for a command element
277        digester.addObjectCreate("*/" + getCommandElement(),
278                                 null,
279                                 getClassAttribute());
280        digester.addSetProperties("*/" + getCommandElement());
281        digester.addRule("*/" + getCommandElement(),
282                         new ConfigRegisterRule(nameAttribute));
283
284        // Add rules for a define element
285        digester.addRule("*/" + getDefineElement(),
286                         new ConfigDefineRule(getNameAttribute(),
287                                              getClassAttribute()));
288    }
289}