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 */
017
018 package org.granite.util;
019
020 import java.lang.reflect.Method;
021
022
023 public class PropertyDescriptor {
024
025 private String name;
026 private Method getter;
027 private Method setter;
028
029 public PropertyDescriptor(String propertyName, Method getter, Method setter) {
030 this.name = propertyName;
031 setReadMethod(getter);
032 setWriteMethod(setter);
033 }
034
035 public PropertyDescriptor(String propertyName, Class<?> beanClass) {
036 this.name = propertyName;
037 try {
038 setReadMethod(beanClass, createDefaultMethodName(propertyName, "is"));
039 }
040 catch (Exception e) {
041 setReadMethod(beanClass, createDefaultMethodName(propertyName, "get"));
042 }
043
044 setWriteMethod(beanClass, createDefaultMethodName(propertyName, "set"));
045 }
046
047 public String getName() {
048 return this.name;
049 }
050
051 public void setWriteMethod(Method setter) {
052 this.setter = setter;
053 }
054
055 public void setReadMethod(Method getter) {
056 this.getter = getter;
057 }
058
059 public Method getWriteMethod() {
060 return setter;
061 }
062
063 public Method getReadMethod() {
064 return getter;
065 }
066
067 @Override
068 public boolean equals(Object object) {
069 if (!(object instanceof PropertyDescriptor))
070 return false;
071
072 PropertyDescriptor pd = (PropertyDescriptor)object;
073 if (!((this.getter == null && pd.getter == null)
074 || (this.getter != null && this.getter.equals(pd.getter))))
075 return false;
076
077 if (!((this.setter == null && pd.setter == null)
078 || (this.setter != null && this.setter.equals(pd.setter))))
079 return false;
080
081 return this.getPropertyType() == pd.getPropertyType();
082 }
083
084 @Override
085 public int hashCode() {
086 int hashCode = getter != null ? getter.hashCode() : 0;
087 if (setter != null)
088 hashCode = hashCode*31 + setter.hashCode();
089 if (getPropertyType() != null)
090 hashCode = hashCode*31 + getPropertyType().hashCode();
091 return hashCode;
092 }
093
094 public Class<?> getPropertyType() {
095 if (getter != null)
096 return getter.getReturnType();
097 if (setter != null) {
098 Class<?>[] parameterTypes = setter.getParameterTypes();
099 return parameterTypes[0];
100 }
101 return null;
102 }
103
104 private String createDefaultMethodName(String propertyName, String prefix) {
105 return prefix + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
106 }
107
108 private void setReadMethod(Class<?> beanClass, String getterName) {
109 try {
110 Method readMethod = beanClass.getMethod(getterName, new Class[] {});
111 setReadMethod(readMethod);
112 }
113 catch (Exception e) {
114 throw new RuntimeException("Introspection exception", e);
115 }
116 }
117
118 private void setWriteMethod(Class<?> beanClass, String setterName) {
119 Method writeMethod = null;
120 try {
121 if (getter != null) {
122 writeMethod = beanClass.getMethod(setterName, new Class[] { getter.getReturnType() });
123 }
124 else {
125 Class<?> clazz = beanClass;
126 Method[] methods = null;
127 while (clazz != null && writeMethod == null) {
128 methods = clazz.getDeclaredMethods();
129 for (Method method : methods) {
130 if (setterName.equals(method.getName())) {
131 if (method.getParameterTypes().length == 1) {
132 writeMethod = method;
133 break;
134 }
135 }
136 }
137 clazz = clazz.getSuperclass();
138 }
139 }
140 }
141 catch (Exception e) {
142 throw new RuntimeException("Introspection exception", e);
143 }
144 if (writeMethod == null)
145 throw new RuntimeException("Could not find setter for property " + name);
146
147 setWriteMethod(writeMethod);
148 }
149 }