Package org.jboss.resteasy.links.impl

Source Code of org.jboss.resteasy.links.impl.BeanUtils

package org.jboss.resteasy.links.impl;

import org.jboss.resteasy.links.ParentResource;
import org.jboss.resteasy.links.ResourceID;
import org.jboss.resteasy.links.ResourceIDs;

import javax.persistence.Id;
import javax.xml.bind.annotation.XmlID;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BeanUtils {

  private static final Class<Annotation>[] IdAnnotationList = new Class[]{ResourceID.class, XmlID.class, Id.class};

  public static List<Object> findIDs(Object entity){
    Class<? extends Object> klass = entity.getClass();
    ResourceIDs resourceIDs = findTypeAnnotation(klass, ResourceIDs.class);
    if(resourceIDs != null){
      // return those properties
      String[] names = resourceIDs.value();
      List<Object> values = new ArrayList<Object>();
      for (String name : names) {
        try {
          values.add(getPropertyValue(entity, entity.getClass(), name));
        } catch (NotFoundException e) {
          throw new RuntimeException("Failed to find bean property "+name);
        }
      }
      return values;
    }
    for(Class<Annotation> idAnnotationClass : IdAnnotationList){
      try {
        return Collections.singletonList(findAnnotatedProperty(entity, klass, idAnnotationClass));
      } catch (NotFoundException e) {
        // ignore
      }
    }
    // we got nothing
    return Collections.emptyList();
  }

  private static Object getPropertyValue(Object entity,
      Class<?> klass, String name) throws NotFoundException {
    // easiest is a public property:
    try {
      return readPropertyMethods(entity, klass, name, false);
    } catch (NotFoundException e) {
      // ignore
    }
    // not found, try private properties
    do{
      try {
        return readPropertyMethods(entity, klass, name, true);
      } catch (NotFoundException e) {
        // ignore
      }
      // try the field
      try {
        Field f = klass.getDeclaredField(name);
        return readField(f, entity);
      } catch (SecurityException e) {
        // there's one but it's not accessible?
        throw new RuntimeException("Failed to read property "+name, e);
      } catch (NoSuchFieldException e) {
        // ignore
      }
      // go up
      klass = klass.getSuperclass();
    }while(klass != null);
    // we got nothing
    throw new NotFoundException();
  }

  private static Object readPropertyMethods(Object entity, Class<?> klass,
      String propertyName, boolean b) throws NotFoundException {
    try {
      return readPropertyMethod(entity, klass, "is"+capitalise(propertyName), false);
    } catch (NotFoundException e) {
      // ignore
    }
    // let this one throw
    return readPropertyMethod(entity, klass, "get"+capitalise(propertyName), false);
  }

  private static Object readPropertyMethod(Object entity, Class<?> klass,
      String methodName, boolean declared) throws NotFoundException {
    try{
      Method getter = declared ? klass.getDeclaredMethod(methodName) : klass.getMethod(methodName);
      return readMethod(getter, entity);
    } catch (SecurityException e) {
      // there's one but it's not accessible?
      throw new RuntimeException("Failed to read property "+methodName, e);
    } catch (NoSuchMethodException e) {
      throw new NotFoundException();
    }
  }

  private static String capitalise(String name) {
    return name.substring(0, 1).toUpperCase() + name.substring(1);
  }

  private static <T extends Annotation> T findTypeAnnotation(Class<?> klass,
      Class<T> annotationClass) {
    do{
      if(klass.isAnnotationPresent(annotationClass))
        return klass.getAnnotation(annotationClass);
      klass = klass.getSuperclass();
    }while(klass != null);
    return null;
  }

  public static Object findParentResource(Object entity) {
    try {
      return findAnnotatedProperty(entity, entity.getClass(), ParentResource.class);
    } catch (NotFoundException e) {
      return null;
    }
  }

  private static Object findAnnotatedProperty(Object entity, Class<?> type, Class<? extends Annotation> annotation) throws NotFoundException {
    for(Field f : type.getDeclaredFields()){
      if(f.isAnnotationPresent(annotation)){
        return readField(f, entity);
      }
    }
    for(Method m : type.getDeclaredMethods()){
      if(m.isAnnotationPresent(annotation) && isBeanAccessor(m)){
        return readMethod(m, entity);
      }
    }
    if(type.getSuperclass() != null)
      return findAnnotatedProperty(entity, type.getSuperclass(), annotation);
    throw new NotFoundException();
  }

  private static Object readMethod(Method m, Object entity) {
    // read that property
    m.setAccessible(true);
    try {
      return m.invoke(entity);
    } catch (Exception e) {
      throw new RuntimeException("Failed to read property from method "+m.getName(), e);
    }finally{
      m.setAccessible(false);
    }
  }

  private static Object readField(Field f, Object entity) {
    // read that field
    f.setAccessible(true);
    try {
      return f.get(entity);
    } catch (Exception e) {
      throw new RuntimeException("Failed to read field "+f.getName(), e);
    }finally{
      f.setAccessible(false);
    }
  }

  private static boolean isBeanAccessor(Method m) {
    String name = m.getName();
    return (name.startsWith("get") || name.startsWith("is")) && m.getParameterTypes().length == 0;
  }
}
TOP

Related Classes of org.jboss.resteasy.links.impl.BeanUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.