source: trunk/gcc/libjava/gnu/java/beans/IntrospectionIncubator.java@ 2446

Last change on this file since 2446 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 10.6 KB
Line 
1/* gnu.java.beans.IntrospectionIncubator
2 Copyright (C) 1998 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package gnu.java.beans;
40
41import java.beans.*;
42import java.util.*;
43import java.lang.reflect.*;
44import gnu.java.lang.*;
45
46/**
47 ** IntrospectionIncubator takes in a bunch of Methods, and
48 ** Introspects only those Methods you give it.
49 **
50 ** @author John Keiser
51 ** @version 1.1.0, 30 Jul 1998
52 ** @see gnu.java.beans.ExplicitBeanInfo
53 ** @see java.beans.BeanInfo
54 **/
55
56public class IntrospectionIncubator {
57 Hashtable propertyMethods = new Hashtable();
58 Hashtable listenerMethods = new Hashtable();
59 Vector otherMethods = new Vector();
60
61 Class propertyStopClass;
62 Class eventStopClass;
63 Class methodStopClass;
64
65 public IntrospectionIncubator() {
66 }
67
68 /* Paving the way for automatic Introspection */
69 public void addMethod(Method method) {
70 if(Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
71 String name = ClassHelper.getTruncatedName(method.getName());
72 Class retType = method.getReturnType();
73 Class[] params = method.getParameterTypes();
74 boolean isVoid = retType.equals(java.lang.Void.TYPE);
75 Class methodClass = method.getDeclaringClass();
76 if(propertyStopClass == null || (propertyStopClass.isAssignableFrom(methodClass) && !propertyStopClass.equals(methodClass))) {
77 if(name.startsWith("is")
78 && retType.equals(java.lang.Boolean.TYPE)
79 && params.length == 0) {
80 addToPropertyHash(name,method,IS);
81 } else if(name.startsWith("get") && !isVoid) {
82 if(params.length == 0) {
83 addToPropertyHash(name,method,GET);
84 } else if(params.length == 1 && params[0].equals(java.lang.Integer.TYPE)) {
85 addToPropertyHash(name,method,GET_I);
86 } else {
87 otherMethods.addElement(method);
88 }
89 } else if(name.startsWith("set") && isVoid) {
90 if(params.length == 1) {
91 addToPropertyHash(name,method,SET);
92 } else if(params.length == 2 && params[0].equals(java.lang.Integer.TYPE)) {
93 addToPropertyHash(name,method,SET_I);
94 } else {
95 otherMethods.addElement(method);
96 }
97 }
98 }
99 if(eventStopClass == null || (eventStopClass.isAssignableFrom(methodClass) && !eventStopClass.equals(methodClass))) {
100 if(name.startsWith("add")
101 && isVoid
102 && params.length == 1
103 && java.util.EventListener.class.isAssignableFrom(params[0])) {
104 addToListenerHash(name,method,ADD);
105 } else if(name.startsWith("remove")
106 && isVoid
107 && params.length == 1
108 && java.util.EventListener.class.isAssignableFrom(params[0])) {
109 addToListenerHash(name,method,REMOVE);
110 }
111 }
112 if(methodStopClass == null || (methodStopClass.isAssignableFrom(methodClass) && !methodStopClass.equals(methodClass))) {
113 otherMethods.addElement(method);
114 }
115 }
116 }
117
118 public void addMethods(Method[] m) {
119 for(int i=0;i<m.length;i++) {
120 addMethod(m[i]);
121 }
122 }
123
124 public void setPropertyStopClass(Class c) {
125 propertyStopClass = c;
126 }
127
128 public void setEventStopClass(Class c) {
129 eventStopClass = c;
130 }
131
132 public void setMethodStopClass(Class c) {
133 methodStopClass = c;
134 }
135
136
137 public BeanInfoEmbryo getBeanInfoEmbryo() throws IntrospectionException {
138 BeanInfoEmbryo b = new BeanInfoEmbryo();
139 findXXX(b,IS);
140 findXXXInt(b,GET_I);
141 findXXXInt(b,SET_I);
142 findXXX(b,GET);
143 findXXX(b,SET);
144 findAddRemovePairs(b);
145 for(int i=0;i<otherMethods.size();i++) {
146 MethodDescriptor newMethod = new MethodDescriptor((Method)otherMethods.elementAt(i));
147 if(!b.hasMethod(newMethod)) {
148 b.addMethod(new MethodDescriptor((Method)otherMethods.elementAt(i)));
149 }
150 }
151 return b;
152 }
153
154 public BeanInfo getBeanInfo() throws IntrospectionException {
155 return getBeanInfoEmbryo().getBeanInfo();
156 }
157
158
159 void findAddRemovePairs(BeanInfoEmbryo b) throws IntrospectionException {
160 Enumeration listenerEnum = listenerMethods.keys();
161 while(listenerEnum.hasMoreElements()) {
162 DoubleKey k = (DoubleKey)listenerEnum.nextElement();
163 Method[] m = (Method[])listenerMethods.get(k);
164 if(m[ADD] != null && m[REMOVE] != null) {
165 EventSetDescriptor e = new EventSetDescriptor(Introspector.decapitalize(k.getName()),
166 k.getType(), k.getType().getMethods(),
167 m[ADD],m[REMOVE]);
168 e.setUnicast(ArrayHelper.contains(m[ADD].getExceptionTypes(),java.util.TooManyListenersException.class));
169 if(!b.hasEvent(e)) {
170 b.addEvent(e);
171 }
172 }
173 }
174 }
175
176 void findXXX(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
177 Enumeration keys = propertyMethods.keys();
178 while(keys.hasMoreElements()) {
179 DoubleKey k = (DoubleKey)keys.nextElement();
180 Method[] m = (Method[])propertyMethods.get(k);
181 if(m[funcType] != null) {
182 PropertyDescriptor p = new PropertyDescriptor(Introspector.decapitalize(k.getName()),
183 m[IS] != null ? m[IS] : m[GET],
184 m[SET]);
185 if(m[SET] != null) {
186 p.setConstrained(ArrayHelper.contains(m[SET].getExceptionTypes(),java.beans.PropertyVetoException.class));
187 }
188 if(!b.hasProperty(p)) {
189 b.addProperty(p);
190 }
191 }
192 }
193 }
194
195 void findXXXInt(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
196 Enumeration keys = propertyMethods.keys();
197 while(keys.hasMoreElements()) {
198 DoubleKey k = (DoubleKey)keys.nextElement();
199 Method[] m = (Method[])propertyMethods.get(k);
200 if(m[funcType] != null) {
201 boolean constrained;
202 if(m[SET_I] != null) {
203 constrained = ArrayHelper.contains(m[SET_I].getExceptionTypes(),java.beans.PropertyVetoException.class);
204 } else {
205 constrained = false;
206 }
207
208 /** Find out if there is an array type get or set **/
209 Class arrayType = Array.newInstance(k.getType(),0).getClass();
210 DoubleKey findSetArray = new DoubleKey(arrayType,k.getName());
211 Method[] m2 = (Method[])propertyMethods.get(findSetArray);
212 IndexedPropertyDescriptor p;
213 if(m2 == null) {
214 p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
215 null,null,
216 m[GET_I],m[SET_I]);
217 } else {
218 if(constrained && m2[SET] != null) {
219 constrained = ArrayHelper.contains(m2[SET].getExceptionTypes(),java.beans.PropertyVetoException.class);
220 }
221 p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
222 m2[GET],m2[SET],
223 m[GET_I],m[SET_I]);
224 }
225 p.setConstrained(constrained);
226 if(!b.hasProperty(p)) {
227 b.addProperty(p);
228 }
229 }
230 }
231 }
232
233 static final int IS=0;
234 static final int GET_I=1;
235 static final int SET_I=2;
236 static final int GET=3;
237 static final int SET=4;
238
239 static final int ADD=0;
240 static final int REMOVE=1;
241
242 void addToPropertyHash(String name, Method method, int funcType) {
243 String newName;
244 Class type;
245
246 switch(funcType) {
247 case IS:
248 type = java.lang.Boolean.TYPE;
249 newName = name.substring(2);
250 break;
251 case GET_I:
252 type = method.getReturnType();
253 newName = name.substring(3);
254 break;
255 case SET_I:
256 type = method.getParameterTypes()[1];
257 newName = name.substring(3);
258 break;
259 case GET:
260 type = method.getReturnType();
261 newName = name.substring(3);
262 break;
263 case SET:
264 type = method.getParameterTypes()[0];
265 newName = name.substring(3);
266 break;
267 default:
268 return;
269 }
270 newName = capitalize(newName);
271
272 DoubleKey k = new DoubleKey(type,newName);
273 Method[] methods = (Method[])propertyMethods.get(k);
274 if(methods == null) {
275 methods = new Method[5];
276 propertyMethods.put(k,methods);
277 }
278 methods[funcType] = method;
279 }
280
281
282 void addToListenerHash(String name, Method method, int funcType) {
283 String newName;
284 Class type;
285
286 switch(funcType) {
287 case ADD:
288 type = method.getParameterTypes()[0];
289 newName = name.substring(3,name.length()-8);
290 break;
291 case REMOVE:
292 type = method.getParameterTypes()[0];
293 newName = name.substring(6,name.length()-8);
294 break;
295 default:
296 return;
297 }
298 newName = capitalize(newName);
299
300 DoubleKey k = new DoubleKey(type,newName);
301 Method[] methods = (Method[])listenerMethods.get(k);
302 if(methods == null) {
303 methods = new Method[2];
304 listenerMethods.put(k,methods);
305 }
306 methods[funcType] = method;
307 }
308
309 static String capitalize(String name) {
310 try {
311 if(Character.isUpperCase(name.charAt(0))) {
312 return name;
313 } else {
314 char[] c = name.toCharArray();
315 c[0] = Character.toLowerCase(c[0]);
316 return new String(c);
317 }
318 } catch(StringIndexOutOfBoundsException E) {
319 return name;
320 } catch(NullPointerException E) {
321 return null;
322 }
323 }
324}
325
326class DoubleKey {
327 Class type;
328 String name;
329
330 DoubleKey(Class type, String name) {
331 this.type = type;
332 this.name = name;
333 }
334
335 Class getType() {
336 return type;
337 }
338
339 String getName() {
340 return name;
341 }
342
343 public boolean equals(Object o) {
344 if(o instanceof DoubleKey) {
345 DoubleKey d = (DoubleKey)o;
346 return d.type.equals(type) && d.name.equals(name);
347 } else {
348 return false;
349 }
350 }
351
352 public int hashCode() {
353 return type.hashCode() ^ name.hashCode();
354 }
355}
Note: See TracBrowser for help on using the repository browser.