br.com.anteros.bean.validation.util.PropertyAccess Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Anteros-Bean-Validation Show documentation
Show all versions of Anteros-Bean-Validation Show documentation
Anteros Bean Validation for Java.
/*******************************************************************************
* Copyright 2012 Anteros Tecnologia
*
* 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 br.com.anteros.bean.validation.util;
import java.lang.annotation.ElementType;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import br.com.anteros.core.utils.ReflectionUtils;
/**
* Description: Undefined dynamic strategy (FIELD or METHOD access) Uses PropertyUtils or tries to determine field to
* access the value
*/
public class PropertyAccess extends AccessStrategy {
private final Class> beanClass;
private final String propertyName;
private Field rememberField;
/**
* Create a new PropertyAccess instance.
*
* @param clazz
* @param propertyName
*/
public PropertyAccess(Class> clazz, String propertyName) {
this.beanClass = clazz;
this.propertyName = propertyName;
}
/**
* {@inheritDoc}
*/
public ElementType getElementType() {
return rememberField != null ? ElementType.FIELD : ElementType.METHOD;
}
private static Object getPublicProperty(Object bean, String property) throws InvocationTargetException,
NoSuchMethodException, IllegalAccessException {
if (bean instanceof Map, ?>) {
return ((Map, ?>) bean).get(property);
} else {
Method getter = ReflectionUtils.getGetterOrNull(bean.getClass(), property);
if (getter==null){
return getter.invoke(bean);
}
}
return null;
}
/**
* Get a named property from bean
.
*
* @param bean
* @param propertyName
* @return Object found
* @throws InvocationTargetException
* @throws NoSuchMethodException
* @throws IllegalAccessException
*/
public static Object getProperty(Object bean, String propertyName) throws InvocationTargetException,
NoSuchMethodException, IllegalAccessException {
return new PropertyAccess(bean.getClass(), propertyName).get(bean);
}
/**
* {@inheritDoc}
*/
public String toString() {
return "Property{" + beanClass.getName() + '.' + propertyName + '}';
}
/**
* {@inheritDoc}
*/
public Type getJavaType() {
Type result = getTypeInner();
return result == null ? Object.class : result;
}
/**
* Learn whether this {@link PropertyAccess} references a known property.
*
* @return boolean
*/
public boolean isKnown() {
return getTypeInner() != null;
}
/**
* Find out what, if any, type can be calculated.
*
* @return type found or null
*/
private Type getTypeInner() {
if (rememberField != null) {
return rememberField.getGenericType();
}
Method readMethod = getPropertyReadMethod(propertyName, beanClass);
if (readMethod != null) {
return readMethod.getGenericReturnType();
}
Field fld = getField(propertyName, beanClass);
if (fld != null) {
cacheField(fld);
return rememberField.getGenericType();
}
return null;
}
private static Method getPropertyReadMethod(String propertyName, Class> beanClass) {
return ReflectionUtils.getGetterOrNull(beanClass, propertyName);
}
private static Field getField(String propertyName, Class> beanClass) {
try {
return beanClass.getField(propertyName);
} catch (NoSuchFieldException ex2) {
Class> theClass = beanClass;
while (theClass != null) {
try {
return theClass.getDeclaredField(propertyName);
} catch (NoSuchFieldException ex3) {
}
theClass = theClass.getSuperclass();
}
}
return null;
}
/**
* {@inheritDoc}
*/
public String getPropertyName() {
return propertyName;
}
/**
* {@inheritDoc}
*/
public Object get(Object bean) {
try {
if (rememberField != null) { // cache field of previous access
return rememberField.get(bean);
}
try { // try public method
return getPublicProperty(bean, propertyName);
} catch (NoSuchMethodException ex) {
return getFieldValue(bean);
}
} catch (IllegalArgumentException e) {
throw e;
} catch (Exception e) {
throw new IllegalArgumentException("cannot access " + propertyName, e);
}
}
private Object getFieldValue(Object bean) throws IllegalAccessException {
Field field = getField(propertyName, beanClass);
if (field != null) {
cacheField(field);
return rememberField.get(bean);
}
throw new IllegalArgumentException("cannot access field " + propertyName);
}
private void cacheField(Field field) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
this.rememberField = field;
}
/**
* {@inheritDoc}
*/
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PropertyAccess that = (PropertyAccess) o;
return beanClass.equals(that.beanClass) && propertyName.equals(that.propertyName);
}
/**
* {@inheritDoc}
*/
public int hashCode() {
int result;
result = beanClass.hashCode();
result = 31 * result + propertyName.hashCode();
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy