|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.ovmj.util.Runabout
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 calls visitDefault() which, if not overriden, throws an exception.
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.
Nested 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. |
Field Summary | |
protected Runabout.Code |
noCode
Code to invoke if no visitor is found (used to avoid scanning the hierarchy again and again). |
static java.lang.String |
VISIT
Name of the visit methods. |
Constructor Summary | |
Runabout()
Create a Runabout. |
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. |
protected Runabout.Code |
getAppropriateCode(java.lang.Class c)
Find the appropriate Code to call in the map. |
protected Runabout.Code |
getCodeForClass(java.lang.Class c)
Helper method to allow subclasses to override getAppropriateCode with their own lookup mechanims. |
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. |
protected void |
visitDefault(java.lang.Object o)
Override this method to provide a default behavior when no other visit matches. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
public static final java.lang.String VISIT
protected final Runabout.Code noCode
Constructor Detail |
public Runabout()
Method Detail |
public final void addExternalVisit(java.lang.Class cl, Runabout.Code co)
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!
cl
- the type for which to invoke this visit methodco
- the code to invokepublic final void visitAppropriate(java.lang.Object o)
o
- the object to visitpublic void visitAppropriate(java.lang.Object o, java.lang.Class c)
o
- the object to visitc
- the type of the object, should be equal to o.getClass() unless o
is primitive (then it should describe the primitive type)public void visit(int i)
public void visit(float f)
public void visit(double d)
public void visit(long l)
public void visit(byte b)
public void visit(char c)
public void visit(boolean b)
public void visit(short s)
protected Runabout.Code getAppropriateCode(java.lang.Class c)
c
- the class for which to find the code
Runabout.RunaboutException
- if the lookup would be ambiguousprotected final Runabout.Code getCodeForClass(java.lang.Class c)
c
- a class
protected void visitDefault(java.lang.Object o)
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |