001/* $Id: PluginContext.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 */
018package org.apache.commons.digester.plugins;
019
020import java.util.List;
021import java.util.LinkedList;
022
023import org.apache.commons.digester.plugins.strategies.FinderFromFile;
024import org.apache.commons.digester.plugins.strategies.FinderFromResource;
025import org.apache.commons.digester.plugins.strategies.FinderFromClass;
026import org.apache.commons.digester.plugins.strategies.FinderFromMethod;
027import org.apache.commons.digester.plugins.strategies.FinderFromDfltMethod;
028import org.apache.commons.digester.plugins.strategies.FinderFromDfltClass;
029import org.apache.commons.digester.plugins.strategies.FinderFromDfltResource;
030import org.apache.commons.digester.plugins.strategies.FinderSetProperties;
031
032/**
033 * Provides data and services which should exist only once per digester.
034 * <p>
035 * This class holds a number of useful items which should be shared by all
036 * plugin objects. Such data cannot be stored on the PluginRules or 
037 * PluginManager classes, as there can be multiple instances of these at 
038 * various times during a parse. 
039 * <p>
040 * The name "Context" refers to the similarity between this class and a
041 * ServletContext class in a servlet engine. A ServletContext object provides
042 * access to the container's services such as obtaining global configuration
043 * parameters for the container, or getting access to logging services. For
044 * plugins, a Digester instance can be regarded as "the container".
045 *
046 * @since 1.6
047 */
048
049public class PluginContext {
050
051    // TODO: Consider making following four constants static in 2.0
052    // the xml attribute the user uses on an xml element to specify
053    // the plugin's class
054    public final String DFLT_PLUGIN_CLASS_ATTR_NS = null;
055    public final String DFLT_PLUGIN_CLASS_ATTR = "plugin-class";
056
057    // the xml attribute the user uses on an xml element to specify
058    // the plugin's class
059    public final String DFLT_PLUGIN_ID_ATTR_NS = null;
060    public final String DFLT_PLUGIN_ID_ATTR = "plugin-id";
061    
062    /** See {@link #setPluginClassAttribute}. */
063    private String pluginClassAttrNs = DFLT_PLUGIN_CLASS_ATTR_NS;
064
065    /** See {@link #setPluginClassAttribute}. */
066    private String pluginClassAttr = DFLT_PLUGIN_CLASS_ATTR;
067
068    /** See {@link #setPluginClassAttribute}. */
069    private String pluginIdAttrNs = DFLT_PLUGIN_ID_ATTR_NS;
070
071    /** See {@link #setPluginClassAttribute}. */
072    private String pluginIdAttr = DFLT_PLUGIN_ID_ATTR;
073    
074    /** 
075     * A list of RuleFinder objects used by all Declarations (and thus
076     * indirectly by all PluginCreateRules to locate the custom rules
077     * for plugin classes.
078     */
079    private List<RuleFinder> ruleFinders;
080
081    //------------------- constructors ---------------------------------------
082    
083    public PluginContext() {
084    }
085    
086    //------------------- methods ---------------------------------------
087
088    /**
089     * Return the list of RuleFinder objects. Under normal circumstances
090     * this method creates a default list of these objects when first called
091     * (ie "on-demand" or "lazy initialization"). However if setRuleFinders
092     * has been called first, then the list specified there is returned.
093     * <p>
094     * It is explicitly permitted for the caller to modify this list
095     * by inserting or removing RuleFinder objects.
096     */
097    public List<RuleFinder> getRuleFinders() {
098        if (ruleFinders == null) {
099            // when processing a plugin declaration, attempts are made to
100            // find custom rules in the order in which the Finder objects
101            // are added below. However this list can be modified
102            ruleFinders = new LinkedList<RuleFinder>();
103            ruleFinders.add(new FinderFromFile());
104            ruleFinders.add(new FinderFromResource());
105            ruleFinders.add(new FinderFromClass());
106            ruleFinders.add(new FinderFromMethod());
107            ruleFinders.add(new FinderFromDfltMethod());
108            ruleFinders.add(new FinderFromDfltClass());
109            ruleFinders.add(new FinderFromDfltResource());
110            ruleFinders.add(new FinderFromDfltResource(".xml"));
111            ruleFinders.add(new FinderSetProperties());
112        }
113        return ruleFinders;
114    }
115    
116    /**
117     * Set the list of RuleFinder objects. This may be useful if working
118     * in a non-english language, allowing the application developer to
119     * replace the standard list with a list of objects which look for xml 
120     * attributes in the local language.
121     * <p>
122     * If the intent is just to add an additional rule-finding algorithm, then
123     * it may be better to call #getRuleFinders, and insert a new object into 
124     * the start of the list.
125     */
126    public void setRuleFinders(List<RuleFinder> ruleFinders) {
127        this.ruleFinders = ruleFinders;
128    }
129
130    /**
131     * Sets the xml attribute which the input xml uses to indicate to a 
132     * PluginCreateRule which class should be instantiated.
133     * <p>
134     * Example:
135     * <pre>
136     * setPluginClassAttribute(null, "class");
137     * </pre>
138     * will allow this in the input xml:
139     * <pre>
140     *  &lt;root&gt;
141     *    &lt;some-plugin class="com.acme.widget"&gt; ......
142     * </pre>
143     * instead of the default syntax:
144     * <pre>
145     *  &lt;root&gt;
146     *    &lt;some-plugin plugin-class="com.acme.widget"&gt; ......
147     * </pre>
148     * This is particularly useful if the input xml document is not in
149     * English.
150     * <p>
151     * Note that the xml attributes used by PluginDeclarationRules are not
152     * affected by this method.
153     *
154     * @param namespaceUri is the namespace uri that the specified attribute
155     * is in. If the attribute is in no namespace, then this should be null.
156     * Note that if a namespace is used, the attrName value should <i>not</i>
157     * contain any kind of namespace-prefix. Note also that if you are using
158     * a non-namespace-aware parser, this parameter <i>must</i> be null.
159     *
160     * @param attrName is the attribute whose value contains the name of the
161     * class to be instantiated.
162     */
163    public void setPluginClassAttribute(String namespaceUri, 
164                                        String attrName) {
165        pluginClassAttrNs = namespaceUri;
166        pluginClassAttr = attrName;
167    }
168
169    /**
170     * Sets the xml attribute which the input xml uses to indicate to a 
171     * PluginCreateRule which plugin declaration is being referenced.
172     * <p>
173     * Example:
174     * <pre>
175     * setPluginIdAttribute(null, "id");
176     * </pre>
177     * will allow this in the input xml:
178     * <pre>
179     *  &lt;root&gt;
180     *    &lt;some-plugin id="widget"&gt; ......
181     * </pre>
182     * rather than the default behaviour:
183     * <pre>
184     *  &lt;root&gt;
185     *    &lt;some-plugin plugin-id="widget"&gt; ......
186     * </pre>
187     * This is particularly useful if the input xml document is not in
188     * English.
189     * <p>
190     * Note that the xml attributes used by PluginDeclarationRules are not
191     * affected by this method.
192     *
193     * @param namespaceUri is the namespace uri that the specified attribute
194     * is in. If the attribute is in no namespace, then this should be null.
195     * Note that if a namespace is used, the attrName value should <i>not</i>
196     * contain any kind of namespace-prefix. Note also that if you are using
197     * a non-namespace-aware parser, this parameter <i>must</i> be null.
198     *
199     * @param attrName is the attribute whose value contains the id of the
200     * plugin declaration to be used when instantiating an object.
201     */
202    public void setPluginIdAttribute(String namespaceUri, 
203                                     String attrName) {
204        pluginIdAttrNs = namespaceUri;
205        pluginIdAttr = attrName;
206    }
207
208    /**
209     * Get the namespace for the xml attribute which indicates to a 
210     * PluginCreateRule which class is to be plugged in.
211     * <p>
212     * May be null (in fact, normally will be).
213     */
214    public String getPluginClassAttrNs() {
215        return pluginClassAttrNs;
216    }
217    
218    /**
219     * Get the namespace for the xml attribute which indicates to a 
220     * PluginCreateRule which class is to be plugged in.
221     * <p>
222     * The return value is never null.
223     */
224    public String getPluginClassAttr() {
225        return pluginClassAttr;
226    }
227    
228    /**
229     * Get the namespace for the xml attribute which indicates to a 
230     * PluginCreateRule which previous plugin declaration should be used.
231     * <p>
232     * May be null (in fact, normally will be).
233     */
234    public String getPluginIdAttrNs() {
235        return pluginIdAttrNs;
236    }
237    
238    /**
239     * Get the namespace for the xml attribute which indicates to a 
240     * PluginCreateRule which previous plugin declaration should be used.
241     * <p>
242     * The return value is never null.
243     */
244    public String getPluginIdAttr() {
245        return pluginIdAttr;
246    }
247}