/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package java.beans; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.harmony.beans.internal.nls.Messages; public class IndexedPropertyDescriptor extends PropertyDescriptor { private Method indexedGetter; private Method indexedSetter; public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass, String getterName, String setterName, String indexedGetterName, String indexedSetterName) throws IntrospectionException { super(propertyName, beanClass, getterName, setterName); // RI behaves like this if (indexedGetterName == null && indexedSetterName == null && (getterName != null || setterName != null)) { throw new IntrospectionException(Messages.getString("beans.50")); } setIndexedReadMethod(beanClass, indexedGetterName); setIndexedWriteMethod(beanClass, indexedSetterName); } public IndexedPropertyDescriptor(String propertyName, Method getter, Method setter, Method indexedGetter, Method indexedSetter) throws IntrospectionException { super(propertyName, getter, setter); // we need this in order to be compatible with RI if (indexedGetter == null && indexedSetter == null && (getter != null || setter != null)) { throw new IntrospectionException(Messages.getString("beans.50")); } setIndexedReadMethod(indexedGetter); setIndexedWriteMethod(indexedSetter); } public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass) throws IntrospectionException { super(propertyName, beanClass, null, null); String getterName; String setterName; String indexedGetterName; String indexedSetterName; // array getter getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$ if (hasMethod(beanClass, getterName)) { setReadMethod(beanClass, getterName); } // array setter setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$ if (hasMethod(beanClass, setterName)) { setWriteMethod(beanClass, setterName); } // indexed getter indexedGetterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$ if (hasMethod(beanClass, indexedGetterName)) { setIndexedReadMethod(beanClass, indexedGetterName); } // indexed setter indexedSetterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$ if (hasMethod(beanClass, indexedSetterName)) { setIndexedWriteMethod(beanClass, indexedSetterName); } // RI seems to behave a bit differently if (indexedGetter == null && indexedSetter == null && getReadMethod() == null && getWriteMethod() == null) { throw new IntrospectionException( Messages.getString("beans.01", propertyName)); //$NON-NLS-1$ } if (indexedGetter == null && indexedSetter == null) { // not an indexed property indeed throw new IntrospectionException(Messages.getString("beans.50")); } } public void setIndexedReadMethod(Method indexedGetter) throws IntrospectionException { if (indexedGetter != null) { int modifiers = indexedGetter.getModifiers(); Class<?>[] parameterTypes; Class<?> returnType; Class<?> indexedPropertyType; if (!Modifier.isPublic(modifiers)) { throw new IntrospectionException(Messages.getString("beans.21")); //$NON-NLS-1$ } parameterTypes = indexedGetter.getParameterTypes(); if (parameterTypes.length != 1) { throw new IntrospectionException(Messages.getString("beans.22")); //$NON-NLS-1$ } if (!parameterTypes[0].equals(int.class)) { throw new IntrospectionException(Messages.getString("beans.23")); //$NON-NLS-1$ } returnType = indexedGetter.getReturnType(); indexedPropertyType = getIndexedPropertyType(); if ((indexedPropertyType != null) && !returnType.equals(indexedPropertyType)) { throw new IntrospectionException(Messages.getString("beans.24")); //$NON-NLS-1$ } } this.indexedGetter = indexedGetter; } public void setIndexedWriteMethod(Method indexedSetter) throws IntrospectionException { if (indexedSetter != null) { int modifiers = indexedSetter.getModifiers(); Class<?>[] parameterTypes; Class<?> firstParameterType; Class<?> secondParameterType; Class<?> propType; if (!Modifier.isPublic(modifiers)) { throw new IntrospectionException(Messages.getString("beans.25")); //$NON-NLS-1$ } parameterTypes = indexedSetter.getParameterTypes(); if (parameterTypes.length != 2) { throw new IntrospectionException(Messages.getString("beans.26")); //$NON-NLS-1$ } firstParameterType = parameterTypes[0]; if (!firstParameterType.equals(int.class)) { throw new IntrospectionException(Messages.getString("beans.27")); //$NON-NLS-1$ } secondParameterType = parameterTypes[1]; propType = getIndexedPropertyType(); if (propType != null && !secondParameterType.equals(propType)) { throw new IntrospectionException(Messages.getString("beans.28")); //$NON-NLS-1$ } } this.indexedSetter = indexedSetter; } public Method getIndexedWriteMethod() { return indexedSetter; } public Method getIndexedReadMethod() { return indexedGetter; } @Override public boolean equals(Object obj) { boolean result = super.equals(obj); if (result) { IndexedPropertyDescriptor pd = (IndexedPropertyDescriptor) obj; if (indexedGetter != null) { result = indexedGetter.equals(pd.getIndexedReadMethod()); } else if (result && indexedGetter == null) { result = pd.getIndexedReadMethod() == null; } if (result) { if (indexedSetter != null) { result = indexedSetter.equals(pd.getIndexedWriteMethod()); } else if (indexedSetter == null) { result = pd.getIndexedWriteMethod() == null; } } } return result; } public Class<?> getIndexedPropertyType() { Class<?> result = null; if (indexedGetter != null) { result = indexedGetter.getReturnType(); } else if (indexedSetter != null) { Class<?>[] parameterTypes = indexedSetter.getParameterTypes(); result = parameterTypes[1]; } return result; } private void setIndexedReadMethod(Class<?> beanClass, String indexedGetterName) { Method[] getters = findMethods(beanClass, indexedGetterName); boolean result = false; for (Method element : getters) { try { setIndexedReadMethod(element); result = true; } catch (IntrospectionException ie) {} if (result) { break; } } } private void setIndexedWriteMethod(Class<?> beanClass, String indexedSetterName) { Method[] setters = findMethods(beanClass, indexedSetterName); boolean result = false; for (Method element : setters) { try { setIndexedWriteMethod(element); result = true; } catch (IntrospectionException ie) {} if (result) { break; } } } }