View Javadoc

1   /*
2    * Copyright 2004 Sun Microsystems, Inc.
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   */
17  package com.sun.syndication.feed.impl;
18  
19  import java.beans.IntrospectionException;
20  import java.beans.Introspector;
21  import java.beans.PropertyDescriptor;
22  import java.lang.reflect.Method;
23  import java.lang.reflect.Modifier;
24  import java.util.*;
25  
26  /***
27   * Obtains all property descriptors from a bean (interface or implementation).
28   * <p>
29   * The java.beans.Introspector does not process the interfaces hierarchy chain, this one does.
30   * <p>
31   * @author Alejandro Abdelnur
32   *
33   */
34  public class BeanIntrospector {
35  
36      private static final Map _introspected = new HashMap();
37  
38      public static synchronized PropertyDescriptor[] getPropertyDescriptors(Class klass) throws IntrospectionException {
39          PropertyDescriptor[] descriptors = (PropertyDescriptor[]) _introspected.get(klass);
40          if (descriptors==null) {
41              descriptors = getPDs(klass);
42              _introspected.put(klass,descriptors);
43          }
44          return descriptors;
45      }
46  
47      private static PropertyDescriptor[] getPDs(Class klass) throws IntrospectionException {
48          Method[] methods = klass.getMethods();
49          Map getters = getPDs(methods,false);
50          Map setters = getPDs(methods,true);
51          List pds     = merge(getters,setters);
52          PropertyDescriptor[] array = new PropertyDescriptor[pds.size()];
53          pds.toArray(array);
54          return array;
55      }
56  
57      private static final String SETTER = "set";
58      private static final String GETTER = "get";
59      private static final String BOOLEAN_GETTER = "is";
60  
61      private static Map getPDs(Method[] methods,boolean setters) throws IntrospectionException {
62          Map pds = new HashMap();
63          for (int i=0;i<methods.length;i++) {
64              String pName = null;
65              PropertyDescriptor pDescriptor = null;
66              if ((methods[i].getModifiers()&Modifier.PUBLIC)!=0) {
67                  if (setters) {
68                      if (methods[i].getName().startsWith(SETTER) &&
69                          methods[i].getReturnType()==void.class && methods[i].getParameterTypes().length==1) {
70                          pName = Introspector.decapitalize(methods[i].getName().substring(3));
71                          pDescriptor = new PropertyDescriptor(pName,null,methods[i]);
72                      }
73                  }
74                  else {
75                      if (methods[i].getName().startsWith(GETTER) &&
76                          methods[i].getReturnType()!=void.class && methods[i].getParameterTypes().length==0) {
77                          pName = Introspector.decapitalize(methods[i].getName().substring(3));
78                          pDescriptor = new PropertyDescriptor(pName,methods[i],null);
79                      }
80                      else
81                      if (methods[i].getName().startsWith(BOOLEAN_GETTER) &&
82                          methods[i].getReturnType()==boolean.class && methods[i].getParameterTypes().length==0) {
83                          pName = Introspector.decapitalize(methods[i].getName().substring(2));
84                          pDescriptor = new PropertyDescriptor(pName,methods[i],null);
85                      }
86                  }
87              }
88              if (pName!=null) {
89                  pds.put(pName,pDescriptor);
90              }
91          }
92          return pds;
93      }
94  
95      private static List merge(Map getters,Map setters) throws IntrospectionException {
96          List props = new ArrayList();
97          Set processedProps = new HashSet();
98          Iterator gs = getters.keySet().iterator();
99          while (gs.hasNext()) {
100             String name = (String) gs.next();
101             PropertyDescriptor getter = (PropertyDescriptor) getters.get(name);
102             PropertyDescriptor setter = (PropertyDescriptor) setters.get(name);
103             if (setter!=null) {
104                 processedProps.add(name);
105                 PropertyDescriptor prop = new PropertyDescriptor(name,getter.getReadMethod(),setter.getWriteMethod());
106                 props.add(prop);
107             }
108             else {
109                 props.add(getter);
110             }
111         }
112         Set writeOnlyProps = new HashSet(setters.keySet());
113         writeOnlyProps.removeAll(processedProps);
114         Iterator ss = writeOnlyProps.iterator();
115         while (ss.hasNext()) {
116             String name = (String) ss.next();
117             PropertyDescriptor setter = (PropertyDescriptor) setters.get(name);
118             props.add(setter);
119         }
120         return props;
121     }
122 
123 }