1 package org.apache.commons.digester3.plugins;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.List;
23 import java.util.LinkedList;
24
25 import org.apache.commons.digester3.plugins.strategies.FinderFromClass;
26 import org.apache.commons.digester3.plugins.strategies.FinderFromDfltClass;
27 import org.apache.commons.digester3.plugins.strategies.FinderFromDfltMethod;
28 import org.apache.commons.digester3.plugins.strategies.FinderFromDfltResource;
29 import org.apache.commons.digester3.plugins.strategies.FinderFromFile;
30 import org.apache.commons.digester3.plugins.strategies.FinderFromMethod;
31 import org.apache.commons.digester3.plugins.strategies.FinderFromResource;
32 import org.apache.commons.digester3.plugins.strategies.FinderSetProperties;
33
34 /**
35 * Provides data and services which should exist only once per digester.
36 * <p>
37 * This class holds a number of useful items which should be shared by all plugin objects. Such data cannot be stored on
38 * the PluginRules or PluginManager classes, as there can be multiple instances of these at various times during a
39 * parse.
40 * <p>
41 * The name "Context" refers to the similarity between this class and a ServletContext class in a servlet engine. A
42 * ServletContext object provides access to the container's services such as obtaining global configuration parameters
43 * for the container, or getting access to logging services. For plugins, a Digester instance can be regarded as
44 * "the container".
45 *
46 * @since 1.6
47 */
48 public class PluginContext
49 {
50
51 private static final String DFLT_PLUGIN_CLASS_ATTR_NS = null;
52
53 private static final String DFLT_PLUGIN_CLASS_ATTR = "plugin-class";
54
55 // the xml attribute the user uses on an xml element to specify
56 // the plugin's class
57 private static final String DFLT_PLUGIN_ID_ATTR_NS = null;
58
59 private static final String DFLT_PLUGIN_ID_ATTR = "plugin-id";
60
61 /** See {@link #setPluginClassAttribute}. */
62 private String pluginClassAttrNs = DFLT_PLUGIN_CLASS_ATTR_NS;
63
64 /** See {@link #setPluginClassAttribute}. */
65 private String pluginClassAttr = DFLT_PLUGIN_CLASS_ATTR;
66
67 /** See {@link #setPluginClassAttribute}. */
68 private String pluginIdAttrNs = DFLT_PLUGIN_ID_ATTR_NS;
69
70 /** See {@link #setPluginClassAttribute}. */
71 private String pluginIdAttr = DFLT_PLUGIN_ID_ATTR;
72
73 /**
74 * A list of RuleFinder objects used by all Declarations (and thus indirectly by all PluginCreateRules to locate the
75 * custom rules for plugin classes.
76 */
77 private List<RuleFinder> ruleFinders;
78
79 // ------------------- methods ---------------------------------------
80
81 /**
82 * Return the list of RuleFinder objects. Under normal circumstances this method creates a default list of these
83 * objects when first called (ie "on-demand" or "lazy initialization"). However if setRuleFinders has been called
84 * first, then the list specified there is returned.
85 * <p>
86 * It is explicitly permitted for the caller to modify this list by inserting or removing RuleFinder objects.
87 *
88 * @return the list of RuleFinder objects
89 */
90 public List<RuleFinder> getRuleFinders()
91 {
92 if ( ruleFinders == null )
93 {
94 // when processing a plugin declaration, attempts are made to
95 // find custom rules in the order in which the Finder objects
96 // are added below. However this list can be modified
97 ruleFinders = new LinkedList<RuleFinder>();
98 ruleFinders.add( new FinderFromFile() );
99 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 }