Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
research:software:reflex:documentation:call_descriptors_parameters [2007/08/13 16:12] adminresearch:software:reflex:documentation:call_descriptors_parameters [2007/08/24 19:16] (current) rtoledo
Line 1: Line 1:
 +====== Call Descriptor & Parameters ======
  
 +
 +The importance of call descriptor and paramters is that they allow to specify the exact metaobject protocol (MOP) we want to use.
 +Using these elements we can see the metaobject programming as a task of connecting objects (as we did in the [[Tracing Aspect|tracing example]]).
 +
 +
 +
 +In this section we will review the API of the [[http://reflex.dcc.uchile.cl/svn/base/trunk/src/reflex/api/call/CallDescriptor.java|ClassDescriptor|]] class and the [[http://reflex.dcc.uchile.cl/svn/base/trunk/src/reflex/api/call/Parameter.java|Parameter]] interface.
 +
 +=====  CallDescriptor class =====
 +
 +The ''CallDescriptor'' class allows us to specify the exact call we want to be made when the metaobejct is invoked.
 +
 +The important part of the CallDescriptor API is its contructor, that takes all the necessary information to make the call:
 +<code java>
 +public CallDescriptor(String aType, String aMethod, Parameter... aParameters){...}
 +</code>
 +This call descriptor will produce code like this:
 +<code java>
 +((aType) metaobject).aMethod(aParameters)
 +</code>
 +The last argument is a list of Parameter intances (as it is a varargs constructor) that describes the parameters that will be used in the call.
 +
 +For example, if we want to invoke println over System.out without arguments, the call descriptor should be like:
 +<code java>
 +new CallDescriptor("java.io.PrintStream", "println");
 +</code>
 +Next we will review the interface Parameter in detail.
 +
 +=====  Parameter interface =====
 +
 +The ''Parameter'' interface describes how to dinamically evaluate call parametres. Notice that "dinamically evaluate" means that contextual information (available at the hook) can be used to generate the parameter.
 +
 +The parameter interface defines three methods that have to be implemented:
 +<code java>
 +public String evaluate(Operation aOperation);
 +</code>
 +This method must return the code of the parameter, for the given operation. The code can include [[http://www.csg.is.titech.ac.jp/~chiba/javassist/tutorial/tutorial2.html|Javassist syntax]].
 +<code java>
 +public String getType(Operation aOperation);
 +</code>
 +This method must return the fully qualified type of the parameter's evaluation. If the parameter represents an int it should return ''int''. If the paramter represents a String, it should return ''java.lang.String''.
 +<code java>
 +public boolean shouldBeEvaluatedAtHook(Operation aOperation);
 +</code>
 +This method is here for optimization only. It must return true if the parameter should be evaluated at the hook (because it uses contextual information).
 +
 +Sometimes, certain parameters are evaluated but never used (because they are used to invoke a method in a metaobejct that is nested and the first metaobject in the chain does not call proceed, then, it would be perfect if their evaluation could be delayed until it is really necessary. This is the purpose of this method, to give a hint to the Reflex code generation engine.
 +
 +An example parameter that records the time when the hook was reached is:
 +<code java>
 +public class TimeParameter implements Parameter{
 +
 +    public String evaluate(Operation aOperation){
 +        return "System.currentTimeMillis()";
 +    }
 +
 +    public String getType(Operation aOperation){
 +        return "long";
 +    }
 +
 +    public boolean shouldBeEvaluatedAtHook(Operation aOperation){
 +        return true;
 +    }
 +}
 +</code>
 +The ''TimeParameter'' class returns a ''String'' that represents a ''System.currentTimeMillis()'' call. As this code is inserted at the hook, the call will be made when the hook is reached. The type of the parameter is ''long'' and it should be evaluated at the hook.
 +
 +Another parameter (a bit more complex) is one that makes use of the operation specified. In this case to determine if the read/write operation thas is being done is read:
 +<code java>
 +public class IsRead implements Parameter{
 +
 +    public String evaluate(Operation aOperation){
 +        return String.valueOf(((Operation.ReadWrite) aOperation).isRead());
 +    }
 +
 +    public String getType(Operation aOperation){
 +        return "boolean";
 +    }
 +
 +    public boolean shouldBeEvaluatedAtHook(Operation aOperation){
 +        return false;
 +    }
 +}
 +</code>
 +The evaluate method returns ''true'' if the operation is read and ''false'' if it is not. The type is ''boolean'' and its evaluation can be delayed, because it does not use contextual information.
 +
 +Next we will see some of the ready-to-use parameters provided by Reflex.
 +
 +====  Utility Parameters ====
 +
 +  * ''Parameter.CONTEXT_OBJECT''
 +This parameter evaluates to the context object: the current class if the operation is in static context and this if it is not.
 +
 +  * ''Parameter.RESULT''
 +This parameter evaluates to the result of the operation (the value about to be returned by a method invocation, the resulting value of the field access if the expression is read access, the resulting value of the object creation, etc). This parameter is the same as the ''$_'' special variable of Javassist (Notice that this parameter is only available for ''AFTER'' control).
 +
 +  * ''Parameter.CLOSURE''
 +This parameter evaluates to the closure object used to invoke the next step in the chain of metoabjects.
 +
 +  * ''StdParameters.ARGUMENTS_ARRAY''
 +This method evaluates to an array of objects, objects that are the parameters of the operation:
 +<code java>
 +new Object[]{ parameter1, parameter2, ..., parameterN}
 +</code>
 +
 +  * ''StdParameters.NAME''
 +This method evaluates to the name of the operation: the method name if it is a method receive or a method invocation, the field name if it is a field access, etc.
 +
 +  * ''StdParameters.TARGET_TYPE''
 +This parameter evaluates to the type of the object receiving the operation: the type of an object subject of a message send, the type of a field being accessed, etc.
 +
 +  * ''StdParameters.DECLARING_CLASS''
 +This parameter evaluates to the declaring class of the operation: the class declaring a method or constructor that is being invoked or a field that is being accessed.
 +
 +  * ''StdParameters.LINE_NUMER''
 +This parameter evaluates to the line number of the operation if available.