Package anvil.core.reflect

Source Code of anvil.core.reflect.Reflection

/*
* $Id: Reflection.java,v 1.10 2002/09/16 08:05:03 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core.reflect;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Constructor;
import java.util.Enumeration;
import anvil.core.Any;
import anvil.core.AnyClass;
import anvil.core.AnyAbstractClass;
import anvil.core.ObjectPool;
import anvil.core.Register;
import anvil.java.util.Hashlist;
import anvil.java.util.BindingEnumeration;
import anvil.script.Context;
import anvil.script.Type;
import anvil.script.ClassDispatcher;
import anvil.script.ClassType;
import anvil.script.InterfaceType;
import anvil.script.InterfaceRef;
import anvil.script.ClassRef;
import anvil.script.ConstantVariableType;
import anvil.script.StaticVariableType;
import anvil.script.VariableType;
import anvil.script.Scope;
import anvil.script.ScriptException;
import anvil.script.ReflectedJava;
import anvil.script.CompilableFunction;
import anvil.script.compiler.ResolvedClassRef;
import anvil.script.compiler.ResolvedInterfaceRef;
import anvil.doc.Doc;

public class Reflection
  extends AnyAbstractClass
  implements ClassType, InterfaceType, ParameterTypes, ReflectedJava
{

  private PackageReflection _parent;
  private ClassRef _superref = null;
  private Reflection _super = null;
  private String _name;
  private Class _class;
  private int _arraytype = -1;
  private InterfaceRef[] _interfaces;
  private InterfaceRef[] _bases;
  private ConstructorTree _ctor = null;
  private Hashlist _declarations = new Hashlist();
  private Hashlist _methods = new Hashlist();


  public Reflection()
  {
  }
 

  public Reflection(Class cls)
  {
    initialize(cls);
  }

   
 
  public void initialize(Class cls)
  {
    _name = cls.getName();
    _class = cls;
    _parent = ObjectPool.createReflection(cls.getPackage());
    _parent.addClass(this);
    if (cls.isArray()) {
      Class elemtype = cls.getComponentType();
      if (elemtype == Boolean.TYPE) {
        _arraytype = BOOLEAN;
      } else if (elemtype == Byte.TYPE) {
        _arraytype = BYTE;
      } else if (elemtype == Short.TYPE) {
        _arraytype = SHORT;
      } else if (elemtype == Integer.TYPE) {
        _arraytype = INT;
      } else if (elemtype == Long.TYPE) {
        _arraytype = LONG;
      } else if (elemtype == Float.TYPE) {
        _arraytype = FLOAT;
      } else if (elemtype == Double.TYPE) {
        _arraytype = DOUBLE;
      } else if (Any.class.isAssignableFrom(elemtype)) {
        _arraytype = ANVIL_CORE_ANY;
      } else {
        _arraytype = JAVA_LANG_OBJECT;
      }
    }

    Class supercls = cls.getSuperclass();
    if (supercls != null) {
      _super = ObjectPool.createReflection(supercls);
      _superref = new ResolvedClassRef(_super);
    }
   
    if (Modifier.isPublic(cls.getModifiers())) {

      Method[] methods = cls.getDeclaredMethods();
      int n = methods.length;
      for(int i=0; i<n; i++) {
        insertMethod(methods[i]);
      }
     
      Constructor[] ctors = cls.getDeclaredConstructors();
      n = ctors.length;
      for(int i=0; i<n; i++) {
        insertConstructor(ctors[i]);
      }
   
      Field[] fields = cls.getDeclaredFields();
      for(int i=0; i<fields.length; i++) {
        Field field = fields[i];
        int modifier = field.getModifiers();
        if (Modifier.isPublic(modifier)) {
          String name = field.getName();
          if (Modifier.isStatic(modifier)) {
            if (Modifier.isFinal(modifier)) {
              addDeclaration(field.getName(),
                new ReflectedConstantVariable(this, name, field, null));
            } else {
              addDeclaration(field.getName(), new AdaptiveClassVariable(name, field, this));
            }
          } else {
            addDeclaration(field.getName(), new AdaptiveMemberVariable(name, field, this));
          }
        }
      }

      Class[] classes = cls.getDeclaredClasses();
      n = classes.length;
      for(int i=0; i<n; i++) {
        Class innercls = classes[i];
        if (Modifier.isPublic(innercls.getModifiers())) {
          Reflection ref = ObjectPool.createReflection(innercls);
          String name = innercls.getName().substring(_name.length()+1);
          addDeclaration(name, ref);
        }
      }

      Class[] interfaces = cls.getInterfaces();
      n = interfaces.length;
      _interfaces = new ResolvedInterfaceRef[n];
      for(int i=0; i<n; i++) {
        Class iface = interfaces[i];
        if (Modifier.isPublic(iface.getModifiers())) {
          _interfaces[i] = new ResolvedInterfaceRef(ObjectPool.createReflection(iface));
        }
      }

    }
   
    Reflection ref = _super;
    while(ref != null) {
      Enumeration enum = ref.getDeclarations();
      while(enum.hasMoreElements()) {
        Type type = (Type)enum.nextElement();
        String name = type.getName();
        addDeclaration(name, type);
        if (type.getType() == METHOD) {
          addMethod(name, type);
        }
      }
      ref = ref._super;
    }

  }


  private void addDeclaration(String name, Type type)
  {
    if (!_declarations.containsKey(name)) {
      _declarations.put(name, type);
    }
  }
 
  private void addMethod(String name, Type type)
  {
    if (!_methods.containsKey(name)) {
      _methods.put(name, type);
      _methods.put(new Integer(Register.register(name)), type);
    }
  }

  private void insertMethod(Method method)
  {
    if (Modifier.isPublic(method.getModifiers())) {
      String name = method.getName();
      MethodTree tree = (MethodTree)_methods.get(name);
      if (tree == null)  {
        tree = new MethodTree(this, name);
        addDeclaration(name, tree);
        addMethod(name, tree);
      }
      tree.insert(method, method.getParameterTypes());
    }
  }


  private void insertConstructor(Constructor ctor)
  {
    if (Modifier.isPublic(ctor.getModifiers())) {
      if (_ctor == null) {
        _ctor = new ConstructorTree(this, _name);
      }
      _ctor.insert(ctor, ctor.getParameterTypes());
    }
  }


  public String getSignature()
  {
    return _class.getName().replace('.', '/');
  }


  public Class getJavaClass()
  {
    return _class;
  }

  public anvil.script.ClassType classOf()
  {
    return this;
  }


  public boolean isInstanceOf(Type ofType)
  {
    if (ofType instanceof Reflection) {
      Reflection reflection = (Reflection)ofType;
      return reflection._class.isAssignableFrom(_class);
    }
    return false;
  }
  public String toString()
  {
    return "class " + _class.getName();
  }


  public Object toObject()
  {
    return _class;
  }
 

  public String getName()
  {
    return _name;
  }
 

  public String getQualifiedName()
  {
    return _name;
  }


  public int getType()
  {
    return _class.isInterface() ? INTERFACE : CLASS;
  }

  public Scope getParent()
  {
    return _parent;
  }
 

  public ClassType[] getEnclosingClasses()
  {
    return new ClassType[0];
  }
 

  public String getPathinfo()
  {
    return "";
  }


  public BindingEnumeration getMembers(AnyClass instance)
  {
    return BindingEnumeration.EMPTY;
  }


  public Doc getDocument()
  {
    return Doc.EMPTY_DOC;
  }


  public Enumeration getDeclarations()
  {
    return _declarations.elements();
  }
 

  public Type lookupDeclaration(String name)
  {
    return (Type)_declarations.get(name);
  }
 

  public ClassRef getBase()
  {
    return _superref;
  }
 
  public ClassType getBaseClass()
  {
    return _super;
  }
 

  public Type lookupInheritedDeclaration(String name)
  {
    if (_super != null) {
      return _super.lookupDeclaration(name);
    }
    return null;
  }


  public InterfaceRef[] getInterfaces()
  {
    return _interfaces;
  }


  public InterfaceRef[] getBases()
  {
    return _interfaces;
  }
 

  public CompilableFunction getConstructor()
  {
    if (_ctor == null) {
      return _super.getConstructor();
    }
    return _ctor;
  }
 
 
  public AnyClass newInstance()
  {
    return null;
  }
 
 
  public boolean hasMethod(String name)
  {
    if (_methods.containsKey(name)) {
      return true;
    }
    if (_super != null) {
      return _super.has(name);
    }
    return false;
  }
 
 
  public Any getAttribute(Context context, String attribute)
  {
    Type type = (Type)_declarations.get(attribute);
    if (type != null) {
      switch(type.getType()) {
      case Type.STATIC_VARIABLE:
      case Type.CONSTANT_VARIABLE:
        return ((StaticVariableType)type).getValue();
      case Type.CLASS:
      case Type.INTERFACE:
        return (Reflection)type;
      }
    }
    return Any.UNDEFINED;
  }


  public Any checkAttribute(Context context, String attribute)
  {
    return getAttribute(context, attribute);
  }
 
 
  public Any setAttribute(Context context, String attribute, Any value)
  {
    Type type = (Type)_declarations.get(attribute);
    if (type != null) {
      if (type.getType() == Type.STATIC_VARIABLE) {
        return ((VariableType)type).setValue(value);
      }
    }
    return value;
  }
   


  public Any getReference(Context context, Any index)
  {
    if (index.isInt()) {
      return Any.create(Array.newInstance(_class, index.toInt()));
     
    } else if (index.isTuple()) {
      int n = index.sizeOf();
      Any[] list = index.toTuple();
      int dims[] = new int[n];
      for(int i=0; i<n; i++) {
        dims[i] = list[i].toInt();
      }
      return Any.create(Array.newInstance(_class, dims));
     
    } else {
      Type type = (Type)_declarations.get(index.toString());
      if (type != null) {
        switch(type.getType()) {
        case Type.STATIC_VARIABLE:
        case Type.CONSTANT_VARIABLE:
          return ((VariableType)type).getValue();
        case Type.CLASS:
        case Type.INTERFACE:
          return (Reflection)type;
        }
      }
    }
    return Any.UNDEFINED;
  }
 
 
  public Any checkReference(Context context, Any index)
  {
    return getReference(context, index);
  }
 

  public Any setReference(Context context, Any index, Any value)
  {
    Type type = (Type)_declarations.get(index.toString());
    if (type != null) {
      if (type.getType() == Type.STATIC_VARIABLE) {
        return ((StaticVariableType)type).setValue(value);
      }
    }
    return value;
  }
 


  public Any invoke(Context context, Object instance, int methodIndex, Any[] parameters)
  {
    ParameterTree tree = (ParameterTree)_methods.get(ObjectPool.createInteger(methodIndex));
    if (tree != null) {
      return tree.invoke(context, instance, parameters);
    } else {
      throw context.NoSuchMethod(_name, methodIndex);
    }
  }


  public Any invoke(Context context, Object instance, String methodName, Any[] parameters)
  {
    ParameterTree tree = (ParameterTree)_methods.get(methodName);
    if (tree != null) {
      return tree.invoke(context, instance, parameters);
    } else {
      throw context.NoSuchMethod(_name + '.' + methodName);
    }
  }

  public Any invoke(Context context, int methodIndex, Any[] parameters)
  {
    return invoke(context, null, methodIndex, parameters);
  }

  public Any invoke(Context context, int methodIndex)
  {
    return invoke(context, null, methodIndex, Any.ARRAY0);
  }

  public Any invoke(Context context, int methodIndex, Any param1)
  {
    return invoke(context, null, methodIndex, new Any[] { param1 });
  }

  public Any invoke(Context context, int methodIndex, Any param1, Any param2)
  {
    return invoke(context, null, methodIndex, new Any[] { param1, param2 });
  }

  public Any invoke(Context context, int methodIndex, Any param1, Any param2, Any param3)
  {
    return invoke(context, null, methodIndex, new Any[] { param1, param2, param3 });
  }

  public Any invoke(Context context, int methodIndex, Any param1, Any param2, Any param3, Any param4)
  {
    return invoke(context, null, methodIndex, new Any[] { param1, param2, param3, param4 });
  }
 
 
  public Any invoke(Context context, String methodName, Any[] parameters)
  {
    return invoke(context, null, methodName, parameters);
  }
 
  public Any invoke(Context context, String methodName)
  {
    return invoke(context, null, methodName, Any.ARRAY0);
  }

  public Any invoke(Context context, String methodName, Any param1)
  {
    return invoke(context, null, methodName, new Any[] { param1 });
  }

  public Any invoke(Context context, String methodName, Any param1, Any param2)
  {
    return invoke(context, null, methodName, new Any[] { param1, param2 });
  }

  public Any invoke(Context context, String methodName, Any param1, Any param2, Any param3)
  {
    return invoke(context, null, methodName, new Any[] { param1, param2, param3 });
  }

  public Any invoke(Context context, String methodName, Any param1, Any param2, Any param3, Any param4)
  {
    return invoke(context, null, methodName, new Any[] { param1, param2, param3, param4 });
  }


  public ClassDispatcher getDispatcher(Context context)
  {
    return null;
  }
 
  public Any execute(Context context, Any[] parameters)
  {
    if (_ctor != null) {
      return _ctor.invoke(context, null, parameters);
    } else {
      return UNDEFINED;
    }
  }

  public Any execute(Context context)
  {
    if (_ctor != null) {
      return _ctor.invoke(context, null, Any.ARRAY0);
    } else {
      return UNDEFINED;
    }
  }

  public Any execute(Context context, Any param1)
  {
    if (_ctor != null) {
      return _ctor.invoke(context, null, new Any[] { param1 });
    } else {
      return UNDEFINED;
    }
  }
 
  public Any execute(Context context, Any param1, Any param2)
  {
    if (_ctor != null) {
      return _ctor.invoke(context, null, new Any[] { param1, param2 });
    } else {
      return UNDEFINED;
    }
  }
 
  public Any execute(Context context, Any param1, Any param2, Any param3)
  {
    if (_ctor != null) {
      return _ctor.invoke(context, null, new Any[] { param1, param2, param3 });
    } else {
      return UNDEFINED;
    }
  }
 
  public Any execute(Context context, Any param1, Any param2, Any param3, Any param4)
  {
    if (_ctor != null) {
      return _ctor.invoke(context, null, new Any[] { param1, param2, param3, param4 });
    } else {
      return UNDEFINED;
    }
  }

  public String getDescriptor()
  {
    return null;
  }
 

  public int getTypeRef(anvil.codec.ConstantPool pool)
  {
    return 0;
  }


  public int getConstructorReference(anvil.codec.ConstantPool pool)
  {
    return 0;
  }
 
 
  public Any arrayGet(Object array, int index)
  {
    switch(_arraytype) {
    case BOOLEAN:
      return Array.getBoolean(array, index) ? TRUE : FALSE;
   
    case BYTE: 
      return Any.create(Array.getByte(array, index));
     
    case CHAR:
      return Any.create(Array.getChar(array, index));
     
    case SHORT:
      return Any.create(Array.getShort(array, index));

    case INT: 
      return Any.create(Array.getInt(array, index));

    case LONG:
      return Any.create(Array.getLong(array, index));
     
    case FLOAT:
      return Any.create(Array.getFloat(array, index));
     
    case DOUBLE:
      return Any.create(Array.getDouble(array, index));
    
    case JAVA_LANG_OBJECT:
      return Any.create(Array.get(array, index));

    case ANVIL_CORE_ANY:
      return (Any)Array.get(array, index);
     
    default:
      return UNDEFINED;
    }
  } 

  public void arraySet(Object array, int index, Any value)
  {
    switch(_arraytype) {
    case BOOLEAN:
      Array.setBoolean(array, index, value.toBoolean());
      return;
   
    case BYTE: 
      Array.setByte(array, index, (byte)value.toInt());
      return;
     
    case CHAR:
      Array.setChar(array, index, value.toChar());
      return;
     
    case SHORT:
      Array.setShort(array, index, (short)value.toInt());
      return;

    case INT: 
      Array.setInt(array, index, value.toInt());
      return;

    case LONG:
      Array.setLong(array, index, value.toLong());
      return;
     
    case FLOAT:
      Array.setFloat(array, index, (float)value.toDouble());
      return;
     
    case DOUBLE:
      Array.setDouble(array, index, value.toDouble());
      return;
    
    case JAVA_LANG_OBJECT:
      Array.set(array, index, value.toObject());
      return;

    case ANVIL_CORE_ANY:
      Array.set(array, index, value);
      return;
    }
  } 


  public boolean isArray()
  {
    return _class.isArray();
  }

  public int arrayLength(Object array)
  {
    if (_class.isArray()) {
      return ((Object[])array).length;
    }
    return 0;
  }

   
}
TOP

Related Classes of anvil.core.reflect.Reflection

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.