com.feilong.lib.javassist.tools.reflect.Metaobject Maven / Gradle / Ivy
Show all versions of feilong Show documentation
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package com.feilong.lib.javassist.tools.reflect;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* A runtime metaobject.
*
*
* A Metaobject
is created for
* every object at the base level. A different reflective object is
* associated with a different metaobject.
*
*
* The metaobject intercepts method calls
* on the reflective object at the base-level. To change the behavior
* of the method calls, a subclass of Metaobject
* should be defined.
*
*
* To obtain a metaobject, calls _getMetaobject()
* on a reflective object. For example,
*
*
*
* Metaobject m = ((Metalevel) reflectiveObject)._getMetaobject();
*
*
* @see com.feilong.lib.javassist.tools.reflect.ClassMetaobject
* @see com.feilong.lib.javassist.tools.reflect.Metalevel
*/
public class Metaobject implements Serializable{
/** default serialVersionUID */
private static final long serialVersionUID = 1L;
protected ClassMetaobject classmetaobject;
protected Metalevel baseobject;
protected Method[] methods;
/**
* Constructs a Metaobject
. The metaobject is
* constructed before the constructor is called on the base-level
* object.
*
* @param self
* the object that this metaobject is associated with.
* @param args
* the parameters passed to the constructor of
* self
.
*/
public Metaobject(Object self, Object[] args){
baseobject = (Metalevel) self;
classmetaobject = baseobject._getClass();
methods = classmetaobject.getReflectiveMethods();
}
/**
* Constructs a Metaobject
without initialization.
* If calling this constructor, a subclass should be responsible
* for initialization.
*/
protected Metaobject(){
baseobject = null;
classmetaobject = null;
methods = null;
}
private void writeObject(ObjectOutputStream out) throws IOException{
out.writeObject(baseobject);
}
private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException{
baseobject = (Metalevel) in.readObject();
classmetaobject = baseobject._getClass();
methods = classmetaobject.getReflectiveMethods();
}
/**
* Obtains the class metaobject associated with this metaobject.
*
* @see com.feilong.lib.javassist.tools.reflect.ClassMetaobject
*/
public final ClassMetaobject getClassMetaobject(){
return classmetaobject;
}
/**
* Obtains the object controlled by this metaobject.
*/
public final Object getObject(){
return baseobject;
}
/**
* Changes the object controlled by this metaobject.
*
* @param self
* the object
*/
public final void setObject(Object self){
baseobject = (Metalevel) self;
classmetaobject = baseobject._getClass();
methods = classmetaobject.getReflectiveMethods();
// call _setMetaobject() after the metaobject is settled.
baseobject._setMetaobject(this);
}
/**
* Returns the name of the method specified
* by identifier
.
*/
public final String getMethodName(int identifier){
String mname = methods[identifier].getName();
int j = ClassMetaobject.methodPrefixLen;
for (;;){
char c = mname.charAt(j++);
if (c < '0' || '9' < c){
break;
}
}
return mname.substring(j);
}
/**
* Returns an array of Class
objects representing the
* formal parameter types of the method specified
* by identifier
.
*/
public final Class>[] getParameterTypes(int identifier){
return methods[identifier].getParameterTypes();
}
/**
* Returns a Class
objects representing the
* return type of the method specified by identifier
.
*/
public final Class> getReturnType(int identifier){
return methods[identifier].getReturnType();
}
/**
* Is invoked when base-level method invocation is intercepted.
* This method simply executes the intercepted method invocation
* with the original parameters and returns the resulting value.
*
*
* Every subclass of this class should redefine this method.
*
*
* Note: this method is not invoked if the base-level method
* is invoked by a constructor in the super class. For example,
*
*
* abstract class A{
*
* abstract void initialize();
*
* A(){
* initialize(); // not intercepted
* }
* }
*
* class B extends A{
*
* void initialize(){
* System.out.println("initialize()");
* }
*
* B(){
* super();
* initialize(); // intercepted
* }
* }
*
*
*
* if an instance of B is created,
* the invocation of initialize() in B is intercepted only once.
* The first invocation by the constructor in A is not intercepted.
* This is because the link between a base-level object and a
* metaobject is not created until the execution of a
* constructor of the super class finishes.
*/
public Object trapMethodcall(int identifier,Object[] args) throws Throwable{
try{
return methods[identifier].invoke(getObject(), args);
}catch (java.lang.reflect.InvocationTargetException e){
throw e.getTargetException();
}catch (java.lang.IllegalAccessException e){
throw new CannotInvokeException(e);
}
}
}