001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.gbean;
017:
018: import java.beans.Introspector;
019: import java.lang.reflect.Constructor;
020: import java.lang.reflect.Method;
021: import java.util.Collection;
022: import java.util.HashMap;
023: import java.util.HashSet;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Set;
028: import java.util.Arrays;
029:
030: import org.apache.geronimo.kernel.ClassLoading;
031: import org.apache.geronimo.kernel.Kernel;
032:
033: /**
034: * @version $Rev: 558235 $ $Date: 2007-07-20 20:47:45 -0700 (Fri, 20 Jul 2007) $
035: */
036: public class GBeanInfoBuilder {
037: public static GBeanInfoBuilder createStatic(Class gbeanType) {
038: if (gbeanType == null)
039: throw new NullPointerException("gbeanType is null");
040: return createStatic(gbeanType, gbeanType.getName(), gbeanType,
041: null, null);
042: }
043:
044: public static GBeanInfoBuilder createStatic(Class gbeanType,
045: String j2eeType) {
046: if (gbeanType == null)
047: throw new NullPointerException("gbeanType is null");
048: return createStatic(gbeanType, gbeanType.getName(), gbeanType,
049: null, j2eeType);
050: }
051:
052: public static GBeanInfoBuilder createStatic(String name,
053: Class gbeanType) {
054: if (gbeanType == null)
055: throw new NullPointerException("gbeanType is null");
056: return createStatic(gbeanType, name, gbeanType, null, null);
057: }
058:
059: public static GBeanInfoBuilder createStatic(String name,
060: Class gbeanType, String j2eeType) {
061: if (gbeanType == null)
062: throw new NullPointerException("gbeanType is null");
063: return createStatic(gbeanType, name, gbeanType, null, j2eeType);
064: }
065:
066: public static GBeanInfoBuilder createStatic(Class gbeanType,
067: GBeanInfo source) {
068: if (gbeanType == null)
069: throw new NullPointerException("gbeanType is null");
070: return createStatic(gbeanType, gbeanType.getName(), gbeanType,
071: source, null);
072: }
073:
074: public static GBeanInfoBuilder createStatic(Class gbeanType,
075: GBeanInfo source, String j2eeType) {
076: if (gbeanType == null)
077: throw new NullPointerException("gbeanType is null");
078: return createStatic(gbeanType, gbeanType.getName(), gbeanType,
079: source, j2eeType);
080: }
081:
082: public static GBeanInfoBuilder createStatic(String name,
083: Class gbeanType, GBeanInfo source) {
084: if (name == null)
085: throw new NullPointerException("name is null");
086: if (gbeanType == null)
087: throw new NullPointerException("gbeanType is null");
088: return createStatic(gbeanType, name, gbeanType, source, null);
089: }
090:
091: //
092: // These methods are used by classes that declare a GBeanInfo for another class
093: //
094: public static GBeanInfoBuilder createStatic(Class sourceClass,
095: Class gbeanType) {
096: if (gbeanType == null)
097: throw new NullPointerException("gbeanType is null");
098: return createStatic(sourceClass, gbeanType.getName(),
099: gbeanType, null, null);
100: }
101:
102: public static GBeanInfoBuilder createStatic(Class sourceClass,
103: Class gbeanType, String j2eeType) {
104: if (sourceClass == null)
105: throw new NullPointerException("sourceClass is null");
106: if (gbeanType == null)
107: throw new NullPointerException("gbeanType is null");
108: return createStatic(sourceClass, gbeanType.getName(),
109: gbeanType, null, j2eeType);
110: }
111:
112: public static GBeanInfoBuilder createStatic(Class sourceClass,
113: Class gbeanType, GBeanInfo source, String j2eeType) {
114: if (sourceClass == null)
115: throw new NullPointerException("sourceClass is null");
116: if (gbeanType == null)
117: throw new NullPointerException("gbeanType is null");
118: return createStatic(sourceClass, gbeanType.getName(),
119: gbeanType, source, j2eeType);
120: }
121:
122: public static GBeanInfoBuilder createStatic(Class sourceClass,
123: String name, Class gbeanType, String j2eeType) {
124: if (sourceClass == null)
125: throw new NullPointerException("sourceClass is null");
126: if (name == null)
127: throw new NullPointerException("name is null");
128: if (gbeanType == null)
129: throw new NullPointerException("gbeanType is null");
130: return createStatic(sourceClass, name, gbeanType, null,
131: j2eeType);
132: }
133:
134: public static GBeanInfoBuilder createStatic(Class sourceClass,
135: String name, Class gbeanType, GBeanInfo source,
136: String j2eeType) {
137: if (sourceClass == null)
138: throw new NullPointerException("sourceClass is null");
139: if (name == null)
140: throw new NullPointerException("name is null");
141: if (gbeanType == null)
142: throw new NullPointerException("gbeanType is null");
143: return new GBeanInfoBuilder(sourceClass.getName(), name,
144: gbeanType, source, j2eeType);
145: }
146:
147: public static final String DEFAULT_J2EE_TYPE = "GBean"; //NameFactory.GERONIMO_SERVICE
148:
149: private static final Class[] NO_ARGS = {};
150:
151: /**
152: * The class from which the info can be retrieved using GBeanInfo.getGBeanInfo(className, classLoader)
153: */
154: private final String sourceClass;
155:
156: private final String name;
157:
158: private final String j2eeType;
159:
160: private final Class gbeanType;
161:
162: private final Map attributes = new HashMap();
163:
164: private GConstructorInfo constructor = new GConstructorInfo();
165:
166: private final Map operations = new HashMap();
167:
168: private final Map references = new HashMap();
169:
170: private final Set interfaces = new HashSet();
171:
172: private int priority = GBeanInfo.PRIORITY_NORMAL;
173:
174: public GBeanInfoBuilder(Class gbeanType) {
175: this (checkNotNull(gbeanType).getName(), gbeanType, null, null);
176: }
177:
178: public GBeanInfoBuilder(Class gbeanType, String j2eeType) {
179: this (checkNotNull(gbeanType).getName(), gbeanType, null,
180: j2eeType);
181: }
182:
183: public GBeanInfoBuilder(String name, Class gbeanType) {
184: this (name, checkNotNull(gbeanType), null, null);
185: }
186:
187: public GBeanInfoBuilder(String name, Class gbeanType,
188: String j2eeType) {
189: this (name, checkNotNull(gbeanType), null, j2eeType);
190: }
191:
192: public GBeanInfoBuilder(Class gbeanType, GBeanInfo source) {
193: this (checkNotNull(gbeanType).getName(), gbeanType, source);
194: }
195:
196: public GBeanInfoBuilder(Class gbeanType, GBeanInfo source,
197: String j2eeType) {
198: this (checkNotNull(gbeanType).getName(), gbeanType, source,
199: j2eeType);
200: }
201:
202: //TODO remove this
203: /**
204: * @deprecated This will be removed in a future release
205: */
206: public GBeanInfoBuilder(String name, ClassLoader classLoader) {
207: this (checkNotNull(name), loadClass(classLoader, name),
208: GBeanInfo.getGBeanInfo(name, classLoader));
209: }
210:
211: public GBeanInfoBuilder(String name, Class gbeanType,
212: GBeanInfo source) {
213: this (name, gbeanType, source, null);
214: }
215:
216: public GBeanInfoBuilder(String name, Class gbeanType,
217: GBeanInfo source, String j2eeType) {
218: this (null, name, gbeanType, source, j2eeType);
219: }
220:
221: private GBeanInfoBuilder(String sourceClass, String name,
222: Class gbeanType, GBeanInfo source, String j2eeType) {
223: checkNotNull(name);
224: checkNotNull(gbeanType);
225: this .name = name;
226: this .gbeanType = gbeanType;
227: this .sourceClass = sourceClass;
228:
229: if (source != null) {
230: for (Iterator i = source.getAttributes().iterator(); i
231: .hasNext();) {
232: GAttributeInfo attributeInfo = (GAttributeInfo) i
233: .next();
234: attributes.put(attributeInfo.getName(), attributeInfo);
235: }
236:
237: for (Iterator i = source.getOperations().iterator(); i
238: .hasNext();) {
239: GOperationInfo operationInfo = (GOperationInfo) i
240: .next();
241: operations.put(new GOperationSignature(operationInfo
242: .getName(), operationInfo.getParameterList()),
243: operationInfo);
244: }
245:
246: for (Iterator iterator = source.getReferences().iterator(); iterator
247: .hasNext();) {
248: GReferenceInfo referenceInfo = (GReferenceInfo) iterator
249: .next();
250: references.put(referenceInfo.getName(), new RefInfo(
251: referenceInfo.getReferenceType(), referenceInfo
252: .getNameTypeName()));
253: }
254:
255: for (Iterator iterator = source.getInterfaces().iterator(); iterator
256: .hasNext();) {
257: String intf = (String) iterator.next();
258: interfaces.add(intf);
259: }
260:
261: //in case subclass constructor has same parameters as superclass.
262: constructor = source.getConstructor();
263:
264: priority = source.getPriority();
265: }
266: if (j2eeType != null) {
267: this .j2eeType = j2eeType;
268: } else if (source != null) {
269: this .j2eeType = source.getJ2eeType();
270: } else {
271: this .j2eeType = DEFAULT_J2EE_TYPE; //NameFactory.GERONIMO_SERVICE
272: }
273:
274: // add all interfaces based on GBean type
275: if (gbeanType.isArray()) {
276: throw new IllegalArgumentException(
277: "GBean is an array type: gbeanType="
278: + gbeanType.getName());
279: }
280: Set allTypes = ClassLoading.getAllTypes(gbeanType);
281: for (Iterator iterator = allTypes.iterator(); iterator
282: .hasNext();) {
283: Class type = (Class) iterator.next();
284: addInterface(type);
285: }
286: }
287:
288: public void setPersistentAttributes(String[] persistentAttributes) {
289: for (int i = 0; i < persistentAttributes.length; i++) {
290: String attributeName = persistentAttributes[i];
291: GAttributeInfo attribute = (GAttributeInfo) attributes
292: .get(attributeName);
293: if (attribute != null
294: && !references.containsKey(attributeName)) {
295: if (isMagicAttribute(attribute)) {
296: // magic attributes can't be persistent
297: continue;
298: }
299: attributes.put(attributeName, new GAttributeInfo(
300: attributeName, attribute.getType(), true,
301: attribute.isManageable(), attribute
302: .getGetterName(), attribute
303: .getSetterName()));
304: } else {
305: if (attributeName.equals("kernel")) {
306: addAttribute("kernel", Kernel.class, false);
307: } else if (attributeName.equals("classLoader")) {
308: addAttribute("classLoader", ClassLoader.class,
309: false);
310: } else if (attributeName.equals("abstractName")) {
311: addAttribute("abstractName", AbstractName.class,
312: false);
313: } else if (attributeName.equals("objectName")) {
314: addAttribute("obectName", String.class, false);
315: }
316: }
317: }
318: }
319:
320: public void setManageableAttributes(String[] manageableAttributes) {
321: for (int i = 0; i < manageableAttributes.length; i++) {
322: String attributeName = manageableAttributes[i];
323: GAttributeInfo attribute = (GAttributeInfo) attributes
324: .get(attributeName);
325: if (attribute != null) {
326: attributes.put(attributeName, new GAttributeInfo(
327: attributeName, attribute.getType(), attribute
328: .isPersistent(), true, attribute
329: .getGetterName(), attribute
330: .getSetterName()));
331: }
332: }
333: }
334:
335: private boolean isMagicAttribute(GAttributeInfo attributeInfo) {
336: String name = attributeInfo.getName();
337: String type = attributeInfo.getType();
338: return ("kernel".equals(name) && Kernel.class.getName().equals(
339: type))
340: || ("classLoader".equals(name) && ClassLoader.class
341: .getName().equals(type))
342: || ("abstractName".equals(name) && AbstractName.class
343: .getName().equals(type))
344: || ("objectName".equals(name) && String.class.getName()
345: .equals(type));
346: }
347:
348: public void addInterface(Class intf) {
349: addInterface(intf, new String[0]);
350: }
351:
352: //do not use beaninfo Introspector to list the properties. This method is primarily for interfaces,
353: //and it does not process superinterfaces. It seems to really only work well for classes.
354: public void addInterface(Class intf, String[] persistentAttributes) {
355: addInterface(intf, persistentAttributes, new String[0]);
356: }
357:
358: public void addInterface(Class intf, String[] persistentAttributes,
359: String[] manageableAttributes) {
360: Set persistentNames = new HashSet(Arrays
361: .asList(persistentAttributes));
362: Set manageableNames = new HashSet(Arrays
363: .asList(manageableAttributes));
364: Method[] methods = intf.getMethods();
365: for (int i = 0; i < methods.length; i++) {
366: Method method = methods[i];
367: if ("java.lang.Object".equals(method.getDeclaringClass()
368: .getName()))
369: continue;
370: if (isGetter(method)) {
371: String attributeName = getAttributeName(method);
372: GAttributeInfo attribute = (GAttributeInfo) attributes
373: .get(attributeName);
374: String attributeType = method.getReturnType().getName();
375: if (attribute == null) {
376: attributes.put(attributeName, new GAttributeInfo(
377: attributeName, attributeType,
378: persistentNames.contains(attributeName),
379: manageableNames.contains(attributeName),
380: method.getName(), null));
381: } else {
382: if (!attributeType.equals(attribute.getType())) {
383: throw new IllegalArgumentException(
384: "Getter and setter type do not match: "
385: + attributeName
386: + " for gbeanType: "
387: + gbeanType.getName());
388: }
389: attributes
390: .put(
391: attributeName,
392: new GAttributeInfo(
393: attributeName,
394: attributeType,
395: attribute.isPersistent()
396: || persistentNames
397: .contains(attributeName),
398: attribute.isManageable()
399: || manageableNames
400: .contains(attributeName),
401: method.getName(), attribute
402: .getSetterName()));
403: }
404: } else if (isSetter(method)) {
405: String attributeName = getAttributeName(method);
406: String attributeType = method.getParameterTypes()[0]
407: .getName();
408: GAttributeInfo attribute = (GAttributeInfo) attributes
409: .get(attributeName);
410: if (attribute == null) {
411: attributes.put(attributeName, new GAttributeInfo(
412: attributeName, attributeType,
413: persistentNames.contains(attributeName),
414: manageableNames.contains(attributeName),
415: null, method.getName()));
416: } else {
417: if (!attributeType.equals(attribute.getType())) {
418: throw new IllegalArgumentException(
419: "Getter and setter type do not match: "
420: + attributeName
421: + " for gbeanType: "
422: + gbeanType.getName());
423: }
424: attributes
425: .put(
426: attributeName,
427: new GAttributeInfo(
428: attributeName,
429: attributeType,
430: attribute.isPersistent()
431: || persistentNames
432: .contains(attributeName),
433: attribute.isManageable()
434: || manageableNames
435: .contains(attributeName),
436: attribute.getGetterName(),
437: method.getName()));
438: }
439: } else {
440: addOperation(new GOperationInfo(method.getName(),
441: method.getParameterTypes(), method
442: .getReturnType().getName()));
443: }
444: }
445: addInterface(interfaces, intf);
446: }
447:
448: private static void addInterface(Set set, Class intf) {
449: String name = intf.getName();
450: if (set.contains(name)) {
451: return;
452: }
453: set.add(name);
454: Class cls[] = intf.getInterfaces();
455: for (int i = 0; i < cls.length; i++) {
456: addInterface(set, cls[i]);
457: }
458: }
459:
460: public void addAttribute(String name, Class type, boolean persistent) {
461: addAttribute(name, type.getName(), persistent, true);
462: }
463:
464: public void addAttribute(String name, String type,
465: boolean persistent) {
466: addAttribute(name, type, persistent, true);
467: }
468:
469: public void addAttribute(String name, Class type,
470: boolean persistent, boolean manageable) {
471: addAttribute(name, type.getName(), persistent, manageable);
472: }
473:
474: public void addAttribute(String name, String type,
475: boolean persistent, boolean manageable) {
476: String getter = searchForGetter(name, type, gbeanType);
477: String setter = searchForSetter(name, type, gbeanType);
478: addAttribute(new GAttributeInfo(name, type, persistent,
479: manageable, getter, setter));
480: }
481:
482: public void addAttribute(GAttributeInfo info) {
483: attributes.put(info.getName(), info);
484: }
485:
486: public void setConstructor(GConstructorInfo constructor) {
487: assert constructor != null;
488: this .constructor = constructor;
489: List names = constructor.getAttributeNames();
490: setPersistentAttributes((String[]) names
491: .toArray(new String[names.size()]));
492: }
493:
494: public void setConstructor(String[] names) {
495: constructor = new GConstructorInfo(names);
496: setPersistentAttributes(names);
497: }
498:
499: public void addOperation(GOperationInfo operationInfo) {
500: operations.put(new GOperationSignature(operationInfo.getName(),
501: operationInfo.getParameterList()), operationInfo);
502: }
503:
504: /**
505: * @deprecated
506: */
507: public void addOperation(String name) {
508: // FIXME : This is needed because the getters/setters are not being added as operation
509: // i.e. kerenl.invoke("getX") fails.
510: addOperation(new GOperationInfo(name, NO_ARGS, ""));
511: }
512:
513: /**
514: * @deprecated
515: */
516: public void addOperation(String name, Class[] paramTypes) {
517: //addOperation(new GOperationInfo(name, paramTypes, ""));
518: }
519:
520: public void addOperation(String name, String returnType) {
521: addOperation(new GOperationInfo(name, NO_ARGS, returnType));
522: }
523:
524: // This is redundant because these operations are added automatically; it can be made private
525: public void addOperation(String name, Class[] paramTypes,
526: String returnType) {
527: addOperation(new GOperationInfo(name, paramTypes, returnType));
528: }
529:
530: public void addReference(GReferenceInfo info) {
531: references.put(info.getName(), new RefInfo(info
532: .getReferenceType(), info.getNameTypeName()));
533: }
534:
535: /**
536: * Add a reference to another GBean or collection of GBeans
537: * @param name the name of the reference
538: * @param type The proxy type of the GBean or objects in a ReferenceCollection
539: * @param namingType the string expected as the type component of the name. For jsr-77 names this is the j2eeType value
540: */
541: public void addReference(String name, Class type, String namingType) {
542: references.put(name, new RefInfo(type.getName(), namingType));
543: }
544:
545: public void addReference(String name, Class type) {
546: references.put(name, new RefInfo(type.getName(), null));
547: }
548:
549: public void setPriority(int priority) {
550: this .priority = priority;
551: }
552:
553: public GBeanInfo getBeanInfo() {
554: // get the types of the constructor args
555: // this also verifies that we have a valid constructor
556: Map constructorTypes = getConstructorTypes();
557:
558: // build the reference infos now that we know the constructor types
559: Set referenceInfos = new HashSet();
560: for (Iterator iterator = references.entrySet().iterator(); iterator
561: .hasNext();) {
562: Map.Entry entry = (Map.Entry) iterator.next();
563: String referenceName = (String) entry.getKey();
564: RefInfo refInfo = (RefInfo) entry.getValue();
565: String referenceType = refInfo.getJavaType();
566: String namingType = refInfo.getNamingType();
567:
568: String proxyType = (String) constructorTypes
569: .get(referenceName);
570: String setterName = null;
571: if (proxyType == null) {
572: Method setter = searchForSetterMethod(referenceName,
573: referenceType, gbeanType);
574: if (setter == null) {
575: setter = searchForSetterMethod(referenceName,
576: Collection.class.getName(), gbeanType);
577: if (setter == null) {
578: throw new InvalidConfigurationException(
579: "Reference must be a constructor argument or have a setter: name="
580: + referenceName
581: + " for gbeanType: "
582: + gbeanType);
583: }
584: }
585: proxyType = setter.getParameterTypes()[0].getName();
586:
587: setterName = setter.getName();
588: }
589:
590: if (!proxyType.equals(Collection.class.getName())
591: && !proxyType.equals(referenceType)) {
592: throw new InvalidConfigurationException(
593: "Reference proxy type must be Collection or "
594: + referenceType + ": name="
595: + referenceName + " for gbeanType: "
596: + gbeanType.getName());
597: }
598:
599: referenceInfos.add(new GReferenceInfo(referenceName,
600: referenceType, proxyType, setterName, namingType));
601: }
602:
603: return new GBeanInfo(sourceClass, name, gbeanType.getName(),
604: j2eeType, attributes.values(), constructor, operations
605: .values(), referenceInfos, interfaces, priority);
606: }
607:
608: private Map getConstructorTypes()
609: throws InvalidConfigurationException {
610: List arguments = constructor.getAttributeNames();
611: String[] argumentTypes = new String[arguments.size()];
612: boolean[] isReference = new boolean[arguments.size()];
613: for (int i = 0; i < argumentTypes.length; i++) {
614: String argumentName = (String) arguments.get(i);
615: if (references.containsKey(argumentName)) {
616: argumentTypes[i] = ((RefInfo) references
617: .get(argumentName)).getJavaType();
618: isReference[i] = true;
619: } else if (attributes.containsKey(argumentName)) {
620: GAttributeInfo attribute = (GAttributeInfo) attributes
621: .get(argumentName);
622: argumentTypes[i] = attribute.getType();
623: isReference[i] = false;
624: }
625: }
626:
627: Constructor[] constructors = gbeanType.getConstructors();
628: Set validConstructors = new HashSet();
629: for (int i = 0; i < constructors.length; i++) {
630: Constructor constructor = constructors[i];
631: if (isValidConstructor(constructor, argumentTypes,
632: isReference)) {
633: validConstructors.add(constructor);
634: }
635: }
636:
637: if (validConstructors.isEmpty()) {
638: throw new InvalidConfigurationException(
639: "Could not find a valid constructor for GBean: "
640: + gbeanType.getName());
641: }
642: if (validConstructors.size() > 1) {
643: throw new InvalidConfigurationException(
644: "More then one valid constructors found for GBean: "
645: + gbeanType.getName());
646: }
647:
648: Map constructorTypes = new HashMap();
649: Constructor constructor = (Constructor) validConstructors
650: .iterator().next();
651: Class[] parameterTypes = constructor.getParameterTypes();
652: Iterator argumentIterator = arguments.iterator();
653: for (int i = 0; i < parameterTypes.length; i++) {
654: String parameterType = parameterTypes[i].getName();
655: String argumentName = (String) argumentIterator.next();
656: constructorTypes.put(argumentName, parameterType);
657: }
658: return constructorTypes;
659: }
660:
661: private static String searchForGetter(String name, String type,
662: Class gbeanType) throws InvalidConfigurationException {
663: Method getterMethod = null;
664:
665: // no explicit name give so we must search for a name
666: String getterName = "get" + name;
667: String isName = "is" + name;
668: Method[] methods = gbeanType.getMethods();
669: for (int i = 0; i < methods.length; i++) {
670: if (methods[i].getParameterTypes().length == 0
671: && methods[i].getReturnType() != Void.TYPE
672: && (getterName.equalsIgnoreCase(methods[i]
673: .getName()) || isName
674: .equalsIgnoreCase(methods[i].getName()))) {
675:
676: // found it
677: getterMethod = methods[i];
678: break;
679: }
680: }
681:
682: // if the return type of the getter doesn't match, throw an exception
683: if (getterMethod != null
684: && !type.equals(getterMethod.getReturnType().getName())) {
685: throw new InvalidConfigurationException(
686: "Incorrect return type for getter method:"
687: + " name=" + name + ", targetClass="
688: + gbeanType.getName() + ", getter type="
689: + getterMethod.getReturnType()
690: + ", expected type=" + type);
691: }
692:
693: if (getterMethod == null) {
694: return null;
695: }
696: return getterMethod.getName();
697: }
698:
699: private static String searchForSetter(String name, String type,
700: Class gbeanType) throws InvalidConfigurationException {
701: Method method = searchForSetterMethod(name, type, gbeanType);
702: if (method == null) {
703: return null;
704: }
705: return method.getName();
706: }
707:
708: private static Method searchForSetterMethod(String name,
709: String type, Class gbeanType)
710: throws InvalidConfigurationException {
711: // no explicit name give so we must search for a name
712: String setterName = "set" + name;
713: Method[] methods = gbeanType.getMethods();
714: for (int i = 0; i < methods.length; i++) {
715: Method method = methods[i];
716: if (method.getParameterTypes().length == 1
717: && method.getParameterTypes()[0].getName().equals(
718: type)
719: && method.getReturnType() == Void.TYPE
720: && setterName.equalsIgnoreCase(method.getName())) {
721:
722: return method;
723: }
724: }
725:
726: // a setter is not necessary for this attribute
727: return null;
728: }
729:
730: private static boolean isValidConstructor(Constructor constructor,
731: String[] argumentTypes, boolean[] isReference) {
732: Class[] parameterTypes = constructor.getParameterTypes();
733:
734: // same number of parameters?
735: if (parameterTypes.length != argumentTypes.length) {
736: return false;
737: }
738:
739: // is each parameter the correct type?
740: for (int i = 0; i < parameterTypes.length; i++) {
741: String parameterType = parameterTypes[i].getName();
742: if (isReference[i]) {
743: // reference: does type match
744: // OR is it a java.util.Collection
745: // OR is it a java.util.Set?
746: if (!parameterType.equals(argumentTypes[i])
747: && !parameterType.equals(Collection.class
748: .getName())
749: && !parameterType.equals(Set.class.getName())) {
750: return false;
751: }
752: } else {
753: // attribute: does type match?
754: if (!parameterType.equals(argumentTypes[i])) {
755: return false;
756: }
757: }
758: }
759: return true;
760: }
761:
762: private String getAttributeName(Method method) {
763: String name = method.getName();
764: String attributeName = (name.startsWith("get") || name
765: .startsWith("set")) ? name.substring(3) : name
766: .substring(2);
767: attributeName = Introspector.decapitalize(attributeName);
768: return attributeName;
769: }
770:
771: private boolean isSetter(Method method) {
772: return method.getName().startsWith("set")
773: && method.getParameterTypes().length == 1;
774: }
775:
776: private static boolean isGetter(Method method) {
777: String name = method.getName();
778: return (name.startsWith("get") || name.startsWith("is"))
779: && method.getParameterTypes().length == 0;
780: }
781:
782: /**
783: * Checks whether or not the input argument is null; otherwise it throws
784: * {@link IllegalArgumentException}.
785: *
786: * @param clazz the input argument to validate
787: * @throws IllegalArgumentException if input is null
788: */
789: private static Class checkNotNull(final Class clazz) {
790: if (clazz == null) {
791: throw new IllegalArgumentException("null argument supplied");
792: }
793: return clazz;
794: }
795:
796: /**
797: * Checks whether or not the input argument is null; otherwise it throws
798: * {@link IllegalArgumentException}.
799: *
800: * @param string the input argument to validate
801: * @throws IllegalArgumentException if input is null
802: */
803: private static String checkNotNull(final String string) {
804: if (string == null) {
805: throw new IllegalArgumentException("null argument supplied");
806: }
807: return string;
808: }
809:
810: private static Class loadClass(ClassLoader classLoader, String name) {
811: try {
812: return classLoader.loadClass(name);
813: } catch (ClassNotFoundException e) {
814: throw new InvalidConfigurationException(
815: "Could not load class " + name, e);
816: }
817: }
818:
819: private static class RefInfo {
820: private final String javaType;
821: private final String namingType;
822:
823: public RefInfo(String javaType, String namingType) {
824: this .javaType = javaType;
825: this .namingType = namingType;
826: }
827:
828: public String getJavaType() {
829: return javaType;
830: }
831:
832: public String getNamingType() {
833: return namingType;
834: }
835: }
836: }
|