| /** |
| * Copyright 2009-2013 Oy Vaadin Ltd |
| * |
| * 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.eclipse.osbp.jpa.services.metadata; |
| |
| import java.io.InvalidObjectException; |
| import java.io.ObjectStreamException; |
| import java.io.Serializable; |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Method; |
| |
| /** |
| * This class represents the metadata of a property. If the property is |
| * transient, this is an ordinary JavaBean property consisting of a getter |
| * method and optionally a setter method. If the property is persistent, |
| * additional information is provided by the {@link PersistentPropertyMetadata} |
| * interface. |
| * |
| * @see ClassMetadata |
| * @author Petter Holmström (Vaadin Ltd) |
| * @since 1.0 |
| */ |
| public class PropertyMetadata implements Serializable { |
| |
| private static final long serialVersionUID = -6500231861860229121L; |
| private final String name; |
| private final Class<?> type; |
| transient final Method getter; |
| transient final Method setter; |
| // Required for serialization: |
| protected final String getterName; |
| protected final String setterName; |
| protected final Class<?> getterDeclaringClass; |
| protected final Class<?> setterDeclaringClass; |
| |
| /** |
| * Creates a new instance of <code>PropertyMetadata</code>. |
| * |
| * @param name |
| * the name of the property (must not be null). |
| * @param type |
| * the type of the property (must not be null). |
| * @param getter |
| * the getter method that can be used to read the value of the |
| * property (must not be null). |
| * @param setter |
| * the setter method that can be used to set the value of the |
| * property (may be null). |
| */ |
| PropertyMetadata(String name, Class<?> type, Method getter, Method setter) { |
| assert name != null : "name must not be null"; |
| assert type != null : "type must not be null"; |
| /* |
| * If we assert that getter != null, PersistentPropertyMetadata will not |
| * work. |
| */ |
| this.name = name; |
| this.type = type; |
| this.getter = getter; |
| this.setter = setter; |
| /* |
| * The getter may also be null, e.g. if PersistentPropertyMetadata uses |
| * a field instead of a getter to access the property. |
| */ |
| if (getter != null) { |
| getterName = getter.getName(); |
| getterDeclaringClass = getter.getDeclaringClass(); |
| } else { |
| getterName = null; |
| getterDeclaringClass = null; |
| } |
| if (setter != null) { |
| setterName = setter.getName(); |
| setterDeclaringClass = setter.getDeclaringClass(); |
| } else { |
| setterName = null; |
| setterDeclaringClass = null; |
| } |
| } |
| |
| public Object readResolve() throws ObjectStreamException { |
| try { |
| Method getterM = null; |
| if (getterName != null) { |
| getterM = getterDeclaringClass.getDeclaredMethod(getterName); |
| } |
| Method setterM = null; |
| if (setterName != null) { |
| setterM = setterDeclaringClass.getDeclaredMethod(setterName, |
| type); |
| } |
| return new PropertyMetadata(name, type, getterM, setterM); |
| } catch (Exception e) { |
| throw new InvalidObjectException(e.getMessage()); |
| } |
| } |
| |
| /** |
| * The name of the property. |
| */ |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * The type of the property. |
| */ |
| public Class<?> getType() { |
| return type; |
| } |
| |
| /** |
| * The annotations of the property, if any. |
| * |
| * @see #getAnnotation(java.lang.Class) |
| */ |
| public Annotation[] getAnnotations() { |
| return getter.getAnnotations(); |
| } |
| |
| /** |
| * Gets the annotation of the specified annotation class, if available. |
| * |
| * @see #getAnnotations() |
| * @see Class#getAnnotation(java.lang.Class) |
| * @param annotationClass |
| * the annotation class. |
| * @return the annotation, or null if not found. |
| */ |
| public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { |
| return getter.getAnnotation(annotationClass); |
| } |
| |
| /** |
| * Returns whether the property is writable or not. Transient properties |
| * (i.e. JavaBean properties) are only writable if they have a setter |
| * method. |
| * |
| * @return true if the property is writable, false if it is not. |
| */ |
| public boolean isWritable() { |
| return setter != null; |
| } |
| |
| public PropertyKind getPropertyKind() { |
| return PropertyKind.NONPERSISTENT; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (obj != null && obj.getClass() == getClass()) { |
| PropertyMetadata other = (PropertyMetadata) obj; |
| return name.equals(other.name) |
| && type.equals(other.type) |
| && (getter == null ? other.getter == null : getter |
| .equals(other.getter)) |
| && (setter == null ? other.setter == null : setter |
| .equals(other.setter)); |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| int hash = 7; |
| hash = hash * 31 + name.hashCode(); |
| hash = hash * 31 + type.hashCode(); |
| if (getter != null) { |
| hash = hash * 31 + getter.hashCode(); |
| } |
| if (setter != null) { |
| hash = hash * 31 + setter.hashCode(); |
| } |
| return hash; |
| } |
| } |