KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > tagshandler > ConfigTagsHandler


1 /*
2  * Copyright (c) 2001, 2002 The XDoclet team
3  * All rights reserved.
4  */

5 package xdoclet.tagshandler;
6
7 import java.beans.Introspector JavaDoc;
8 import java.lang.reflect.Method JavaDoc;
9 import java.util.ArrayList JavaDoc;
10 import java.util.Collection JavaDoc;
11 import java.util.Properties JavaDoc;
12 import java.util.StringTokenizer JavaDoc;
13
14 import org.apache.commons.logging.Log;
15
16 import xdoclet.ConfigParamIntrospector;
17 import xdoclet.SubTask;
18 import xdoclet.XDocletException;
19 import xdoclet.XDocletTagSupport;
20 import xdoclet.util.LogUtil;
21
22 /**
23  * @author Ara Abrahamian (ara_e@email.com)
24  * @created Oct 15, 2001
25  * @xdoclet.taghandler namespace="Config"
26  * @version $Revision: 1.9 $
27  */

28 public class ConfigTagsHandler extends XDocletTagSupport
29 {
30     /**
31      * The current config parameter name. forAllConfigParameters sets the value while looping over values of the config
32      * parameter. Note that this is only used for config parameters of type java.util.ArrayList. Other tags working with
33      * config parameters use current config parameter name to lookup the value of that parameter. For each config
34      * parameter there exists a corresponding getter method in the subtask, so all public getter methods can be used as
35      * config parameters.
36      *
37      * @see #currentConfigParamIndex
38      * @see #getConfigParameter(java.lang.String)
39      * @see #forAllConfigParameters(java.lang.String,java.util.Properties)
40      */

41     private static String JavaDoc currentConfigParam = null;
42
43     /**
44      * The current config parameter index. forAllConfigParameters sets the value while looping over values of the config
45      * parameter.
46      *
47      * @see #currentConfigParam
48      * @see #getConfigParameter(java.lang.String)
49      * @see #forAllConfigParameters(java.lang.String,java.util.Properties)
50      */

51     private static int currentConfigParamIndex = -1;
52
53     /**
54      * Gets the CurrentConfigParamIndex attribute of the ConfigTagsHandler class
55      *
56      * @return The CurrentConfigParamIndex value
57      */

58     public static int getCurrentConfigParamIndex()
59     {
60         return currentConfigParamIndex;
61     }
62
63     /**
64      * Returns the value for the specified configuration parameter. Null if the config parameter not found.
65      *
66      * @param paramName Description of Parameter
67      * @return The ConfigParameter value
68      * @exception XDocletException Description of Exception
69      * @todo When searching for param part of a subtask.element.param config param we rely on
70      * bare reflection mechanism, so if we had getMyParam and we specified myparam for example (case mismatch) it
71      * fails (in Class.getMethod). We should provide a case-insensitive solution.
72      */

73     public Object JavaDoc getConfigParameter(String JavaDoc paramName) throws XDocletException
74     {
75         Log log = LogUtil.getLog(ConfigTagsHandler.class, "getConfigParameter");
76
77         paramName = Introspector.decapitalize(paramName);
78
79         SubTask subtask = getDocletContext().getActiveSubTask();
80
81         if (log.isDebugEnabled()) {
82             log.debug("subtask=" + subtask.getClass());
83             log.debug("currentConfigParamIndex=" + currentConfigParamIndex);
84             log.debug("currentConfigParam=" + currentConfigParam);
85             log.debug("paramName=" + paramName);
86         }
87
88         String JavaDoc configName = paramName;
89         Object JavaDoc configValue = null;
90         int index = 0;
91
92         index = configName.indexOf('.');
93
94         if (index != -1) {
95             // so it's not in global namespace or activesubtask.param
96

97             int index2 = paramName.indexOf('.', index + 1);
98
99             // has one dot. subtaskname.param or activesubtask.element.param format
100
if (configValue == null && index2 == -1) {
101                 // 1. is in subtaskname.param format
102
configName = paramName;
103                 configValue = getDocletContext().getConfigParam(configName);
104
105                 // 2. is in activesubtask.element.param format
106
if (configValue == null) {
107                     String JavaDoc elemname = paramName.substring(0, index);
108                     String JavaDoc paramname = paramName.substring(index + 1);
109
110                     configName = subtask.getSubTaskName() + '.' + elemname;
111                     configValue = getDocletContext().getConfigParam(configName);
112
113                     // ok we have activesubtask.element value, use reflection to get
114
// the param inside the element
115
if (configValue != null) {
116                         // we're in a forAllConfigParams loop for a ArrayList-based config parameter
117
if (currentConfigParamIndex != -1) {
118                             log.debug("In a forAllConfigParams loop for an ArrayList-based config parameter.");
119                             // param_value = element at currentConfigParamIndex index of the ArrayList
120
configValue = ((java.util.ArrayList JavaDoc) configValue).get(currentConfigParamIndex);
121                         }
122
123                         Method JavaDoc getterMethod = ConfigParamIntrospector.findGetterMethod(configValue, paramname);
124
125                         if (getterMethod == null) {
126                             configValue = null;
127                         }
128
129                         try {
130                             configValue = getterMethod.invoke(configValue, null);
131                         }
132                         catch (Exception JavaDoc e) {
133                             log.debug("not found", e);
134                         }
135                     }
136                 }
137             }
138             else {
139                 // has more than one dot. subtaskname.elem.param format
140

141                 // lookup subtaskname.elem
142
int lastDotIndex = paramName.lastIndexOf('.');
143                 String JavaDoc paramname = paramName.substring(lastDotIndex + 1);
144
145                 configName = paramName.substring(0, lastDotIndex);
146                 configValue = getDocletContext().getConfigParam(configName);
147
148                 if (configValue != null) {
149                     // we're in a forAllConfigParams loop for a ArrayList-based config parameter
150
if (currentConfigParamIndex != -1) {
151                         log.debug("In a forAllConfigParams loop for an ArrayList-based config parameter.");
152
153                         // param_value = element at currentConfigParamIndex index of the ArrayList
154
configValue = ((java.util.ArrayList JavaDoc) configValue).get(currentConfigParamIndex);
155                     }
156
157                     Method JavaDoc getterMethod = ConfigParamIntrospector.findGetterMethod(configValue, paramname);
158
159                     if (getterMethod == null) {
160                         configValue = null;
161                     }
162
163                     try {
164                         configValue = getterMethod.invoke(configValue, null);
165                     }
166                     catch (Exception JavaDoc e) {
167                         log.debug("not found", e);
168                     }
169                 }
170             }
171         }
172         else {
173             // is either in global namespace or activesubtask.param
174

175             // 1. search active subtask
176
configName = subtask.getSubTaskName() + '.' + paramName;
177             configValue = getDocletContext().getConfigParam(configName);
178
179             // 2. search DocletTask global namespace
180
if (configValue == null) {
181                 configName = paramName;
182                 configValue = getDocletContext().getConfigParam(paramName);
183             }
184         }
185
186         // not found at all
187
if (configValue == null) {
188             return null;
189         }
190         else {
191             if (log.isDebugEnabled()) {
192                 log.debug("Config param found:" + paramName);
193             }
194         }
195
196         // NULL is used instead of null because you can't put a null in a hashtable
197
if (configValue.equals(ConfigParamIntrospector.NULL)) {
198             configValue = null;
199         }
200
201         log.debug("configValue=" + configValue);
202
203         return configValue;
204     }
205
206     /**
207      * Evaluates the body if config parameter specified is not null.
208      *
209      * @param template The body of the block tag
210      * @param attributes The attributes of the template tag
211      * @exception XDocletException Description of Exception
212      * @doc.tag type="block"
213      * @doc.param name="paramName" optional="false" description="The config parameter name, it's a
214      * parameter settable from within build file."
215      */

216     public void ifHasConfigParam(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
217     {
218         if (!configParameterValue(attributes).equals("")) {
219             generate(template);
220         }
221     }
222
223     /**
224      * Returns the values of a configuration parameter with the name paramName.
225      *
226      * @param attributes The attributes of the template tag
227      * @return Description of the Returned Value
228      * @exception XDocletException Description of Exception
229      * @doc.tag type="content"
230      * @doc.param name="paramName" optional="false" description="The config parameter name, it's a
231      * parameter settable from within build file."
232      */

233     public String JavaDoc configParameterValue(Properties JavaDoc attributes) throws XDocletException
234     {
235         String JavaDoc paramName = attributes.getProperty("paramName");
236         Object JavaDoc configParam = getConfigParameter(paramName);
237
238         // if empty collection, treat as no value
239
if (configParam instanceof Collection JavaDoc && ((Collection JavaDoc) configParam).isEmpty()) {
240             return "";
241         }
242         // or if zero length array treat as no value
243
else if (configParam instanceof Object JavaDoc[] && ((Object JavaDoc[]) configParam).length == 0) {
244             return "";
245         }
246         // otherwise get the value
247
else if (configParam != null) {
248             return configParam.toString();
249         }
250         // if nothing there, return empty string
251
else {
252             return "";
253         }
254     }
255
256     /**
257      * Evaluate the body for all configuration parameters with the name paramName. It's basically used for
258      * java.util.ArrayList-based parameter types, and the body is evaluated for all items of the ArrayList.
259      *
260      * @param template The body of the block tag
261      * @param attributes The attributes of the template tag
262      * @exception XDocletException Description of Exception
263      * @doc.tag type="block"
264      * @doc.param name="paramName" optional="false" description="The config parameter name, it's a
265      * parameter settable from within build file."
266      */

267     public void forAllConfigParameters(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
268     {
269         String JavaDoc paramName = attributes.getProperty("paramName");
270         ArrayList JavaDoc configParams = (java.util.ArrayList JavaDoc) getConfigParameter(paramName);
271
272         for (int i = 0; i < configParams.size(); i++) {
273             currentConfigParam = paramName;
274             currentConfigParamIndex = i;
275
276             generate(template);
277         }
278
279         currentConfigParam = null;
280         currentConfigParamIndex = -1;
281     }
282
283     /**
284      * Evaluate the body if the value of the configuration parameter is greater or equal to value.
285      *
286      * @param template The body of the block tag
287      * @param attributes The attributes of the template tag
288      * @exception XDocletException Description of Exception
289      * @doc.tag type="block"
290      * @doc.param name="paramName" optional="false" description="The config parameter name, it's a
291      * parameter settable from within build file."
292      * @doc.param name="value" optional="false" description="The desired value."
293      */

294     public void ifConfigParamGreaterOrEquals(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
295     {
296         if (ifConfigParamGreaterOrEquals_Impl(attributes)) {
297             generate(template);
298         }
299     }
300
301     /**
302      * Evaluate the body if the value of the configuration parameter is not greater or equal to value.
303      *
304      * @param template The body of the block tag
305      * @param attributes The attributes of the template tag
306      * @exception XDocletException Description of Exception
307      * @doc.tag type="block"
308      * @doc.param name="paramName" optional="false" description="The config parameter name, it's a
309      * parameter settable from within build file."
310      * @doc.param name="value" optional="false" description="The desired value."
311      */

312     public void ifConfigParamNotGreaterOrEquals(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
313     {
314         if (!ifConfigParamGreaterOrEquals_Impl(attributes)) {
315             generate(template);
316         }
317     }
318
319     /**
320      * Evaluate the body if the value of the configuration parameter equals value.
321      *
322      * @param template The body of the block tag
323      * @param attributes The attributes of the template tag
324      * @exception XDocletException Description of Exception
325      * @doc.tag type="block"
326      * @doc.param name="paramName" optional="false" description="The config parameter name, it's a
327      * parameter settable from within build file."
328      * @doc.param name="value" optional="false" description="The desired value."
329      */

330     public void ifConfigParamEquals(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
331     {
332         if (ifConfigParamEquals_Impl(attributes)) {
333             generate(template);
334         }
335     }
336
337     /**
338      * Evaluate the body if the value of the configuration parameter doesn't equal value.
339      *
340      * @param template The body of the block tag
341      * @param attributes The attributes of the template tag
342      * @exception XDocletException Description of Exception
343      * @doc.tag type="block"
344      * @doc.param name="paramName" optional="false" description="The config parameter name, it's a
345      * parameter settable from within build file."
346      * @doc.param name="value" optional="false" description="The desired value."
347      */

348     public void ifConfigParamNotEquals(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
349     {
350         if (!ifConfigParamEquals_Impl(attributes)) {
351             generate(template);
352         }
353     }
354
355     /**
356      * The implementation of ifConfigParamGreaterOrEquals and ifConfigParamNotGreaterOrEquals tags. Currently the value
357      * can only be of a float type like "2.0".
358      *
359      * @param attributes The attributes of the template tag
360      * @return Description of the Returned Value
361      * @exception XDocletException Description of Exception
362      * @see #ifConfigParamGreaterOrEquals(java.lang.String,java.util.Properties)
363      * @see #ifConfigParamNotGreaterOrEquals(java.lang.String,java.util.Properties)
364      */

365     protected boolean ifConfigParamGreaterOrEquals_Impl(Properties JavaDoc attributes) throws XDocletException
366     {
367         Log log = LogUtil.getLog(ConfigTagsHandler.class, "ifConfigParamGreaterOrEquals_Impl");
368
369         String JavaDoc paramName = attributes.getProperty("paramName");
370         String JavaDoc paramValue = attributes.getProperty("value");
371
372         Object JavaDoc configParamValue = getConfigParameter(paramName);
373
374         boolean greaterOrEquals = false;
375
376         if (configParamValue != null) {
377             greaterOrEquals = configParamValue.equals(paramValue);
378             if (!greaterOrEquals) {
379                 StringTokenizer JavaDoc configParamTokenizer = new StringTokenizer JavaDoc(configParamValue.toString(), ".");
380                 StringTokenizer JavaDoc paramTokenizer = new StringTokenizer JavaDoc(paramValue, ".");
381
382                 boolean greater = false;
383                 boolean less = false;
384
385                 while (!greater && !less && (configParamTokenizer.hasMoreTokens() ||
386                     paramTokenizer.hasMoreTokens())) {
387                     int i = configParamTokenizer.hasMoreTokens() ? Integer.parseInt(configParamTokenizer.nextToken()) : 0;
388                     int j = paramTokenizer.hasMoreTokens() ? Integer.parseInt(paramTokenizer.nextToken()) : 0;
389
390                     greater = i > j;
391                     less = i < j;
392                 }
393
394                 greaterOrEquals = greater || !less;
395             }
396         }
397
398         return greaterOrEquals;
399     }
400
401     /**
402      * The implementation of ifConfigParamEquals and ifConfigParamEquals tags. Currently the value can only be of a
403      * float type like "2.0".
404      *
405      * @param attributes The attributes of the template tag
406      * @return Description of the Returned Value
407      * @exception XDocletException Description of Exception
408      * @see #ifConfigParamEquals(java.lang.String,java.util.Properties)
409      * @see #ifConfigParamNotEquals(java.lang.String,java.util.Properties)
410      */

411     protected boolean ifConfigParamEquals_Impl(Properties JavaDoc attributes) throws XDocletException
412     {
413         Log log = LogUtil.getLog(ConfigTagsHandler.class, "ifConfigParamEquals_Impl");
414
415         String JavaDoc paramName = attributes.getProperty("paramName");
416         String JavaDoc paramValue = attributes.getProperty("value");
417
418         Object JavaDoc configParamValue = getConfigParameter(paramName);
419
420         if (log.isDebugEnabled())
421             log.debug("paramName='" + paramName +
422                 "',paramValue='" + paramValue +
423                 "',configParamValue='" + configParamValue + '\'');
424
425         if (configParamValue == null)
426             return false;
427
428         if (configParamValue instanceof Boolean JavaDoc)
429             return configParamValue.equals(Boolean.valueOf(paramValue));
430         if (configParamValue instanceof Integer JavaDoc)
431             return configParamValue.equals(Integer.valueOf(paramValue));
432
433         // Catch-all for Strings and any other types we don't (yet) check for.
434
// Any non-strings that get here should be added to the cases above, or
435
// the comparison may not be accurate e.g. "1.000" != "1.0000"
436
if (!(configParamValue instanceof String JavaDoc))
437             log.warn(configParamValue.getClass() + " needs adding to configParamValue types");
438         return configParamValue.toString().equals(paramValue);
439     }
440
441     /**
442      * Say we had <XDtConfig:forAllConfigParameters paramName="tagLibs">, and now we do a
443      * <XDtConfig:configParameterValue paramName="tagLibs.uri"/>. What this method does is
444      *
445      * @param paramName
446      * @return true if it is the same
447      */

448     private boolean isSubConfigParamInSameConfigParam(String JavaDoc paramName)
449     {
450         return paramName.equals(currentConfigParam);
451     }
452 }
453
Popular Tags