Package net.sourceforge.retroweaver.runtime.java.lang.reflect

Source Code of net.sourceforge.retroweaver.runtime.java.lang.reflect.ReflectionDescriptor$WildcardTypeImpl

package net.sourceforge.retroweaver.runtime.java.lang.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import net.sourceforge.retroweaver.runtime.java.lang.TypeNotPresentException;
import net.sourceforge.retroweaver.runtime.java.lang.annotation.AIB;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

public class ReflectionDescriptor implements ClassVisitor {

  private static final boolean DEBUG = false;

  private static final Map<Class, ReflectionDescriptor> descriptors = new HashMap<Class, ReflectionDescriptor>();

  public static ReflectionDescriptor getReflectionDescriptor(Class class_) {
    synchronized (descriptors) {
      ReflectionDescriptor d = descriptors.get(class_);
      if (d == null) {
        d = new ReflectionDescriptor(class_);
        descriptors.put(class_, d);
        if (DEBUG) d.debugMessage("Adding descriptor");
      }
      return d;     
    }
  }

  private final Class class_;

  private ReflectionDescriptor(Class class_) {
    this.class_ = class_;
    String name = class_.getName();

    String resource = "/" + name.replace('.', '/') + ".class";
if (DEBUG) System.out.println("Reading class file: " + resource);
    InputStream classStream = class_.getResourceAsStream(resource);
    try {
      ClassReader r = new ClassReader(classStream);
      r.accept(this, ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG
          + ClassReader.SKIP_FRAMES);

    } catch (IOException e) {
      // Shouldn't generally happen
      throw new TypeNotPresentException(
          "[Retroweaver] Unable to read reflection data for: " + name, e);
    } finally {
      try {
        if (classStream != null) {
          classStream.close();
        }
      } catch (IOException e) { // NOPMD by xlv
      }
    }
  }

  private String internalName;

  private String enclosingClassName;

  private String enclosingMethodName;

  private String enclosingMethodDesc;

  public String getEnclosingClassName() {
    return enclosingClassName;
  }

  public void debugMessage(String msg) {
    System.out.println(msg +
        "\n\tclass: " + class_.getName() +
        "\n\tenclosingClassName: " + enclosingClassName +
        "\n\tenclosingMethodName: " + enclosingMethodName + ' ' + enclosingMethodDesc);
  }

  public Class getEnclosingClass() {
    //debugMessage("getEnclosingClass");
    if (enclosingClassName == null) {
      return null;
    }

    try {
      //debugMessage("getEnclosingClass");
      String name = enclosingClassName.replace('/', '.');
      Class c = class_.getClassLoader().loadClass(name);
   
      return c;
    } catch (ClassNotFoundException e) {
      return null;
    }
  }

  public Method getEnclosingMethod() {
    //debugMessage("getEnclosingMethod");
    if (enclosingMethodName == null) {
      return null;
    }

    return getMethod(getEnclosingClass(), enclosingMethodName, enclosingMethodDesc);
  }

  public Constructor getEnclosingConstructor() {
    //debugMessage("getEnclosingMethod");
    if (enclosingMethodName == null) {
      return null;
    }

    return getConstructor(getEnclosingClass(), enclosingMethodDesc);
  }

  private Method getMethod(Class class_, String name, String desc) {
    Type[] types = Type.getArgumentTypes(desc);

  outer_loop:
    for (Method m : class_.getDeclaredMethods()) {
      final Type[] methodTypes = Type.getArgumentTypes(m);
      if (!m.getName().equals(name)
          || methodTypes.length != types.length) {
        continue;
      }
      for (int i = 0; i < types.length; ++i) {
        if (!types[i].equals(methodTypes[i])) {
          continue outer_loop;
        }
      }
      return m;
    }
    return null;
  }

  private Constructor getConstructor(Class class_, String desc) {
    Type[] types = Type.getArgumentTypes(desc);

  outer_loop:
    for (Constructor c : class_.getDeclaredConstructors()) {
      final Class[] constructorTypes = c.getParameterTypes();
      if (constructorTypes.length != types.length) {
        continue;
      }
      for (int i = 0; i < types.length; ++i) {
        if (!types[i].equals(Type.getType(constructorTypes[i]))) {
          continue outer_loop;
        }
      }
      return c;
    }
    return null;
  }

  public TypeVariable[] getTypeParameters() throws GenericSignatureFormatError {
    throw new UnsupportedOperationException("NotImplemented");
  }

  public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type getGenericSuperclass() throws GenericSignatureFormatError, TypeNotPresentException, MalformedParameterizedTypeException {
    throw new UnsupportedOperationException("NotImplemented");
  }

  public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type[] getGenericInterfaces() throws GenericSignatureFormatError, TypeNotPresentException, MalformedParameterizedTypeException {
    throw new UnsupportedOperationException("NotImplemented");
  }

