001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package org.granite.util; 023 024import java.lang.reflect.Method; 025 026 027public class PropertyDescriptor { 028 029 private String name; 030 private Method getter; 031 private Method setter; 032 033 public PropertyDescriptor(String propertyName, Method getter, Method setter) { 034 this.name = propertyName; 035 setReadMethod(getter); 036 setWriteMethod(setter); 037 } 038 039 public PropertyDescriptor(String propertyName, Class<?> beanClass) { 040 this.name = propertyName; 041 try { 042 setReadMethod(beanClass, createDefaultMethodName(propertyName, "is")); 043 } 044 catch (Exception e) { 045 setReadMethod(beanClass, createDefaultMethodName(propertyName, "get")); 046 } 047 048 setWriteMethod(beanClass, createDefaultMethodName(propertyName, "set")); 049 } 050 051 public String getName() { 052 return this.name; 053 } 054 055 public void setWriteMethod(Method setter) { 056 this.setter = setter; 057 } 058 059 public void setReadMethod(Method getter) { 060 this.getter = getter; 061 } 062 063 public Method getWriteMethod() { 064 return setter; 065 } 066 067 public Method getReadMethod() { 068 return getter; 069 } 070 071 @Override 072 public boolean equals(Object object) { 073 if (!(object instanceof PropertyDescriptor)) 074 return false; 075 076 PropertyDescriptor pd = (PropertyDescriptor)object; 077 if (!((this.getter == null && pd.getter == null) 078 || (this.getter != null && this.getter.equals(pd.getter)))) 079 return false; 080 081 if (!((this.setter == null && pd.setter == null) 082 || (this.setter != null && this.setter.equals(pd.setter)))) 083 return false; 084 085 return this.getPropertyType() == pd.getPropertyType(); 086 } 087 088 @Override 089 public int hashCode() { 090 int hashCode = getter != null ? getter.hashCode() : 0; 091 if (setter != null) 092 hashCode = hashCode*31 + setter.hashCode(); 093 if (getPropertyType() != null) 094 hashCode = hashCode*31 + getPropertyType().hashCode(); 095 return hashCode; 096 } 097 098 public Class<?> getPropertyType() { 099 if (getter != null) 100 return getter.getReturnType(); 101 if (setter != null) { 102 Class<?>[] parameterTypes = setter.getParameterTypes(); 103 return parameterTypes[0]; 104 } 105 return null; 106 } 107 108 private String createDefaultMethodName(String propertyName, String prefix) { 109 return prefix + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); 110 } 111 112 private void setReadMethod(Class<?> beanClass, String getterName) { 113 try { 114 Method readMethod = beanClass.getMethod(getterName, new Class[] {}); 115 setReadMethod(readMethod); 116 } 117 catch (Exception e) { 118 throw new RuntimeException("Introspection exception", e); 119 } 120 } 121 122 private void setWriteMethod(Class<?> beanClass, String setterName) { 123 Method writeMethod = null; 124 try { 125 if (getter != null) { 126 writeMethod = beanClass.getMethod(setterName, new Class[] { getter.getReturnType() }); 127 } 128 else { 129 Class<?> clazz = beanClass; 130 Method[] methods = null; 131 while (clazz != null && writeMethod == null) { 132 methods = clazz.getDeclaredMethods(); 133 for (Method method : methods) { 134 if (setterName.equals(method.getName())) { 135 if (method.getParameterTypes().length == 1) { 136 writeMethod = method; 137 break; 138 } 139 } 140 } 141 clazz = clazz.getSuperclass(); 142 } 143 } 144 } 145 catch (Exception e) { 146 throw new RuntimeException("Introspection exception", e); 147 } 148 if (writeMethod == null) 149 throw new RuntimeException("Could not find setter for property " + name); 150 151 setWriteMethod(writeMethod); 152 } 153}