| 
 | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Object | +--org.jutil.java.collections.RobustVisitor
A robust visitor of collections. The code in visit is performed for each element in the visited collection.

Of course, sometimes exceptions can be thrown during a visit. The default behaviour when an exception occurs, is to undo all changes that were made and throw an exception to the caller of the method. This means that the actions that were performed on elements visited before the element that caused the exception, have to be undone. The RobustVisitor class adds support for handling exceptions to the Visitor class.
If an exception occurs while visiting the collection, the changes made to
 the elements visited before the element that caused the exception, are
 undone. To accomplish this, a method void
 unvisit(Object element, Object undoData) is introduced, which
 takes a visited element and data to undo the changes as arguments. The method
 must undo the changes made to the given element. The undoData object is the
 object that is returned by the void visit(Object element)
 throws Exception method. If no undo data is necessary to undo the
 changes, null can be returned. The changes are undone in the
 opposite order as the changes were done. The changes of the visit that caused
 the exception should be undone by the visit method itself, the other visits
 are undone using the unvisit method. After all changes are undone, the
 exception is propagated to the caller of the applyTo
 method.
The visit and
 applyTo
 methods throw Exceptions to keep the class as general as
 possible. The Exception of the visit method can
 be strengthened to one specific exception when overwriting the method, but
 the Exception of the applyTo method can't because that method is
 made final. That means that in the code you have to catch
 Exception, which is a disadvantage of using a
 RobustVisitor. Most methods we didn't think could be overwritten
 in a useful way are made final. Even if we would allow to overwrite the
 applyTo
 method, the only way to strengthen the exception there is to insert a
 try-catch block and call the super method, or copy the code from the
 
RobustVisitor doesn't inherit from Visitor
 because adding an exception to the throws clausule of the visit method would
 violate LSP (Liskov Substitution Principle) and because the visit methods of
 both classes have different return types. The last reason also prevents us
 from doing the opposite, making Visitor inherit from
 RobustVistor (which would also introduce a useless unvisit
 method in Visitor).
 Iterator iter = collection.iterator();
 Vector changed = new Vector();
 Vector undo = new Vector();
 try{
   while(iter.hasNext()) {
     MyClass object = (MyClass) iter.next();
     // action code
     changed.add(object);
 		undo.add(undoData);
   }
 }
 catch(MyException exc) {
   for(int i=changed.size(); i>= 0; i--) {
     // undo action code;
   }
   throw exc;
 }
 
 new RobustVisitor() {
   public Object visit(Object element) throws MyException {
     MyClass object = (MyClass) element;
     // action code;
 		 return undoData;
   }
 	
   public void unvisit(Object element, Object undoData) {
     // undo action code;
   }
 }.applyTo(collection);
 
| Inner Class Summary | |
| (package private)  class | RobustVisitor.Entry | 
| Field Summary | |
| static java.lang.String | CVS_REVISION | 
| Constructor Summary | |
| RobustVisitor() | |
| Method Summary | |
|  java.lang.Object[] | applyTo(java.lang.Object[] array)Perform the visitation defined in public void visit(Object)on | 
|  java.util.Collection | applyTo(java.util.Collection collection)Perform the visitation defined in public void visit(Object)on | 
|  void | applyTo(java.util.Enumeration enumeration)Perform the visitation defined in public void visit(Object)on all elements reachable from | 
|  void | applyTo(java.util.Iterator iterator)Perform the visitation defined in public void visit(Object)on all elements reachable from | 
| abstract  void | unvisit(java.lang.Object element,
        java.lang.Object unvisitData)This method will be called when the visit method has raised an exception for some element which was visited after | 
| abstract  java.lang.Object | visit(java.lang.Object element)The code to be applied to all elements of a collection. | 
| Methods inherited from class java.lang.Object | 
| clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | 
| Methods inherited from interface org.jutil.java.collections.CollectionOperator | 
| isValidElement | 
| Field Detail | 
public static final java.lang.String CVS_REVISION
| Constructor Detail | 
public RobustVisitor()
| Method Detail | 
public abstract java.lang.Object visit(java.lang.Object element)
                                throws java.lang.Exception
element - The object the code should be applied to.
public abstract void unvisit(java.lang.Object element,
                             java.lang.Object unvisitData)
public final java.util.Collection applyTo(java.util.Collection collection)
                                   throws java.lang.Exception,
                                          java.util.ConcurrentModificationException
Perform the visitation defined in public void visit(Object)
 on 
The collection is returned, so that further operations can be applied to it inline.
collection - The collection to perform this visitation on. This can be null.
public final java.lang.Object[] applyTo(java.lang.Object[] array)
                                 throws java.lang.Exception
Perform the visitation defined in public void visit(Object)
 on 
The array is returned, so that further operations can be applied to it inline.
array - The array to perform this visitation on.
         This can be null.
public final void applyTo(java.util.Iterator iterator)
                   throws java.lang.Exception,
                          java.util.ConcurrentModificationException
Perform the visitation defined in public void visit(Object)
 on all elements reachable from 
iterator - The iterator to perform this visitation on. This can be null.
public final void applyTo(java.util.Enumeration enumeration)
                   throws java.lang.Exception,
                          java.util.ConcurrentModificationException
Perform the visitation defined in public void visit(Object)
 on all elements reachable from 
enumeration - The enumeration to perform this visitation on. This can be null.| 
 | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||