001    /* $Id: PluginContext.java 476312 2006-11-17 20:59:09Z rahul $
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    package org.apache.commons.digester.plugins;
019    
020    import java.util.List;
021    import java.util.LinkedList;
022    
023    import org.apache.commons.digester.plugins.strategies.FinderFromFile;
024    import org.apache.commons.digester.plugins.strategies.FinderFromResource;
025    import org.apache.commons.digester.plugins.strategies.FinderFromClass;
026    import org.apache.commons.digester.plugins.strategies.FinderFromMethod;
027    import org.apache.commons.digester.plugins.strategies.FinderFromDfltMethod;
028    import org.apache.commons.digester.plugins.strategies.FinderFromDfltClass;
029    import org.apache.commons.digester.plugins.strategies.FinderFromDfltResource;
030    import 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    
049    public 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 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 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();
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 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    }