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