KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jxpath > JXPathIntrospector


1 /*
2  * Copyright 1999-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 package org.apache.commons.jxpath;
17
18 import java.util.Date JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.HashMap JavaDoc;
21
22 /**
23  * JXPathIntrospector maintains a registry of {@link JXPathBeanInfo
24  * JXPathBeanInfo} objects for Java classes.
25  *
26  * @author Dmitri Plotnikov
27  * @version $Revision: 1.10 $ $Date: 2004/05/08 15:10:05 $
28  */

29 public class JXPathIntrospector {
30
31     private static HashMap JavaDoc byClass = new HashMap JavaDoc();
32     private static HashMap JavaDoc byInterface = new HashMap JavaDoc();
33
34     static {
35         registerAtomicClass(Class JavaDoc.class);
36         registerAtomicClass(Boolean.TYPE);
37         registerAtomicClass(Boolean JavaDoc.class);
38         registerAtomicClass(Byte.TYPE);
39         registerAtomicClass(Byte JavaDoc.class);
40         registerAtomicClass(Character.TYPE);
41         registerAtomicClass(Character JavaDoc.class);
42         registerAtomicClass(Short.TYPE);
43         registerAtomicClass(Short JavaDoc.class);
44         registerAtomicClass(Integer.TYPE);
45         registerAtomicClass(Integer JavaDoc.class);
46         registerAtomicClass(Long.TYPE);
47         registerAtomicClass(Long JavaDoc.class);
48         registerAtomicClass(Float.TYPE);
49         registerAtomicClass(Float JavaDoc.class);
50         registerAtomicClass(Double.TYPE);
51         registerAtomicClass(Double JavaDoc.class);
52         registerAtomicClass(String JavaDoc.class);
53         registerAtomicClass(Date JavaDoc.class);
54         registerAtomicClass(java.sql.Date JavaDoc.class);
55         registerAtomicClass(java.sql.Time JavaDoc.class);
56         registerAtomicClass(java.sql.Timestamp JavaDoc.class);
57
58         registerDynamicClass(Map JavaDoc.class, MapDynamicPropertyHandler.class);
59     }
60
61     /**
62      * Automatically creates and registers a JXPathBeanInfo object
63      * for the specified class. That object returns true to isAtomic().
64      */

65     public static void registerAtomicClass(Class JavaDoc beanClass) {
66         byClass.put(beanClass, new JXPathBasicBeanInfo(beanClass, true));
67     }
68
69     /**
70      * Automatically creates and registers a JXPathBeanInfo object
71      * for the specified class. That object returns true to isDynamic().
72      */

73     public static void registerDynamicClass(
74         Class JavaDoc beanClass,
75         Class JavaDoc dynamicPropertyHandlerClass)
76     {
77         JXPathBasicBeanInfo bi =
78             new JXPathBasicBeanInfo(beanClass, dynamicPropertyHandlerClass);
79         if (beanClass.isInterface()) {
80             byInterface.put(beanClass, bi);
81         }
82         else {
83             byClass.put(beanClass, bi);
84         }
85     }
86
87     /**
88      * Creates and registers a JXPathBeanInfo object for the supplied class. If
89      * the class has already been registered, returns the registered
90      * JXPathBeanInfo object.
91      * <p>
92      * The process of creation of JXPathBeanInfo is as follows:
93      * <ul>
94      * <li>If class named <code>&lt;beanClass&gt;XBeanInfo</code> exists,
95      * an instance of that class is allocated.
96      * <li>Otherwise, an instance of {@link JXPathBasicBeanInfo
97      * JXPathBasicBeanInfo} is allocated.
98      * </ul>
99      */

100     public static JXPathBeanInfo getBeanInfo(Class JavaDoc beanClass) {
101         JXPathBeanInfo beanInfo = (JXPathBeanInfo) byClass.get(beanClass);
102         if (beanInfo == null) {
103             beanInfo = findDynamicBeanInfo(beanClass);
104             if (beanInfo == null) {
105                 beanInfo = findInformant(beanClass);
106                 if (beanInfo == null) {
107                     beanInfo = new JXPathBasicBeanInfo(beanClass);
108                 }
109             }
110             byClass.put(beanClass, beanInfo);
111         }
112         return beanInfo;
113     }
114
115     /**
116      * Find a dynamic bean info if available for any superclasses or
117      * interfaces.
118      */

119     private static JXPathBeanInfo findDynamicBeanInfo(Class JavaDoc beanClass) {
120         JXPathBeanInfo beanInfo = null;
121         if (beanClass.isInterface()) {
122             beanInfo = (JXPathBeanInfo) byInterface.get(beanClass);
123             if (beanInfo != null && beanInfo.isDynamic()) {
124                 return beanInfo;
125             }
126         }
127
128         Class JavaDoc interfaces[] = beanClass.getInterfaces();
129         if (interfaces != null) {
130             for (int i = 0; i < interfaces.length; i++) {
131                 beanInfo = findDynamicBeanInfo(interfaces[i]);
132                 if (beanInfo != null && beanInfo.isDynamic()) {
133                     return beanInfo;
134                 }
135             }
136         }
137
138         Class JavaDoc sup = beanClass.getSuperclass();
139         if (sup != null) {
140             beanInfo = (JXPathBeanInfo) byClass.get(sup);
141             if (beanInfo != null && beanInfo.isDynamic()) {
142                 return beanInfo;
143             }
144             return findDynamicBeanInfo(sup);
145         }
146         return null;
147     }
148
149     private static synchronized JXPathBeanInfo findInformant(Class JavaDoc beanClass) {
150         String JavaDoc name = beanClass.getName() + "XBeanInfo";
151         try {
152             return (JXPathBeanInfo) instantiate(beanClass, name);
153         }
154         catch (Exception JavaDoc ex) {
155             // Just drop through
156
}
157
158         // Now try checking if the bean is its own JXPathBeanInfo.
159
try {
160             if (JXPathBeanInfo.class.isAssignableFrom(beanClass)) {
161                 return (JXPathBeanInfo) beanClass.newInstance();
162             }
163         }
164         catch (Exception JavaDoc ex) {
165             // Just drop through
166
}
167
168         return null;
169     }
170
171     /**
172      * Try to create an instance of a named class.
173      * First try the classloader of "sibling", then try the system
174      * classloader.
175      */

176     private static Object JavaDoc instantiate(Class JavaDoc sibling, String JavaDoc className)
177         throws Exception JavaDoc
178     {
179
180         // First check with sibling's classloader (if any).
181
ClassLoader JavaDoc cl = sibling.getClassLoader();
182         if (cl != null) {
183             try {
184                 Class JavaDoc cls = cl.loadClass(className);
185                 return cls.newInstance();
186             }
187             catch (Exception JavaDoc ex) {
188                 // Just drop through and try the system classloader.
189
}
190         }
191
192         // Now try the bootstrap classloader.
193
Class JavaDoc cls = Class.forName(className);
194         return cls.newInstance();
195     }
196 }
Popular Tags