Package com.habitsoft.kiyaa.rebind.typeinfo

Source Code of com.habitsoft.kiyaa.rebind.typeinfo.RuntimeClassWrapper$RuntimeMethodWrapper

/**
*
*/
package com.habitsoft.kiyaa.rebind.typeinfo;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;

import com.google.gwt.core.ext.typeinfo.JClassType;
import com.habitsoft.kiyaa.util.Name;

public class RuntimeClassWrapper implements GeneratorTypeInfo {
  private static final class RuntimeMethodWrapper extends GeneratorMethodInfo {
    private final Method m;

    private RuntimeMethodWrapper(String name, GeneratorTypeInfo returnType, GeneratorTypeInfo[] parameterTypes, String[] parameterNames,
        GeneratorTypeInfo asyncReturnType, Method m) {
      super(name, returnType, parameterTypes, parameterNames, asyncReturnType);
      this.m = m;
    }

    @Override
    public boolean isAbstract() {
      return (m.getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT || m.getDeclaringClass().isInterface();
    }
    @Override
    public <T extends Annotation> T getAnnotation(Class<T> annotationToLookFor) {
      return m.getAnnotation(annotationToLookFor);
    }
    @Override
    public String toString() {
      return m.toString();
    }
  }

  public static final RuntimeClassWrapper OBJECT = new RuntimeClassWrapper(Object.class);
  public static final RuntimeClassWrapper STRING = new RuntimeClassWrapper(String.class);

  final Class<?> clazz;
 
  private HashMap<String, ArrayList<GeneratorMethodInfo>> methods;
  private HashMap<String, ArrayList<GeneratorMethodInfo>> staticMethods;
 
  protected RuntimeClassWrapper(Class<?> clazz) {
    super();
    this.clazz = clazz;
  }

  @Override
  public ExpressionInfo findAccessors(String prefix, String expr) {
    return null;
  }

  @Override
  public String getName() {
    return clazz.getName();
  }

  @Override
  public String toString() {
    return clazz.toString();
  }
 
  @Override
  public boolean implementsInterface(GeneratorTypeInfo iface) {
    try {
      return Class.forName(iface.getName()).isAssignableFrom(clazz);
    } catch (ClassNotFoundException e) {
      // Can't implement an interface that does not exist
      return false;
    }
  }
 
  public boolean equals(GeneratorTypeInfo otherType) {
    return this == otherType || (otherType != null && getName().equals(otherType.getName()));
  }
 
  @Override
  public boolean equals(Object other) {
    return this == other || (other instanceof GeneratorMethodInfo && this.equals((GeneratorTypeInfo)other));
  }
 
  @Override
  public String getParameterizedQualifiedSourceName() {
    return getName();
  }
 
  @Override
  public boolean hasStaticMethodMatching(String name, GeneratorTypeInfo desiredReturnType, GeneratorTypeInfo... parameterTypes) {
    if(staticMethods == null) {
      loadMethods();
    }
   
    return GeneratorMethodInfo.checkForMethod(staticMethods, name, true, true, desiredReturnType, parameterTypes);
  }

 
  @Override
  public boolean hasMethodMatching(String name, boolean matchAbstract, GeneratorTypeInfo desiredReturnType, GeneratorTypeInfo... parameterTypes) {
    if(methods == null) {
      loadMethods();
    }
    return GeneratorMethodInfo.checkForMethod(methods, name, matchAbstract, true, desiredReturnType, parameterTypes);
  }

  @Override
  public GeneratorMethodInfo findMethodMatching(String name, boolean allowCastable, GeneratorTypeInfo returnType, GeneratorTypeInfo... parameterTypes) {
    if(methods == null) {
      loadMethods();
    }
    return GeneratorMethodInfo.findMethod(methods, name, allowCastable, returnType, parameterTypes);
  }
 
  @Override
  public GeneratorMethodInfo findStaticMethodMatching(String name, boolean allowCastable, GeneratorTypeInfo returnType, GeneratorTypeInfo... parameterTypes) {
    if(staticMethods == null) {
      loadMethods();
    }
    return GeneratorMethodInfo.findMethod(staticMethods, name, allowCastable, returnType, parameterTypes);
  }
 
