ovm.util
Class Runabout

java.lang.Object
  |
  +--ovm.util.Runabout

public class Runabout
extends java.lang.Object

Runabout is a fast implementation of the Walkabout which is a variant of the Visitor Pattern that does not require an accept method and uses reflection instead.

An instance of Runabout is able to walk over an arbitrary object graph using visit methods which take arguments of the specific type of the object to visit. For each node in the object graph the Runabout invokes the most appropriate visit method.

Using the Runabout typically involves subclassimg Runabout and adding a couple of visit methods. The Runabout provides a 'visitAppropriate' method which will invoke the most appropriate visit method of the current Runabout instance. If no visit method is applicable, visitAppropriate does nothing.

The elements of the object graph typically extend the Element class, which provides a generic way to quickly invoke the Runabout on all the fields of the Element.

Note that the Runabout uses dynamic code generation and dynamic loading in order to be quickly able to invoke the appropriate visit methods. To make the dynamic code generation fast, the code inlines parts of Java class-files in binary form (ugly!).
A per-thread Cache is used to speed-up the creation of the Runabout by caching reflection, code creation and dynamic loading operations.

Restrictions: Java semantics require:

Otherwise the visitor will die with an IllegalAccessError during execution.

Author:
Christian Grothoff

Inner Class Summary
static class Runabout.Code
          Code is the generic interface that all generated classes implement.
static class Runabout.RunaboutException
          Generic Exception for problems in the Runabout.
 
Constructor Summary
Runabout()
          Create a Runabout using the cache to speed-up multiple instantiations.
 
Method Summary
 void addExternalVisit(java.lang.Class cl, Runabout.Code co)
          Add a Code of a visit method to visit for a certain type which is not defined in the visitor itself.
 void visit(boolean b)
          Visit method that is called from visitAppropriate(Boolean b, Boolean.TYPE) with b.booleanValue() as the argument.
 void visit(byte b)
          Visit method that is called from visitAppropriate(Byte b, Byte.TYPE) with b.byteValue() as the argument.
 void visit(char c)
          Visit method that is called from visitAppropriate(Character c, Character.TYPE) with c.charValue() as the argument.
 void visit(double d)
          Visit method that is called from visitAppropriate(Double d, Double.TYPE) with d.doubleValue() as the argument.
 void visit(float f)
          Visit method that is called from visitAppropriate(Float f, Float.TYPE) with f.floatValue() as the argument.
 void visit(int i)
          Visit method that is called from visitAppropriate(Integer i, Integer.TYPE) with i.intValue() as the argument.
 void visit(long l)
          Visit method that is called from visitAppropriate(Long l, Long.TYPE) with l.longValue() as the argument.
 void visit(short s)
          Visit method that is called from visitAppropriate(Short s, Short.TYPE) with s.shortValue() as the argument.
 void visitAppropriate(java.lang.Object o)
          Call the appropriate visit method.
 void visitAppropriate(java.lang.Object o, java.lang.Class c)
          Call the appropriate visit method.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Runabout

public Runabout()
Create a Runabout using the cache to speed-up multiple instantiations.
Parameters:
cache - the Cache to use
Method Detail

addExternalVisit

public final void addExternalVisit(java.lang.Class cl,
                                   Runabout.Code co)
Add a Code of a visit method to visit for a certain type which is not defined in the visitor itself. Note that this extention is not added to the cache for all instances but kept private to this class.

This method should only be invoked before the Runabout is used (for example in the constructor) since afterwards subtypes of cl may already be mapped to more general handlers. This method will not check this!

Parameters:
cl - the type for which to invoke this visit method
co - the code to invoke

visitAppropriate

public final void visitAppropriate(java.lang.Object o)
Call the appropriate visit method. Use this method if you are visiting a graph of objects (no primitives).
Parameters:
o - the object to visit

visitAppropriate

public void visitAppropriate(java.lang.Object o,
                             java.lang.Class c)
Call the appropriate visit method. Use this methd if the traversal may hit primitives. This is typcially the case if you walk over some graph using reflection.
Parameters:
o - the object to visit
c - the type of the object, should be equal to o.getClass() unless o is primitive (then it should describe the primitive type)

visit

public void visit(int i)
Visit method that is called from visitAppropriate(Integer i, Integer.TYPE) with i.intValue() as the argument. Override if you need to visit primitive integers.

visit

public void visit(float f)
Visit method that is called from visitAppropriate(Float f, Float.TYPE) with f.floatValue() as the argument. Override if you need to visit primitive floats.

visit

public void visit(double d)
Visit method that is called from visitAppropriate(Double d, Double.TYPE) with d.doubleValue() as the argument. Override if you need to visit primitive doubles.

visit

public void visit(long l)
Visit method that is called from visitAppropriate(Long l, Long.TYPE) with l.longValue() as the argument. Override if you need to visit primitive longs.

visit

public void visit(byte b)
Visit method that is called from visitAppropriate(Byte b, Byte.TYPE) with b.byteValue() as the argument. Override if you need to visit primitive bytes.

visit

public void visit(char c)
Visit method that is called from visitAppropriate(Character c, Character.TYPE) with c.charValue() as the argument. Override if you need to visit primitive characters.

visit

public void visit(boolean b)
Visit method that is called from visitAppropriate(Boolean b, Boolean.TYPE) with b.booleanValue() as the argument. Override if you need to visit primitive booleans.

visit

public void visit(short s)
Visit method that is called from visitAppropriate(Short s, Short.TYPE) with s.shortValue() as the argument. Override if you need to visit primitive shorts.

http://www.ovmj.org/runabout/