KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > tests > org > enhydra > xml > xhtml > dominfo > DOMInfo


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: DOMInfo.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
22  */

23
24 package tests.org.enhydra.xml.xhtml.dominfo;
25
26 import java.io.IOException JavaDoc;
27 import java.io.PrintWriter JavaDoc;
28 import java.lang.reflect.Method JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Set JavaDoc;
33 import java.util.TreeMap JavaDoc;
34
35 import org.enhydra.error.FatalExceptionError;
36
37 /**
38  * Class to collection information about the objects that compose an
39  * set of DOM interfaces or implementations.
40  */

41 class DOMInfo {
42     /*
43      * A property of an Element class. This is defined by get and set methods.
44      */

45     public class ElementProperty {
46         /** The property name */
47         private String JavaDoc fName;
48
49         /** Lower-case version of the name */
50         private String JavaDoc fNameLower;
51
52         /** Accessor */
53         private Method JavaDoc fAccessor;
54
55         /** Mutator */
56         private Method JavaDoc fMutator;
57         
58         /** Construct a new property */
59         ElementProperty(String JavaDoc name) {
60             fName = name;
61             fNameLower = name.toLowerCase();
62         }
63
64         /**
65          * Add an accessor/mutator method.
66          */

67         void addAccessor(Method JavaDoc method) {
68             if (method.getName().startsWith("get")) {
69                 fAccessor = method;
70             } else {
71                 fMutator = method;
72             }
73         }
74
75         /** Get the property name */
76         public String JavaDoc getName() {
77             return fName;
78         }
79
80         /** Get the lower-case property name */
81         public String JavaDoc getNameLower() {
82             return fNameLower;
83         }
84
85         /** Get the attribute name the property represents. */
86         public String JavaDoc getAttrName() {
87             return fNameLower;
88         }
89
90         /** Get the accessor method */
91         public Method JavaDoc getAccessor() {
92             return fAccessor;
93         }
94         
95         /** get the mutator method */
96         public Method JavaDoc getMutator() {
97             return fMutator;
98         }
99
100         /* Dump the class */
101         public void dump(PrintWriter JavaDoc out,
102                          int level) {
103             PrintUtils.printIndent(out, level);
104             out.println(fName + ": " +
105                         ((fAccessor == null) ? "null" : fAccessor.getName())
106                         + "/" +
107                         ((fMutator == null) ? "null" : fMutator.getName()));
108         }
109     }
110
111     /**
112      * Information about a class or interface.
113      */

114     public class ElementClass {
115         /** The Class object for the Element class or interface */
116         private Class JavaDoc fClassObj;
117
118         /**
119          * Interfaces this implements. If this class is an interface,
120          * then this is the interface it extends.
121          */

122         private Map JavaDoc fImplements = new TreeMap JavaDoc();
123  
124         /**
125          * List of properties. A property is someting with a get* and/or
126          * set* method. This includes methods that are inherrited. Key
127          * is the lower-case name.
128          */

129         private Map JavaDoc fProperties = new TreeMap JavaDoc();
130
131         /** Process a get/set method */
132         private void processPropertyMethod(Method JavaDoc method) {
133             String JavaDoc name = method.getName().substring(3);
134             String JavaDoc nameLower = name.toLowerCase();
135             ElementProperty prop = (ElementProperty)fProperties.get(nameLower);
136             if (prop == null) {
137                 prop = new ElementProperty(name);
138                 fProperties.put(prop.getNameLower(), prop);
139             }
140             prop.addAccessor(method);
141         }
142         
143         /** Record information about a method */
144         private void processMethod(Method JavaDoc method) {
145             if (isPropertyMethod(method)) {
146                 processPropertyMethod(method);
147             }
148         }
149
150         /** Find the properties */
151         private void findProperties() {
152             Method JavaDoc[] methods = fClassObj.getMethods();
153             for (int idx = 0; idx < methods.length; idx++) {
154                 processMethod(methods[idx]);
155             }
156         }
157
158         /**
159          * Process a class to determine if it should be added to
160          * the implements list. Recursively search its interfaces and
161          * super class.
162          */

163         private void processImplements(Class JavaDoc classObj) {
164             if (classObj.isInterface() && !fImplements.containsKey(classObj.getName())) {
165                 fImplements.put(classObj.getName(), classObj);
166                 findImplements(classObj);
167             }
168         }
169
170         /**
171          * Construct a list of implemented interfaces, walking the
172          * inheritance heierarchy to find all interfaces.
173          */

174         private void findImplements(Class JavaDoc classObj) {
175             Class JavaDoc[] ifaces = classObj.getInterfaces();
176             for (int idx = 0; idx < ifaces.length; idx++) {
177                 if (!fImplements.containsKey(ifaces[idx].getName())) {
178                     fImplements.put(ifaces[idx].getName(), ifaces[idx]);
179                     findImplements(ifaces[idx]);
180                 }
181             }
182             Class JavaDoc superObj = classObj.getSuperclass();
183             if (superObj != null) {
184                 processImplements(superObj);
185             }
186         }
187
188         /** Constructor */
189         public ElementClass(Class JavaDoc classObj) {
190             fClassObj = classObj;
191             findProperties();
192             findImplements(fClassObj);
193         }
194
195         /** Get the class name */
196         public String JavaDoc getName() {
197             return fClassObj.getName();
198         }
199
200         /* Get the lower-case property names */
201         public Set JavaDoc getPropertyNames() {
202             return fProperties.keySet();
203         }
204
205         /* Get an property */
206         public ElementProperty getProperty(String JavaDoc name) {
207             ElementProperty prop = (ElementProperty)fProperties.get(name.toLowerCase());
208             if (prop == null) {
209                 throw new Error JavaDoc("Can't find property \"" + name + "\" of element \"" + getName() + "\"");
210             }
211             return prop;
212         }
213
214         /* Get the implemented interface names */
215         public Set JavaDoc getImplementsNames() {
216             return fImplements.keySet();
217         }
218
219         /* Dump the class */
220         public void dump(PrintWriter JavaDoc out,
221                          int level) {
222             PrintUtils.printIndent(out, level);
223             out.println(getName());
224
225             PrintUtils.printIndent(out, level+1);
226             out.println("Implements:");
227             Iterator JavaDoc impls = getImplementsNames().iterator();
228             while (impls.hasNext()) {
229                 PrintUtils.printIndent(out, level+2);
230                 out.println((String JavaDoc)impls.next());
231             }
232
233             PrintUtils.printIndent(out, level+1);
234             out.println("Properties:");
235             Iterator JavaDoc propNames = getPropertyNames().iterator();
236             while (propNames.hasNext()) {
237                 getProperty((String JavaDoc)propNames.next()).dump(out, level+2);
238             }
239         }
240
241         /** Get a string representation */
242         public String JavaDoc toString() {
243             return fClassObj.getName();
244         }
245     }
246
247     /** Element names to drop (lower-cased) */
248     private Set JavaDoc fDropElementNames = new HashSet JavaDoc();
249
250     /** Methods to ignore when getting properties. */
251     private Set JavaDoc fDropPropertyMethodNames = new HashSet JavaDoc();
252
253     /** The elements in the DOM */
254     private Map JavaDoc fElements = new TreeMap JavaDoc();
255
256     /** Should an element be dropped */
257     private boolean dropElementClass(String JavaDoc className) {
258         return fDropElementNames.contains(className.toLowerCase());
259     }
260
261     /** Is this a property method (get* or set* and not in drop list) */
262     private boolean isPropertyMethod(Method JavaDoc method) {
263         String JavaDoc name = method.getName();
264         return ((name.startsWith("get") || name.startsWith("set")) && !fDropPropertyMethodNames.contains(name));
265     }
266
267     /** Add method to the drop property list */
268     private void addDropPropertyMethod(String JavaDoc name) {
269         fDropPropertyMethodNames.add(name);
270     }
271     
272     /** Add the property-like methods in a class to a list of ones to ignore */
273     private void addDropPropertyMethods(Class JavaDoc classObj) {
274         Method JavaDoc[] methods = classObj.getMethods();
275         for (int idx = 0; idx < methods.length; idx++) {
276             if (isPropertyMethod(methods[idx])) {
277                 fDropPropertyMethodNames.add(methods[idx].getName());
278             }
279         }
280     }
281
282     /* Constructor */
283     public DOMInfo() {
284         addDropPropertyMethods(org.w3c.dom.Element JavaDoc.class);
285         addDropPropertyMethods(org.enhydra.apache.xerces.dom.ElementImpl.class);
286         addDropPropertyMethods(org.enhydra.apache.xerces.dom.ElementNSImpl.class);
287     }
288
289
290     /* Constructor with package */
291     public DOMInfo(String JavaDoc pkgName) {
292         this();
293         addElementsFromClassPath(pkgName);
294     }
295
296     /* Get the element names */
297     public Set JavaDoc getElementNames() {
298         return fElements.keySet();
299     }
300
301     /* Get an element */
302     public ElementClass getElement(String JavaDoc name) {
303         ElementClass element = (ElementClass)fElements.get(name);
304         if (element == null) {
305             throw new Error JavaDoc("Can't find element \"" + name + "\"");
306         }
307         return element;
308     }
309
310     /* Get the set of ElementClass objects */
311     public Set JavaDoc getElementClassSet() {
312         HashSet JavaDoc set = new HashSet JavaDoc();
313
314         Iterator JavaDoc elementNames = getElementNames().iterator();
315         while (elementNames.hasNext()) {
316             set.add(getElement((String JavaDoc)elementNames.next()));
317         }
318         return set;
319     }
320
321     /* Add an element */
322     private void addElement(ElementClass element) {
323         if (fElements.containsKey(element.getName())) {
324             throw new Error JavaDoc("Element class info already exists: " + element.getName());
325         }
326         fElements.put(element.getName(), element);
327     }
328
329     /** Add an element given its class */
330     public void addElement(Class JavaDoc element) {
331         addElement(new ElementClass(element));
332     }
333
334     /** Drop a suffix from a name */
335     private String JavaDoc dropSuffix(String JavaDoc suffix,
336                               String JavaDoc name) {
337         if (name.regionMatches(name.length()-suffix.length(), suffix, 0, suffix.length())) {
338             name = name.substring(0, name.length()-suffix.length());
339         }
340         return name;
341     }
342
343     /** Clean up a unqualifiied class name (making unqualified if necessary) */
344     private String JavaDoc cleanUnqualClassName(String JavaDoc name) {
345         // Delete .class and .java suffixs, if they exist
346
name = dropSuffix(".class", name);
347         name = dropSuffix(".java", name);
348
349         // Delete package qualification
350
int idx = name.lastIndexOf('.');
351         if (idx >= 0) {
352             name = name.substring(idx+1);
353         }
354         return name;
355     }
356     
357
358     /** Load an element class and add */
359     public void addElement(String JavaDoc className) {
360         try {
361             addElement(Class.forName(className));
362         } catch (ClassNotFoundException JavaDoc except) {
363             throw new FatalExceptionError(except);
364         }
365     }
366
367     /** Load an element class and add */
368     public void addElement(String JavaDoc pkgName,
369                            String JavaDoc unqualClassName) {
370         String JavaDoc className = pkgName + "." + cleanUnqualClassName(unqualClassName);
371         try {
372             addElement(Class.forName(className));
373         } catch (ClassNotFoundException JavaDoc except) {
374             throw new FatalExceptionError(except);
375         }
376     }
377
378     /** Load a list of class in a package */
379     public void addElements(String JavaDoc pkgName,
380                             String JavaDoc[] unqualClassNames) {
381         for (int idx = 0; idx < unqualClassNames.length; idx++) {
382             addElement(pkgName, unqualClassNames[idx]);
383         }
384     }
385
386     /**
387      * Load a list of class in a package by searching the CLASSPATH
388      * for the specified package.
389      */

390     public void addElementsFromClassPath(String JavaDoc pkgName) {
391         String JavaDoc[] classes = ElementClassMappings.getPackageElementClasses(pkgName);
392         for (int idx = 0; idx < classes.length; idx++) {
393             addElement(classes[idx]);
394         }
395     }
396
397     /**
398      * Dump the elements in the DOM.
399      */

400     public void dump(PrintWriter JavaDoc out) {
401           Iterator JavaDoc elementNames = getElementNames().iterator();
402           while (elementNames.hasNext()) {
403               getElement((String JavaDoc)elementNames.next()).dump(out, 0);
404           }
405     }
406
407     /**
408      * Main used for testing.
409      */

410     public static void main(String JavaDoc[] args) throws IOException JavaDoc {
411         if (args.length < 1) {
412             System.err.println("Wrong # args: DOMInfo package [classFile1 classFile2 ...]]");
413             System.exit(1);
414         }
415         DOMInfo domInfo = new DOMInfo();
416
417         if (args.length == 1) {
418             domInfo.addElementsFromClassPath(args[0]);
419         } else {
420             for (int idx = 1; idx < args.length; idx++) {
421                 domInfo.addElement(args[0], args[idx]);
422             }
423         }
424         domInfo.dump(new PrintWriter JavaDoc(System.out, true));
425     }
426 }
427
Popular Tags