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 018package org.granite.util; 019 020import java.lang.reflect.Method; 021 022 023public 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}