001: /*
002: * Copyright 2004 Sun Microsystems, Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: */
017: package com.sun.syndication.feed.impl;
018:
019: import java.beans.IntrospectionException;
020: import java.beans.Introspector;
021: import java.beans.PropertyDescriptor;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Modifier;
024: import java.util.*;
025:
026: /**
027: * Obtains all property descriptors from a bean (interface or implementation).
028: * <p>
029: * The java.beans.Introspector does not process the interfaces hierarchy chain, this one does.
030: * <p>
031: * @author Alejandro Abdelnur
032: *
033: */
034: public class BeanIntrospector {
035:
036: private static final Map _introspected = new HashMap();
037:
038: public static synchronized PropertyDescriptor[] getPropertyDescriptors(
039: Class klass) throws IntrospectionException {
040: PropertyDescriptor[] descriptors = (PropertyDescriptor[]) _introspected
041: .get(klass);
042: if (descriptors == null) {
043: descriptors = getPDs(klass);
044: _introspected.put(klass, descriptors);
045: }
046: return descriptors;
047: }
048:
049: private static PropertyDescriptor[] getPDs(Class klass)
050: throws IntrospectionException {
051: Method[] methods = klass.getMethods();
052: Map getters = getPDs(methods, false);
053: Map setters = getPDs(methods, true);
054: List pds = merge(getters, setters);
055: PropertyDescriptor[] array = new PropertyDescriptor[pds.size()];
056: pds.toArray(array);
057: return array;
058: }
059:
060: private static final String SETTER = "set";
061: private static final String GETTER = "get";
062: private static final String BOOLEAN_GETTER = "is";
063:
064: private static Map getPDs(Method[] methods, boolean setters)
065: throws IntrospectionException {
066: Map pds = new HashMap();
067: for (int i = 0; i < methods.length; i++) {
068: String pName = null;
069: PropertyDescriptor pDescriptor = null;
070: if ((methods[i].getModifiers() & Modifier.PUBLIC) != 0) {
071: if (setters) {
072: if (methods[i].getName().startsWith(SETTER)
073: && methods[i].getReturnType() == void.class
074: && methods[i].getParameterTypes().length == 1) {
075: pName = Introspector.decapitalize(methods[i]
076: .getName().substring(3));
077: pDescriptor = new PropertyDescriptor(pName,
078: null, methods[i]);
079: }
080: } else {
081: if (methods[i].getName().startsWith(GETTER)
082: && methods[i].getReturnType() != void.class
083: && methods[i].getParameterTypes().length == 0) {
084: pName = Introspector.decapitalize(methods[i]
085: .getName().substring(3));
086: pDescriptor = new PropertyDescriptor(pName,
087: methods[i], null);
088: } else if (methods[i].getName().startsWith(
089: BOOLEAN_GETTER)
090: && methods[i].getReturnType() == boolean.class
091: && methods[i].getParameterTypes().length == 0) {
092: pName = Introspector.decapitalize(methods[i]
093: .getName().substring(2));
094: pDescriptor = new PropertyDescriptor(pName,
095: methods[i], null);
096: }
097: }
098: }
099: if (pName != null) {
100: pds.put(pName, pDescriptor);
101: }
102: }
103: return pds;
104: }
105:
106: private static List merge(Map getters, Map setters)
107: throws IntrospectionException {
108: List props = new ArrayList();
109: Set processedProps = new HashSet();
110: Iterator gs = getters.keySet().iterator();
111: while (gs.hasNext()) {
112: String name = (String) gs.next();
113: PropertyDescriptor getter = (PropertyDescriptor) getters
114: .get(name);
115: PropertyDescriptor setter = (PropertyDescriptor) setters
116: .get(name);
117: if (setter != null) {
118: processedProps.add(name);
119: PropertyDescriptor prop = new PropertyDescriptor(name,
120: getter.getReadMethod(), setter.getWriteMethod());
121: props.add(prop);
122: } else {
123: props.add(getter);
124: }
125: }
126: Set writeOnlyProps = new HashSet(setters.keySet());
127: writeOnlyProps.removeAll(processedProps);
128: Iterator ss = writeOnlyProps.iterator();
129: while (ss.hasNext()) {
130: String name = (String) ss.next();
131: PropertyDescriptor setter = (PropertyDescriptor) setters
132: .get(name);
133: props.add(setter);
134: }
135: return props;
136: }
137:
138: }
|