/* * Copyright 2005 Joe Walker * * Licensed 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 org.directwebremoting.extend; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import org.directwebremoting.ConversionException; import org.directwebremoting.util.LocalUtil; /** * @author Joe Walker [joe at getahead dot ltd dot uk] */ public class NestedProperty implements Property { /** * */ public NestedProperty(Property parent, Object method, Type parentParameterType, int parameterNumber, int newParameterNumber) { this.parent = parent; if (parentParameterType instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) parentParameterType; Type[] actualTypeArguments = ptype.getActualTypeArguments(); if (newParameterNumber >= actualTypeArguments.length) { throw new IllegalArgumentException("newParameterNumber=" + newParameterNumber + " is too big when parameterType=" + parentParameterType + " give actualTypeArguments.length=" + actualTypeArguments.length); } this.parameterType = actualTypeArguments[newParameterNumber]; } else { this.parameterType = null; } this.object = method; this.parameterNumber = parameterNumber; this.newParameterNumber = newParameterNumber; } /* (non-Javadoc) * @see org.directwebremoting.extend.Property#getName() */ public String getName() { return "NestedProperty"; } /* (non-Javadoc) * @see org.directwebremoting.extend.Property#getPropertyType() */ public Class<?> getPropertyType() { return LocalUtil.toClass(parameterType, toString()); } /* (non-Javadoc) * @see org.directwebremoting.extend.Property#getValue(java.lang.Object) */ public Object getValue(Object bean) throws ConversionException { throw new UnsupportedOperationException("Can't get value from nested property"); } /* (non-Javadoc) * @see org.directwebremoting.extend.Property#setValue(java.lang.Object, java.lang.Object) */ public void setValue(Object bean, Object value) throws ConversionException { throw new UnsupportedOperationException("Can't set value to nested property"); } /* (non-Javadoc) * @see org.directwebremoting.extend.Property#createChild(int) */ public Property createChild(int aNewParameterNumber) { return new NestedProperty(this, object, parameterType, parameterNumber, aNewParameterNumber); } /** * @return The type parameter */ public Type getParameterType() { return parameterType; } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return object.hashCode() + parameterNumber; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || this.getClass() != obj.getClass()) { return false; } NestedProperty that = (NestedProperty) obj; if (!this.object.equals(that.object)) { return false; } if (!this.parent.equals(that.parent)) { return false; } if (this.newParameterNumber != that.newParameterNumber) { return false; } return this.parameterNumber == that.parameterNumber; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { if (object instanceof Method) { Method method = (Method) object; return "(method=" + method.toGenericString() + ", parameter: " + parameterNumber + ")"; } else if (object instanceof Constructor) { Constructor<?> ctor = (Constructor<?>) object; return "(method=" + ctor.toGenericString() + ", parameter: " + parameterNumber + ")"; } return "(method=" + object.toString() + ", parameter: " + parameterNumber + ")"; } private final Property parent; private final Object object; private final int parameterNumber; private final Type parameterType; private final int newParameterNumber; }