1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.beans; 19 20 import java.lang.reflect.Method; 21 import java.lang.reflect.Modifier; 22 import org.apache.harmony.beans.internal.nls.Messages; 23 24 public class IndexedPropertyDescriptor extends PropertyDescriptor { 25 private Method indexedGetter; 26 27 private Method indexedSetter; 28 29 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass, 30 String getterName, String setterName, String indexedGetterName, 31 String indexedSetterName) throws IntrospectionException { 32 super(propertyName, beanClass, getterName, setterName); 33 34 // RI behaves like this 35 if (indexedGetterName == null && indexedSetterName == null && 36 (getterName != null || setterName != null)) { 37 throw new IntrospectionException(Messages.getString("beans.50")); 38 } 39 setIndexedReadMethod(beanClass, indexedGetterName); 40 setIndexedWriteMethod(beanClass, indexedSetterName); 41 } 42 43 public IndexedPropertyDescriptor(String propertyName, Method getter, Method setter, 44 Method indexedGetter, Method indexedSetter) throws IntrospectionException { 45 super(propertyName, getter, setter); 46 47 // we need this in order to be compatible with RI 48 if (indexedGetter == null && indexedSetter == null && 49 (getter != null || setter != null)) { 50 throw new IntrospectionException(Messages.getString("beans.50")); 51 } 52 setIndexedReadMethod(indexedGetter); 53 setIndexedWriteMethod(indexedSetter); 54 } 55 56 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass) 57 throws IntrospectionException { 58 super(propertyName, beanClass, null, null); 59 String getterName; 60 String setterName; 61 String indexedGetterName; 62 String indexedSetterName; 63 64 // array getter 65 getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$ 66 if (hasMethod(beanClass, getterName)) { 67 setReadMethod(beanClass, getterName); 68 } 69 // array setter 70 setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$ 71 if (hasMethod(beanClass, setterName)) { 72 setWriteMethod(beanClass, setterName); 73 } 74 // indexed getter 75 indexedGetterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$ 76 if (hasMethod(beanClass, indexedGetterName)) { 77 setIndexedReadMethod(beanClass, indexedGetterName); 78 } 79 // indexed setter 80 indexedSetterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$ 81 if (hasMethod(beanClass, indexedSetterName)) { 82 setIndexedWriteMethod(beanClass, indexedSetterName); 83 } 84 // RI seems to behave a bit differently 85 if (indexedGetter == null && indexedSetter == null && 86 getReadMethod() == null && getWriteMethod() == null) { 87 throw new IntrospectionException( 88 Messages.getString("beans.01", propertyName)); //$NON-NLS-1$ 89 } 90 if (indexedGetter == null && indexedSetter == null) { 91 // not an indexed property indeed 92 throw new IntrospectionException(Messages.getString("beans.50")); 93 } 94 } 95 96 public void setIndexedReadMethod(Method indexedGetter) throws IntrospectionException { 97 if (indexedGetter != null) { 98 int modifiers = indexedGetter.getModifiers(); 99 Class<?>[] parameterTypes; 100 Class<?> returnType; 101 Class<?> indexedPropertyType; 102 103 if (!Modifier.isPublic(modifiers)) { 104 throw new IntrospectionException(Messages.getString("beans.21")); //$NON-NLS-1$ 105 } 106 parameterTypes = indexedGetter.getParameterTypes(); 107 if (parameterTypes.length != 1) { 108 throw new IntrospectionException(Messages.getString("beans.22")); //$NON-NLS-1$ 109 } 110 if (!parameterTypes[0].equals(int.class)) { 111 throw new IntrospectionException(Messages.getString("beans.23")); //$NON-NLS-1$ 112 } 113 returnType = indexedGetter.getReturnType(); 114 indexedPropertyType = getIndexedPropertyType(); 115 if ((indexedPropertyType != null) && !returnType.equals(indexedPropertyType)) { 116 throw new IntrospectionException(Messages.getString("beans.24")); //$NON-NLS-1$ 117 } 118 } 119 this.indexedGetter = indexedGetter; 120 } 121 122 public void setIndexedWriteMethod(Method indexedSetter) throws IntrospectionException { 123 if (indexedSetter != null) { 124 int modifiers = indexedSetter.getModifiers(); 125 Class<?>[] parameterTypes; 126 Class<?> firstParameterType; 127 Class<?> secondParameterType; 128 Class<?> propType; 129 130 if (!Modifier.isPublic(modifiers)) { 131 throw new IntrospectionException(Messages.getString("beans.25")); //$NON-NLS-1$ 132 } 133 parameterTypes = indexedSetter.getParameterTypes(); 134 if (parameterTypes.length != 2) { 135 throw new IntrospectionException(Messages.getString("beans.26")); //$NON-NLS-1$ 136 } 137 firstParameterType = parameterTypes[0]; 138 if (!firstParameterType.equals(int.class)) { 139 throw new IntrospectionException(Messages.getString("beans.27")); //$NON-NLS-1$ 140 } 141 secondParameterType = parameterTypes[1]; 142 propType = getIndexedPropertyType(); 143 if (propType != null && !secondParameterType.equals(propType)) { 144 throw new IntrospectionException(Messages.getString("beans.28")); //$NON-NLS-1$ 145 } 146 } 147 this.indexedSetter = indexedSetter; 148 } 149 150 public Method getIndexedWriteMethod() { 151 return indexedSetter; 152 } 153 154 public Method getIndexedReadMethod() { 155 return indexedGetter; 156 } 157 158 @Override 159 public boolean equals(Object obj) { 160 boolean result = super.equals(obj); 161 162 if (result) { 163 IndexedPropertyDescriptor pd = (IndexedPropertyDescriptor) obj; 164 165 if (indexedGetter != null) { 166 result = indexedGetter.equals(pd.getIndexedReadMethod()); 167 } else if (result && indexedGetter == null) { 168 result = pd.getIndexedReadMethod() == null; 169 } 170 171 if (result) { 172 if (indexedSetter != null) { 173 result = indexedSetter.equals(pd.getIndexedWriteMethod()); 174 } else if (indexedSetter == null) { 175 result = pd.getIndexedWriteMethod() == null; 176 } 177 } 178 } 179 180 return result; 181 } 182 183 public Class<?> getIndexedPropertyType() { 184 Class<?> result = null; 185 186 if (indexedGetter != null) { 187 result = indexedGetter.getReturnType(); 188 } else if (indexedSetter != null) { 189 Class<?>[] parameterTypes = indexedSetter.getParameterTypes(); 190 191 result = parameterTypes[1]; 192 } 193 return result; 194 } 195 196 private void setIndexedReadMethod(Class<?> beanClass, String indexedGetterName) { 197 Method[] getters = findMethods(beanClass, indexedGetterName); 198 boolean result = false; 199 200 for (Method element : getters) { 201 try { 202 setIndexedReadMethod(element); 203 result = true; 204 } catch (IntrospectionException ie) {} 205 206 if (result) { 207 break; 208 } 209 } 210 } 211 212 private void setIndexedWriteMethod(Class<?> beanClass, String indexedSetterName) { 213 Method[] setters = findMethods(beanClass, indexedSetterName); 214 boolean result = false; 215 216 for (Method element : setters) { 217 try { 218 setIndexedWriteMethod(element); 219 result = true; 220 } catch (IntrospectionException ie) {} 221 222 if (result) { 223 break; 224 } 225 } 226 } 227 } 228