KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > tools > NetUITldTagsHandler


1     /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.tools;
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.Comparator JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Properties JavaDoc;
27 import java.util.StringTokenizer JavaDoc;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 import xdoclet.DocletSupport;
33 import xdoclet.XDocletException;
34 import xdoclet.XDocletMessages;
35 import xdoclet.tagshandler.AbstractProgramElementTagsHandler;
36 import xdoclet.tagshandler.TypeTagsHandler;
37 import xdoclet.util.Translator;
38 import xdoclet.util.TypeConversionUtil;
39
40 import xjavadoc.XTag;
41 import xjavadoc.XProgramElement;
42 import xjavadoc.XMethod;
43 import xjavadoc.XClass;
44 import xjavadoc.XMember;
45
46 /**
47  *
48  * @xdoclet.taghandler namespace="NetUITldGen"
49  */

50 public class NetUITldTagsHandler
51     extends AbstractProgramElementTagsHandler
52 {
53     private static final Log logger = LogFactory.getLog(NetUITldTagsHandler.class);
54     private static final boolean DEBUG = true; //logger.isDebugEnabled();
55

56     private static final String JavaDoc NETUI_ATTRIBUTE = "netui:attribute";
57     private static final String JavaDoc NETUI_TLDX_ATTRIBUTE = "netui.tldx:attribute";
58
59     private static final String JavaDoc EMPTY_STRING = "";
60
61     private String JavaDoc currentTagName;
62
63     /**
64      * @doc:tag type="block"
65      * @doc:param name="paramName" description="The parameter name"
66      */

67     public void ifHasTagValue(String JavaDoc template, Properties JavaDoc attributes)
68         throws XDocletException
69     {
70         String JavaDoc value = paramValue(attributes);
71         if(value != null)
72             generate(template);
73     }
74
75     /**
76      * @doc:tag type="content"
77      * @doc:param name="paramName" description="The parameter name"
78      * @doc.param name="values"
79      * description="The valid values for the parameter, comma separated. An error message is printed if the parameter value is not one of the values."
80      */

81     public String JavaDoc paramValue(Properties JavaDoc attributes)
82         throws XDocletException
83     {
84         XTag cTag = getCurrentClassTag();
85         XTag mTag = getCurrentMethodTag();
86
87         String JavaDoc validValues = attributes.getProperty("values");
88         String JavaDoc paramName = attributes.getProperty("paramName");
89         String JavaDoc tagName = getCurrentTagName();
90
91         if(DEBUG) logger.debug("current class: " + getCurrentClass().getName());
92         if(DEBUG) logger.debug("cTag value for attribute \"" +
93                                             attributes.getProperty("paramName") + "\" is " +
94                                             (cTag != null ? cTag.getAttributeValue(attributes.getProperty("paramName")) : "null"));
95
96         XProgramElement member = null;
97         String JavaDoc value = null;
98         if(cTag != null)
99         {
100             value = cTag.getAttributeValue(paramName);
101             member = getCurrentClass();
102         }
103         else if(mTag != null)
104         {
105             value = mTag.getAttributeValue(paramName);
106             member = getCurrentMethod();
107         }
108
109         // a value was found. perform sanity checks on valid values
110
if (validValues != null)
111         {
112             if(DEBUG) logger.debug("validValues: " + validValues);
113             // check if the value is among the valid values
114
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(validValues, ",");
115             boolean valid = false;
116             while (st.hasMoreTokens())
117             {
118                 if (st.nextToken().equals(value))
119                     valid = true;
120             }
121
122             if(!valid)
123             {
124                 if(DEBUG) logger.debug("FOUND AN INVALID VALUE: " + value);
125
126                 if(member instanceof XMethod)
127                 {
128                     throw new XDocletException
129                         (Translator.getString(XDocletMessages.class,
130                                               XDocletMessages.INVALID_TAG_PARAM_VALUE_METHOD,
131                                               new String JavaDoc[]{value,
132                                                            paramName,
133                                                            tagName,
134                                                            ((XMethod)member).getName(),
135                                                            ((XMethod)member).getContainingClass().getQualifiedName(),
136                                                            validValues}));
137                 }
138                 else if(member instanceof XClass)
139                 {
140                     throw new XDocletException(Translator.getString(XDocletMessages.class,
141                                                                     XDocletMessages.INVALID_TAG_PARAM_VALUE_CLASS,
142                                                                     new String JavaDoc[]{value,
143                                                                                  paramName,
144                                                                                  tagName, ((XClass)member).getQualifiedName(),
145                                                                                  validValues}));
146                 }
147             }
148
149             // it's ridiculous that this is private in the base class
150
//invalidParamValueFound(doc, paramName, "", value, validValues);
151
}
152         
153         return value;
154     }
155
156     /**
157      * @doc.tag type="block"
158      * @doc.param name="abstract" optional="true" values="true,false" description="If true then accept
159      * abstract classes also; otherwise don't."
160      * @doc.param name="type" optional="true" description="For all classes by the type."
161      * @doc.param name="extent" optional="true" values="concrete-type,superclass,hierarchy"
162      * description="Specifies the extent of the type search. If concrete-type then only check the concrete type, if
163      * superclass then check also superclass, if hierarchy then search the whole hierarchy and find if the class is
164      * of the specified type. Default is hierarchy."
165      */

166     public void forAllClasses(String JavaDoc template, Properties JavaDoc attributes)
167         throws XDocletException
168     {
169         String JavaDoc abstractStr = attributes.getProperty("abstract");
170         boolean acceptAbstractClasses = TypeConversionUtil.stringToBoolean(abstractStr, true);
171         String JavaDoc typeName = attributes.getProperty("type");
172         String JavaDoc extentStr = attributes.getProperty("extent");
173         int extent = TypeTagsHandler.extractExtentType(extentStr);
174
175         Object JavaDoc obj = getDocletContext().getConfigParam(getDocletContext().getActiveSubTask().getSubTaskName() + ".packageName");
176         String JavaDoc packageName = (obj != null && !obj.equals(EMPTY_STRING) ? obj.toString() : null);
177
178         if (DEBUG)
179         {
180             logger.debug("filter on package name: " + packageName);
181             logger.debug("acceptAbstractClasses=" + acceptAbstractClasses);
182             logger.debug("typeName=" + typeName);
183             logger.debug("extentStr=" + extentStr);
184             logger.debug("extent=" + extent);
185         }
186
187         //System.out.println("packageName: " + packageName);
188

189         Collection JavaDoc classes = getAllClasses();
190
191         // sort alphabetically
192
Iterator JavaDoc i = sort(classes.iterator());
193         while(i.hasNext())
194         {
195             XClass currentClass = (XClass)i.next();
196             
197             if(packageName != null && !currentClass.getQualifiedName().startsWith(packageName))
198                 continue;
199
200              //System.out.println("currentClass=" + currentClass.getQualifiedName());
201
//System.out.println(" packageName: " + packageName);
202
//System.out.println(" startsWith: " + currentClass.getQualifiedName().startsWith(packageName));
203

204             setCurrentClass(currentClass);
205
206             if (DocletSupport.isDocletGenerated(getCurrentClass()) || (getCurrentClass().isAbstract() && acceptAbstractClasses == false))
207             {
208                 logger.debug("isDocletGenerated or isAbstract");
209                 continue;
210             }
211
212             if (typeName != null)
213             {
214                 if (TypeTagsHandler.isOfType(currentClass, typeName, extent))
215                 {
216                     if(DEBUG) {
217                         logger.debug("isOfType true, generate().");
218                         logger.debug("handling type: " + currentClass.getQualifiedName());
219                     }
220
221                     generate(template);
222                 }
223                 else if(DEBUG) logger.debug("isOfType false, generate().");
224             }
225             else
226             {
227                 if(DEBUG) logger.debug("typeName=null, generate().");
228                 generate(template);
229             }
230         }
231     }
232
233     /**
234      * @doc.tag type="block"
235      * @doc.param name="abstract" optional="true" values="true,false" description="If true then accept abstract classes also; otherwise don't."
236      * @doc.param name="type" optional="true" description="For all classes by the type."
237      * @doc.param name="extent" optional="true" values="concrete-type,superclass,hierarchy"
238      * description="Specifies the extent of the type search. If concrete-type then only check the concrete type, if
239      * superclass then check also superclass, if hierarchy then search the whole hierarchy and find if the class is
240      * of the specified type. Default is hierarchy."
241      */

242     public void forAllFunctions(String JavaDoc template, Properties JavaDoc attributes)
243         throws XDocletException
244     {
245         String JavaDoc abstractStr = attributes.getProperty("abstract");
246         boolean acceptAbstractClasses = TypeConversionUtil.stringToBoolean(abstractStr, true);
247         String JavaDoc typeName = attributes.getProperty("type");
248         String JavaDoc extentStr = attributes.getProperty("extent");
249         int extent = TypeTagsHandler.extractExtentType(extentStr);
250
251         Object JavaDoc obj = getDocletContext().getConfigParam(getDocletContext().getActiveSubTask().getSubTaskName() + ".functionPackage");
252         String JavaDoc packageName = (obj != null && !obj.equals(EMPTY_STRING) ? obj.toString() : null);
253
254         if (DEBUG)
255         {
256             logger.debug("filter on package name: " + packageName);
257             logger.debug("acceptAbstractClasses=" + acceptAbstractClasses);
258             logger.debug("typeName=" + typeName);
259             logger.debug("extentStr=" + extentStr);
260             logger.debug("extent=" + extent);
261         }
262
263         //System.out.println("packageName: " + packageName);
264

265         Collection JavaDoc classes = getAllClasses();
266
267         // sort alphabetically
268
Iterator JavaDoc i = sort(classes.iterator());
269         while(i.hasNext())
270         {
271             XClass currentClass = (XClass)i.next();
272
273             if(packageName != null && !currentClass.getQualifiedName().startsWith(packageName))
274                 continue;
275
276              //System.out.println("currentClass=" + currentClass.getQualifiedName());
277
//System.out.println(" packageName: " + packageName);
278
//System.out.println(" startsWith: " + currentClass.getQualifiedName().startsWith(packageName));
279

280             setCurrentClass(currentClass);
281
282             if (DocletSupport.isDocletGenerated(getCurrentClass()) || (getCurrentClass().isAbstract() && acceptAbstractClasses == false))
283             {
284                 logger.debug("isDocletGenerated or isAbstract");
285                 continue;
286             }
287
288             if (typeName != null)
289             {
290                 if (TypeTagsHandler.isOfType(currentClass, typeName, extent))
291                 {
292                     if(DEBUG) {
293                         logger.debug("isOfType true, generate().");
294                         logger.debug("handling type: " + currentClass.getQualifiedName());
295                     }
296
297                     generate(template);
298                 }
299                 else if(DEBUG) logger.debug("isOfType false, generate().");
300             }
301             else
302             {
303                 if(DEBUG) logger.debug("typeName=null, generate().");
304                 generate(template);
305             }
306         }
307     }
308
309     /**
310      * @param template Describe what the parameter does
311      * @param attributes Describe what the parameter does
312      * @exception XDocletException Describe the exception
313      * @doc:tag type="block"
314      * @doc:tag name="tagName" optional="false" values="netui:jspfunction"
315      */

316     public void forAllMethods(String JavaDoc template, Properties JavaDoc attributes)
317         throws XDocletException {
318         String JavaDoc tagName = attributes.getProperty("tagName");
319
320         if(DEBUG)
321             logger.debug("Handling tagName: " + tagName);
322
323         setCurrentTagName(tagName);
324
325         try {
326             XClass currentClass = getCurrentClass();
327
328             if (currentClass == null)
329                 throw new XDocletException("currentClass == null!!!");
330
331             Collection JavaDoc members = currentClass.getMethods(true);
332
333             List JavaDoc sortedMembers = new ArrayList JavaDoc(members);
334             Collections.sort(sortedMembers, memberComparator);
335             members = sortedMembers;
336
337             Iterator JavaDoc methods = members.iterator();
338             while(methods.hasNext())
339             {
340                 XMethod xm = (XMethod)methods.next();
341
342                 if(DEBUG)
343                     logger.debug("handle method: " + xm.getName());
344
345                 XTag attribute = getFirstTag(getCurrentClass(), xm.getName(), tagName);
346
347                 setCurrentMethod(xm);
348                 setCurrentMethodTag(attribute);
349
350                 if(getCurrentMethod() != null && attribute != null)
351                     generate(template);
352
353                 setCurrentMethodTag(null);
354                 setCurrentClassTag(null);
355                 setCurrentMethod(null);
356             }
357             setCurrentClass(currentClass);
358         }
359         catch(Exception JavaDoc e) {
360             e.printStackTrace();
361             throw new XDocletException(e, "An error occurred in the forAllAttributes tag: " + e);
362         }
363     }
364
365     /**
366      * @param template Describe what the parameter does
367      * @param attributes Describe what the parameter does
368      * @exception XDocletException Describe the exception
369      * @doc:tag type="block"
370      * @doc:tag name="tagName" optional="false" values="netui.tldx:attribute,netui-tld:attribute"
371      * @doc:param name="superclasses" optional="true" values="true,false"
372      * description="If true then traverse superclasses also, otherwise look up the tag in current concrete class only."
373      */

374     public void forAllAttributes(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
375     {
376         String JavaDoc tagName = attributes.getProperty("tagName");
377         
378         if(DEBUG) logger.debug("Handling tagName: " + tagName);
379         //System.out.println("type: " + getCurrentClass().getQualifiedName());
380

381         setCurrentTagName(tagName);
382         
383         boolean genTldx = getCurrentTagName().equals(NETUI_TLDX_ATTRIBUTE);
384
385         try
386         {
387             XClass currentClass = getCurrentClass();
388             
389             if(DEBUG)
390             {
391                 logger.debug("handle class: " + currentClass.getName());
392                 XClass parent = currentClass.getSuperclass();
393                 while(parent != null)
394                 {
395                     logger.debug("superclass: " + parent.getName());
396                     if(parent.getName().equals("DataSourceTag"))
397                     {
398                         Iterator JavaDoc tmp = parent.getMethods().iterator();
399                         if(tmp.hasNext())
400                         {
401                             logger.debug("found methods on DataSourceTag");
402                             while(tmp.hasNext())
403                             {
404                                 logger.debug("method: " + tmp.next());
405                             }
406                         }
407                         else logger.debug("found NO methods on DataSourceTag");
408                     }
409                     
410                     parent = parent.getSuperclass();
411                 }
412             }
413
414             if (currentClass == null)
415                 throw new XDocletException("currentClass == null!!!");
416
417             // need to check all methods
418
Collection JavaDoc members = currentClass.getMethods(true);
419             
420             // sort fields, but we should make a copy first, because members is not a new copy, it's shared by all
421
List JavaDoc sortedMembers = new ArrayList JavaDoc(members);
422             Collections.sort(sortedMembers, memberComparator);
423             members = sortedMembers;
424             
425             // for all XMethods
426
Iterator JavaDoc methods = members.iterator();
427             while(methods.hasNext())
428             {
429                 XMethod xm = (XMethod)methods.next();
430                 
431                 if(DEBUG) logger.debug("handle method: " + xm.getName());
432                 
433                 // if(DEBUG) logger.debug("found @jsp:attribute tag on method: " + tldAttribute);
434

435                 // to create a TLD entry
436
// 1) @netui:attribute
437
// 2) @netui:attribute name="propName" -- use this for a class-level attribute when there can't be a method level one
438

439                 // to create a TLDX entry
440
// 0) @netui:attribute -- there are not TLDX properties, but the attribute still needs to be created
441
// 1) @netui.tldx:attribute -- specify TLDX properties
442
// 2) @netui.tldx:attribute name="propName" -- use this for a class-level attribute when there can't be a method level one
443

444                 // get all @netui:attribute annotated methods
445
XTag tldAttribute = getFirstTag(getCurrentClass(), xm.getName(), NETUI_ATTRIBUTE);
446
447                 //if(tldAttribute == null) continue;
448
//setCurrentMethod(xm);
449

450                 // @netui.tldx:attribute
451
if(tldAttribute != null)
452                 {
453                     if(genTldx)
454                     {
455                         // if the attribute has been omitted in the TLD, omit in the TLDX
456
//
457
// @todo: this needs to happen from the class-level
458
//
459
XTag classTldOverride = getOverrideClassTag(xm.getPropertyName(), NETUI_ATTRIBUTE, getCurrentClass());
460                         if(classTldOverride != null && TypeConversionUtil.stringToBoolean(classTldOverride.getAttributeValue("hide"), false))
461                             continue;
462
463                         // get the first @netui.tldx:attribute tag if it exists
464
XTag tldxAttribute = getFirstTag(getCurrentClass(), xm.getName(), NETUI_TLDX_ATTRIBUTE);
465                         
466                         // if(DEBUG) logger.debug("found @netui.tldx:attribute tag on method: " + tldxAttribute);
467

468                         if(tldxAttribute != null)
469                             setCurrentMethodTag(tldxAttribute);
470                     }
471                     // @netui-tld:attribute
472
else if(tldAttribute != null)
473                         setCurrentMethodTag(tldAttribute);
474                      
475                     XTag tag = getOverrideClassTag(xm.getPropertyName(), getCurrentTagName(), getCurrentClass());
476                     
477                     if(tag != null)
478                         setCurrentClassTag(tag);
479
480                     setCurrentMethod(xm);
481                 }
482                 else
483                 {
484 // System.out.println("***** search for class override: " + xm.getPropertyName());
485
// XTag tag = getOverrideClassTag(xm.getPropertyName(), getCurrentTagName(), getCurrentClass());
486
// System.out.println("method: " + xm.getName() + " found class override: " + tag);
487

488 // if(tag != null)
489
// {
490
// setCurrentMethod(xm);
491
// setCurrentClassTag(tag);
492
// }
493
}
494                     
495                 if(getCurrentMethod() != null)
496                 {
497                     if(getCurrentClassTag() == null ||
498                        !TypeConversionUtil.stringToBoolean(getCurrentClassTag().getAttributeValue("hide"), false))
499                     {
500                         generate(template);
501                     }
502                 }
503
504                 setCurrentMethodTag(null);
505                 setCurrentClassTag(null);
506                 setCurrentMethod(null);
507             }
508             setCurrentClass(currentClass);
509         }
510         catch(Exception JavaDoc e)
511         {
512             e.printStackTrace();
513             throw new XDocletException(e, "An error occurred in the forAllAttributes tag: " + e);
514         }
515     }
516
517     private XTag getOverrideClassTag(String JavaDoc name, String JavaDoc tagName, XClass currentClass)
518     {
519         // look for a class override for either netui:attribute or netui.tldx:attribute, depending on the current tagName
520
Iterator JavaDoc iterator = currentClass.getDoc().getTags(tagName, false).iterator();
521         while(iterator.hasNext())
522         {
523             XTag tag = (XTag)iterator.next();
524 // System.out.println("check class-level tag named " + tag.getName() + " with name attribute " + tag.getAttributeValue("name") + " searching for: " + name);
525

526             if(tag.getAttributeValue("name").equals(name))
527             {
528                 // if(DEBUG) logger.debug("setting class tag");
529
return tag;
530             }
531         }
532         
533         return null;
534     }
535
536     private XTag getFirstTag(XClass clazz, String JavaDoc methodName, String JavaDoc tagName)
537         throws XDocletException
538     {
539         List JavaDoc methods = clazz.getMethods(false);
540         
541         //if(DEBUG) logger.debug("getFirstTag from class: " + clazz.getName() + " with method " + methodName + " and tag " + tagName);
542

543         for(int i = 0; i < methods.size(); i++)
544         {
545             XMethod method = (XMethod)methods.get(i);
546             
547             //if(DEBUG) logger.debug("check method: " + method.getName());
548

549             if(method.getName().equals(methodName))
550             {
551                 Collection JavaDoc coll = method.getDoc().getTags(tagName, false);
552                 if(coll.size() == 1)
553                 {
554                     //if(DEBUG) logger.debug("found matching tag; return");
555
// return the matching XTag
556
return (XTag)coll.iterator().next();
557                 }
558                 else if(coll.size() == 0 && clazz.getSuperclass() != null)
559                 {
560                     //if(DEBUG) logger.debug("no tag found; check superclass");
561

562                     return getFirstTag(clazz.getSuperclass(), methodName, tagName);
563                 }
564                 else
565                 {
566                     throw new XDocletException("Found " + coll.size() + " tags for the class/method/tag " + clazz.getName() + "/" + methodName + "/" + tagName);
567                 }
568             }
569         }
570
571         if(clazz.getSuperclass() != null)
572         {
573             return getFirstTag(clazz.getSuperclass(), methodName, tagName);
574         }
575
576         return null;
577     }
578     
579     private void setCurrentTagName(String JavaDoc tagName)
580     {
581         currentTagName = tagName;
582     }
583     
584     private String JavaDoc getCurrentTagName()
585     {
586         return currentTagName;
587     }
588
589 // private static final void debug(String msg)
590
// {
591
// if(DEBUG)
592
// System.out.println(msg);
593
// }
594

595     private final static Comparator JavaDoc memberComparator =
596         new Comparator JavaDoc()
597         {
598             public int compare(Object JavaDoc o1, Object JavaDoc o2)
599             {
600                 XMember m1 = (XMember) o1;
601                 XMember m2 = (XMember) o2;
602
603                 return m1.getName().compareTo(m2.getName());
604             }
605
606             public boolean equals(Object JavaDoc obj)
607             {
608                 // dumb
609
return obj == this;
610             }
611         };
612
613     private Iterator JavaDoc sort(Iterator JavaDoc iterator)
614     {
615         List JavaDoc sorted = new ArrayList JavaDoc();
616         
617         while(iterator.hasNext())
618         {
619             XClass clazz = (XClass)iterator.next();
620             
621             sorted.add(clazz);
622         }
623
624         java.util.Collections.sort(sorted, new java.util.Comparator JavaDoc()
625             {
626                 public int compare(Object JavaDoc o1, Object JavaDoc o2)
627                 {
628                     return ((XClass)o1).getName().compareTo(((XClass)o2).getName());
629                 }
630                 
631                 public boolean equals(Object JavaDoc obj)
632                 {
633                     if(this == obj)
634                         return true;
635                     else return false;
636                 }
637             }
638                                    );
639         
640         return sorted.iterator();
641     }
642 }
643
Popular Tags