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, "class" );
134 * </pre>
135 *
136 * will allow this in the input xml:
137 *
138 * <pre>
139 * <root>
140 * <some-plugin class="com.acme.widget"> ......
141 * </pre>
142 *
143 * instead of the default syntax:
144 *
145 * <pre>
146 * <root>
147 * <some-plugin plugin-class="com.acme.widget"> ......
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, "id" );
174 * </pre>
175 *
176 * will allow this in the input xml:
177 *
178 * <pre>
179 * <root>
180 * <some-plugin id="widget"> ......
181 * </pre>
182 *
183 * rather than the default behaviour:
184 *
185 * <pre>
186 * <root>
187 * <some-plugin plugin-id="widget"> ......
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 }