  /**
   * Load all methods available on this class into a cache for quick lookups
   */
  private void loadMethods() {
    methods = new HashMap<String, ArrayList<GeneratorMethodInfo>>();
    for(Method m : clazz.getMethods()) {
      if((m.getModifiers() & Modifier.STATIC) == 0) {
        addMethod(m, methods);
      }
    }
    staticMethods = new HashMap<String, ArrayList<GeneratorMethodInfo>>();
    for(Method m : clazz.getDeclaredMethods()) {
      if((m.getModifiers() & Modifier.STATIC) == Modifier.STATIC) {
        addMethod(m, staticMethods);
      }
    }
  }

  /**
   * Helper method to convert a java.lang.reflect.Method into a GeneratorMethodInfo
   * and add it to the methods map.
   */
  static void addMethod(final Method m, HashMap<String, ArrayList<GeneratorMethodInfo>> map) {
    String name = m.getName();
    Name nameAnnotation = m.getAnnotation(Name.class);
    if(nameAnnotation != null) name = nameAnnotation.value();
    ArrayList<GeneratorMethodInfo> overloads = map.get(name);
    if(overloads == null) map.put(m.getName(), overloads = new ArrayList<GeneratorMethodInfo>());
    GeneratorTypeInfo[] parameterTypes = new GeneratorTypeInfo[m.getParameterTypes().length];
    for(int i=0; i < parameterTypes.length; i++) {
      parameterTypes[i] = wrap(m.getParameterTypes()[i]);
    }
    GeneratorTypeInfo returnType = wrap(m.getReturnType());
    overloads.add(new RuntimeMethodWrapper(m.getName(), returnType, parameterTypes, null, null, m));
  }

  @Override
  public boolean isSubclassOf(GeneratorTypeInfo potentialSuperclass) {
    for(Class<?> superclass = clazz; superclass != null; superclass = superclass.getSuperclass()) {
      if(superclass.equals(potentialSuperclass))
        return true;
    }
    return false;
  }

  @Override
  public boolean isPrimitive() {
    return clazz.isPrimitive();
  }

  @Override
  public boolean isStatic() {
    return (clazz.getModifiers() & Modifier.STATIC) == Modifier.STATIC;
  }

  @Override
  public boolean isAbstract() {
    return (clazz.getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT;
  }

  @Override
  public GeneratorTypeInfo getEnclosingType() {
    return wrap(clazz.getEnclosingClass());
  }

  @Override
  public String getSimpleSourceName() {
    return clazz.getSimpleName();
  }

  @Override
  public boolean isEnum() {
    return clazz.isEnum();
  }

  transient TreeSet<String> enumMembers;
  @Override
  public Set<String> getEnumMembers() throws IllegalStateException {
    if(!clazz.isEnum())
      return null;
    enumMembers = new TreeSet<String>();
    for(Object ec : clazz.getEnumConstants()) {
      try {
        enumMembers.add((String)ec.getClass().getMethod("name").invoke(ec));
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return enumMembers;
  }

  @Override
  public JClassType getJClassType() {
    return null;
  }

  @Override
  public boolean isArray() {
    return clazz.isArray();
  }

  @Override
  public GeneratorTypeInfo getComponentType() {
    return wrap(clazz.getComponentType());
  }
 
  private static HashMap<Class<?>, RuntimeClassWrapper> cache = new HashMap<Class<?>, RuntimeClassWrapper>();
 
  /**
   * Get a class info for the given class.  Uses a cache to re-use the same instance
   * over and over which can be useful sometimes.
   */
  public static RuntimeClassWrapper wrap(Class<?> clazz) {
    if(clazz == null)
      return null;
    if(clazz.isPrimitive())
      return PrimitiveTypeInfo.valueOf(clazz.getName());
    RuntimeClassWrapper result = cache.get(clazz);
    if(result != null)
      return result;
    cache.put(clazz, result = new RuntimeClassWrapper(clazz));
    return result;
  }

  @Override
  public GeneratorTypeInfo getFieldType(String name, boolean allowProtected) {
    Field field;
    try {
      field = clazz.getField(name);
    } catch (NoSuchFieldException e) {
      return null;
    }
    if((field.getModifiers() & (Modifier.PUBLIC | (allowProtected ? Modifier.PROTECTED : 0))) != 0) {
      return wrap(field.getType());
    }
    return null;
  }
 
}
TOP

Related Classes of com.habitsoft.kiyaa.rebind.typeinfo.RuntimeClassWrapper$RuntimeMethodWrapper

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.