    /**
     * Visits the header of the class.
     *
     * @param version the class version.
     * @param access the class's access flags (see {@link Opcodes}). This
     *        parameter also indicates if the class is deprecated.
     * @param name the internal name of the class (see
     *        {@link Type#getInternalName() getInternalName}).
     * @param signature the signature of this class. May be <tt>null</tt> if
     *        the class is not a generic one, and does not extend or implement
     *        generic classes or interfaces.
     * @param superName the internal of name of the super class (see
     *        {@link Type#getInternalName() getInternalName}). For interfaces,
     *        the super class is {@link Object}. May be <tt>null</tt>, but
     *        only for the {@link Object} class.
     * @param interfaces the internal names of the class's interfaces (see
     *        {@link Type#getInternalName() getInternalName}). May be
     *        <tt>null</tt>.
     */
    public void visit(
            int version,
            int access,
            String name,
            String signature,
            String superName,
            String[] interfaces) {
      internalName = name;
    }

    public void visitSource(String source, String debug) {}

    /**
     * Visits the enclosing class of the class. This method must be called only
     * if the class has an enclosing class.
     *
     * @param owner internal name of the enclosing class of the class.
     * @param name the name of the method that contains the class, or
     *        <tt>null</tt> if the class is not enclosed in a method of its
     *        enclosing class.
     * @param desc the descriptor of the method that contains the class, or
     *        <tt>null</tt> if the class is not enclosed in a method of its
     *        enclosing class.
     */
    public void visitOuterClass(String owner, String name, String desc) {
      enclosingClassName = owner;
      enclosingMethodName = name;
      enclosingMethodDesc = desc;
      //debugMessage("visitOuterClass");
    }

    /**
     * Visits information about an inner class. This inner class is not
     * necessarily a member of the class being visited.
     *
     * @param name the internal name of an inner class (see
     *        {@link Type#getInternalName() getInternalName}).
     * @param outerName the internal name of the class to which the inner class
     *        belongs (see {@link Type#getInternalName() getInternalName}). May
     *        be <tt>null</tt>.
     * @param innerName the (simple) name of the inner class inside its
     *        enclosing class. May be <tt>null</tt> for anonymous inner
     *        classes.
     * @param access the access flags of the inner class as originally declared
     *        in the enclosing class.
     */
    public void visitInnerClass(
            String name,
            String outerName,
            String innerName,
            int access) {
      if (name.equals(internalName)) {
        if (outerName != null) {
          enclosingClassName = outerName;
        }
      }
      //debugMessage("visitInnerClass");
    }

    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
      return AIB.EMPTY_VISITOR;
    }

    public void visitAttribute(Attribute attr) {}

    public FieldVisitor visitField(
            int access,
            String name,
            String desc,
            String signature,
            Object value) { return null; }

    public MethodVisitor visitMethod(
            int access,
            String name,
            String desc,
            String signature,
            String[] exceptions) { return null; }

    public void visitEnd() {}

  public static class ClassTypeImpl implements net.sourceforge.retroweaver.runtime.java.lang.reflect.Type {
    private final String name;
   
    public ClassTypeImpl(String name) {
      this.name = name;
    }
  }

  public static class GenericArrayTypeImpl implements GenericArrayType {
    public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type getGenericComponentType() throws TypeNotPresentException, MalformedParameterizedTypeException {
      throw new UnsupportedOperationException("NotImplemented");
    }
  }

  public static class ParameterizedTypeImpl implements ParameterizedType {
    public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type[] getActualTypeArguments() throws TypeNotPresentException, MalformedParameterizedTypeException {
      throw new UnsupportedOperationException("NotImplemented");
    }

    public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type getOwnerType() {
      throw new UnsupportedOperationException("NotImplemented");
    }

    public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type getRawType() {
      throw new UnsupportedOperationException("NotImplemented");
    }
  }

  public static class TypeVariableImpl<D extends GenericDeclaration> implements net.sourceforge.retroweaver.runtime.java.lang.reflect.TypeVariable {
    private final String name;

    public TypeVariableImpl(String name) {
      this.name = name;
    }

    public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type[] getBounds() throws TypeNotPresentException, MalformedParameterizedTypeException {
      throw new UnsupportedOperationException("NotImplemented");
    }

    public D getGenericDeclaration() {
      throw new UnsupportedOperationException("NotImplemented");
    }

    public String getName() {
      return name;
    }
   
    public String toString() { return name; }
  }

  public static class WildcardTypeImpl implements WildcardType {
    public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type[] getLowerBounds() throws TypeNotPresentException, MalformedParameterizedTypeException {
      throw new UnsupportedOperationException("NotImplemented");
    }

    public net.sourceforge.retroweaver.runtime.java.lang.reflect.Type[] getUpperBounds() throws TypeNotPresentException, MalformedParameterizedTypeException {
      throw new UnsupportedOperationException("NotImplemented");
    }
  }

}
TOP

Related Classes of net.sourceforge.retroweaver.runtime.java.lang.reflect.ReflectionDescriptor$WildcardTypeImpl

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.