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

play.utils.Java Maven / Gradle / Ivy

There is a newer version: 2.6.2
Show newest version
package play.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import play.mvc.With;

/**
 * Java utils
 */
public class Java {

  protected static JavaWithCaching _javaWithCaching = new JavaWithCaching();

  protected static JavaWithCaching getJavaWithCaching() {
    return _javaWithCaching;
  }

  /**
   * Retrieve parameter names of a method
   *
   * @param method The given method
   * @return Array of parameter names
   */
  public static String[] parameterNames(Method method) {
    Parameter[] parameters = method.getParameters();
    String[] names = new String[parameters.length];
    for (int i = 0; i < parameters.length; i++) {
      names[i] = parameters[i].getName();
    }
    return names;
  }

  /**
   * Find all annotated method from a class
   *
   * @param clazz          The class
   * @param annotationType The annotation class
   * @return A list of method object
   */
  public static List findAllAnnotatedMethods(
      Class clazz, Class annotationType) {
    return getJavaWithCaching().findAllAnnotatedMethods(clazz, annotationType);
  }

  public static byte[] serialize(Object o) throws IOException {
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
      try (ObjectOutputStream oo = new ObjectOutputStream(baos)) {
        oo.writeObject(o);
        oo.flush();
      }
      return baos.toByteArray();
    }
  }

  public static Object deserialize(byte[] b) throws IOException, ClassNotFoundException {
    try (ByteArrayInputStream bais = new ByteArrayInputStream(b)) {
      try (ObjectInputStream oi = new ObjectInputStream(bais)) {
        return oi.readObject();
      }
    }
  }
}

/**
 * This is an internal class uses only by the Java-class. It contains functionality with caching..
 *
 * 

The idea is that the Java-objects creates a new instance of JavaWithCaching, each time * something new is compiled.. */ class JavaWithCaching { /** * Class uses as key for storing info about the relation between a Class and an Annotation */ private static class ClassAndAnnotation { private final Class clazz; private final Class annotation; private ClassAndAnnotation(Class clazz, Class annotation) { this.clazz = clazz; this.annotation = annotation; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ClassAndAnnotation that = (ClassAndAnnotation) o; if (annotation != null ? !annotation.equals(that.annotation) : that.annotation != null) { return false; } return clazz != null ? clazz.equals(that.clazz) : that.clazz == null; } @Override public int hashCode() { int result = clazz != null ? clazz.hashCode() : 0; result = 31 * result + (annotation != null ? annotation.hashCode() : 0); return result; } } // cache follows.. private final Object classAndAnnotationsLock = new Object(); private final Map> classAndAnnotation2Methods = new HashMap<>(); private final Map, List> class2AllMethodsWithAnnotations = new HashMap<>(); /** * Find all annotated method from a class * * @param clazz The class * @param annotationType The annotation class * @return A list of method object */ public List findAllAnnotatedMethods( Class clazz, Class annotationType) { if (clazz == null) { return new ArrayList<>(0); } synchronized (classAndAnnotationsLock) { // first look in cache ClassAndAnnotation key = new ClassAndAnnotation(clazz, annotationType); List methods = classAndAnnotation2Methods.get(key); if (methods != null) { // cache hit return methods; } // have to resolve it. methods = new ArrayList<>(); // get list of all annotated methods on this class.. for (Method method : findAllAnnotatedMethods(clazz)) { if (method.isAnnotationPresent(annotationType)) { methods.add(method); } } sortByPriority(methods, annotationType); // store it in cache classAndAnnotation2Methods.put(key, methods); return methods; } } private void sortByPriority( List methods, final Class annotationType) { try { final Method priority = annotationType.getMethod("priority"); methods.sort( (m1, m2) -> { try { Integer priority1 = (Integer) priority.invoke(m1.getAnnotation(annotationType)); Integer priority2 = (Integer) priority.invoke(m2.getAnnotation(annotationType)); return priority1.compareTo(priority2); } catch (Exception e) { // Should not happen throw new RuntimeException(e); } }); } catch (NoSuchMethodException e) { // No need to sort - this annotation doesn't have priority() method } } /** * Find all annotated method from a class * * @param clazz The class * @return A list of method object */ public List findAllAnnotatedMethods(Class clazz) { synchronized (classAndAnnotationsLock) { // First check the cache. List methods = class2AllMethodsWithAnnotations.get(clazz); if (methods != null) { // Cache hit return methods; } // Have to resolve it. methods = new ArrayList<>(); // Clazz can be null if we are looking at an interface / annotation while (clazz != null && !clazz.equals(Object.class)) { for (Method method : clazz.getDeclaredMethods()) { if (method.getAnnotations().length > 0) { methods.add(method); } } if (clazz.isAnnotationPresent(With.class)) { for (Class withClass : clazz.getAnnotation(With.class).value()) { methods.addAll(findAllAnnotatedMethods(withClass)); } } clazz = clazz.getSuperclass(); } // Store it in the cache. class2AllMethodsWithAnnotations.put(clazz, methods); return methods; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy