All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.co.it.modular.beans.BeanProperty Maven / Gradle / Ivy

Go to download

Utilities for manipulating and inspecting Java classes implementing the Java Beans standard

There is a newer version: 0.9.10
Show newest version

package uk.co.it.modular.beans;

import static uk.co.it.modular.beans.MethodUtils.genericArgs;
import static uk.co.it.modular.beans.Type.type;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * Immutable value object to encapsulate a property on an Object which follows the get/set Java beans standard.

*

* An instance of this class is not bound to a specific instance of an object, rather it represents a re-usable defintion of a get/set pair on a given class *

* * @author Stewart Bissett */ public class BeanProperty { /** * Static factory method for constructing a {@link BeanProperty} for the property name on the given class.

Returns null if the property is not present.

*/ public static final BeanProperty beanProperty(final Class instance, final String name) { return type(instance).propertyNamed(name); } private final Class declaringType; private final String name; private final Class type; private final Class[] params; private final Method accessor, mutator; public BeanProperty(final String propertyName, final Method accessor, final Method mutator) { this.declaringType = accessor.getDeclaringClass(); this.name = propertyName; this.accessor = accessor; this.mutator = mutator; this.type = accessor.getReturnType(); this.params = genericArgs(accessor); } /** * Return the name of the property */ public String getName() { return name; } /** * Return the accessor {@link Method} for this property */ public Method getAccessor() { return accessor; } /** * Return the mutator {@link Method} for this property */ public Method getMutator() { return mutator; } /** * Test the name of the property to see if it matches the supplied name */ public boolean hasName(final String name) { return StringUtils.equals(name, this.name); } /** * Return the value of this property. Will throw a {@link BeanPropertyException} if the property is not found on the given instance */ public Object getValue(final Object instance) { return MethodUtils.invoke(accessor, instance); } /** * Return the value of this property from the given object cast to the given type. Will throw a {@link ClassCastException} if the value is not of the given type. * * @param type * the type to return the value as */ @SuppressWarnings("unchecked") public T getValue(final Object instance, final Class type) { return (T) getValue(instance); } /** * Set the value of this property on the object to the given value. Will throw a {@link RuntimeException} if the property does not exist or return true if the * property was successfullly set. * * @param value * the value to set this property to on the instance */ public boolean setValue(final Object instance, final Object value) { return MethodUtils.invoke(mutator, instance, value); } /** * Return the declaring type of the property */ public Class getDeclaringType() { return declaringType; } /** * Return the declaring type of the property */ public String getDeclaringTypeCanonicalName() { return declaringType.getCanonicalName(); } /** * Return the declaring type of the property */ public String getDeclaringTypeSimpleName() { return declaringType.getSimpleName(); } /** * Return the type of the property */ public Class getType() { return type; } /** * Return the canonical name of the type */ public String getTypeCanonicalName() { return type.getCanonicalName(); } /** * Return the canonical name of the type */ public String getTypeSimpleName() { return type.getSimpleName(); } /** * Return the nth type parameter or throw {@link IllegalArgumentException} if there is no nth type parameter */ public Class getTypeParameter(final int n) { if (params.length > n) { return params[n]; } else { throw new IllegalArgumentException("Unknown type parameter with index '" + n + "'"); } } /** * Return the collection of type paramaters or an empty {@link List} if this property is not generic */ public List> getTypeParameters() { return Arrays.asList(params); } public boolean hasAnyTypeParameters(final Class... types) { for (Class type : types) { for (Class param : this.params) { if (type.isAssignableFrom(param)) { return true; } } } return false; } public boolean hasTypeParameter(final Class type) { for (Class param : this.params) { if (type.isAssignableFrom(param)) { return true; } } return false; } /** * Test if the property implements {@link Iterable} */ public boolean isIterable() { return isType(Iterable.class); } /** * Test if the property type is assignable from the supplied type * * @param type * any type to check to see if this properties type is assignable to it */ public boolean isType(final Class type) { return type.isAssignableFrom(this.type); } /** * Test if the property type is assignable from any one of the supplied types * * @param types * types to check to see if this properties type is assignable to it */ public boolean isType(final Class... types) { for (Class type : types) { if (type.isAssignableFrom(this.type)) { return true; } } return false; } /** * Test if the property is a generic type */ public boolean isGeneric() { return this.params.length > 0; } /** * Test if the property is primitive */ public boolean isPrimitive() { return type.isPrimitive(); } /** * Test if the property is an array */ public boolean isArray() { return type.isArray(); } /** * Test if the property is a {@link String} */ public boolean isString() { return isType(String.class); } /** * Test if the property is an {@link Character} or char */ public boolean isCharacter() { return isType(Character.class, char.class); } /** * Test if the property is an {@link Byte} or char */ public boolean isByte() { return isType(Byte.class, byte.class); } /** * Test if the property is an {@link Integer} or int */ public boolean isInteger() { return isType(Integer.class, int.class); } /** * Test if the property is an {@link Double} or double */ public boolean isDouble() { return isType(Double.class, double.class); } /** * Test if the property is an {@link Float} or float */ public boolean isFloat() { return isType(Float.class, float.class); } /** * Test if the property is an {@link Short} or short */ public boolean isShort() { return isType(Short.class, short.class); } /** * Test if the property is an {@link Long} or long */ public boolean isLong() { return isType(Long.class, long.class); } /** * Test if the property is an {@link Boolean} or boolean */ public boolean isBoolean() { return isType(Boolean.class, boolean.class); } /** * Test if the property is an {@link Date} or long */ public boolean isDate() { return isType(Date.class); } /** * Test if the property implements {@link Map} */ public boolean isMap() { return isType(Map.class); } /** * Test if the property implements {@link List} */ public boolean isList() { return isType(List.class); } /** * Test if the property implements {@link Set} */ public boolean isSet() { return isType(Set.class); } /** * Test if the property implements {@link Collection} */ public boolean isCollection() { return isType(Collection.class); } /** * Test if the property is an enum */ public boolean isEnum() { return type.isEnum(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof BeanProperty)) { return false; } BeanProperty rhs = (BeanProperty) obj; return new EqualsBuilder().append(declaringType, rhs.declaringType).append(name, rhs.name).isEquals(); } @Override public int hashCode() { return new HashCodeBuilder(23, 35).append(declaringType).append(this.name).toHashCode(); } @Override public String toString() { return "BeanProperty [" + declaringType + "." + name + "]"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy