Standar MOP

NOTE: The standard MOP is partially obsolete at present. We rather recommend using Call Descriptors.

Reflex provides a standard metaobject protocol (Standard MOP) for all the standard operations (Message send, message reception, instantiation, creation, field access and cast). This MOP defines the exact call that should be done to communicate with the metaobject. There are three kinds of calls, one for before control, one for after control and one to around control. Each one of this calls different according to the operation. Also, the reified information is different. The MOP defines a serie of “dynamic operations”, objects that acts as a point of entrance to all the reified inforamtion.
It is important to note that all the available information is reified. Because of this reason, we explicitly encourage you to use a custom MOP through call descriptors and parameters.

Standard MOP API

As we said before, the standard MOP defines the way to communicate with the metaobject for all the standard operations. Here we will review each one of these sub-protocols.

There is one interface-method pair for each control: the metaobject must implement the interface and the method.

The method takes as unique parameter a “dynamic” object that holds all the available information about the operation. In the case of around control, the method takes one more parameter: the closure object.

Message send

The three interfaces are:

public interface BeforeMsgSend{
    public void beforeMsgSend(DMsgSend aDMsgSend);
}
 
public interface AfterMsgSend{
    public void beforeMsgSend(DMsgSend aDMsgSend);
}
 
public interface AroundMsgSend{
    public void beforeMsgSend(
        DMsgSend aDMsgSend, IExecutionPointClosure aClosure
);
}

And the DMsgSend class has the following methods:

public Method getMethod(){...}

Returns the invoked method.

public String getMethodName(){...}

Returns the name of the invoked method.

public Object[] getArguments(){...}

Returns the arguments of the invocation.

public Object getTargetObject(){...}

Returns the object target of the invocation, or null if the called method is static.

public Class getDeclaringClass(){...}

Returns the class that declares this method.

Message receive

The three interfaces are:

public interface BeforeMsgReceive{
    public void beforeMsgReceive(DMsgSend aDMsgReceive);
}
 
public interface AfterMsgReceive{
    public void beforeMsgReceive(DMsgSend aDMsgReceive);
}
 
public interface AroundMsgReceive{
    public void beforeMsgReceive(
        DMsgSend aDMsgReceive, IExecutionPointClosure aClosure
);
}

And the DMsgReceive class has the following methods:

public Method getMethod(){...}

Returns the invoked method.

public Object[] getArguments(){...}

Returns the arguments of the invocation.

Instantiation

The three interfaces are:

public interface BeforeInstantiation{
    public void beforeInstantiation(DMsgSend aDInstantiation);
}
 
public interface AfterInstantiation{
    public void beforeInstantiation(DMsgSend aDInstantiation);
}
 
public interface AroundInstantiation{
    public void beforeInstantiation(
        DMsgSend aDInstantiation, IExecutionPointClosure aClosure
);
}

And the DInstantiation class has the following methods:

public String getReceiverClassname(){...}

Returns the name of the class being instantiated.

public Class getReceiverClass(){...}

Returns the class being instantiated.

public Object[] getArguments(){...}

Returns the arguments of the instantiation.

Creation

The three interfaces are:

public interface BeforeCreation{
    public void beforeCreation(DMsgSend aDCreation);
}
 
public interface AfterCreation{
    public void beforeCreation(DMsgSend aDCreation);
}
 
public interface AroundCreation{
    public void beforeCreation(
        DMsgSend aDCreation, IExecutionPointClosure aClosure
);
}

And the DCreation class has the following methods:

public Object[] getArguments(){...}

Returns the arguments of the creation.

Field Access

The three interfaces are:

public interface BeforeFieldAccess{
    public void beforeFieldAccess(DMsgSend aDFieldAccess);
}
 
public interface AfterFieldAccess{
    public void beforeFieldAccess(DMsgSend aDFieldAccess);
}
 
public interface AroundFieldAccess{
    public void beforeFieldAccess(
        DMsgSend aDFieldAccess, IExecutionPointClosure aClosure
);
}

And the DFieldAccess class has the following methods:

public  Field getField(){...}

Returns the field being accessed.

public String getFieldName(){...}

Returns the name of the accessed field.

public boolean isRead(){...}

Returns the boolean indicating if it is a read or write access.

public String getTypeName(){...}

Returns the name of the target type.

public Object getValue(){...}

Returns the value being set if the operation is field access, null if it is not.

public Object getTargetObject(){...}

Returns the object that owns the field, null if the field is static.

public Class getDeclaringClass(){...}

Returns the class that declares the field.

Cast

The three interfaces are:

public interface BeforeCast{
    public void beforeCast(DMsgSend aDCast);
}
 
public interface AfterCast{
    public void beforeCast(DMsgSend aDCast);
}
 
public interface AroundCast{
    public void beforeCast(
        DMsgSend aDCast, IExecutionPointClosure aClosure
);
}

And the DFieldAccess class has the following methods:

public Class getTargetType(){...}

Returns the target type of the cast.

public Object getTargetObject(){...}

Returns the target object of the cast.

DynamicOperation

All dynamic classes extend from a common superclass: DynamicOperation. It defines two methods that are common to all subclasses and an abstract method: perform that allows the programmer to execute the original operation.

Let us review the class:

public abstract class DynamicOperation{
 
    public Object getContextObject(){...}
 
    public Object getResult(){...}
 
    public abstract Object perform();
}

The getContextObject method returns a reference to the object in which the operation is occurring (class if the operation is in static context or this if it is not).

The getResult method returns the result of the operation (null if not available. In general is only available for links with AFTER control).

And finally, the perform abstract method executes the original operation.