Hi Laurent

Yes I think I understand the problem much better now - thanks for that.

I just wondered if ModuleContext needs to implement ElementHandler at all?
Would just having a ModuleStack, which just implements the stack of modules,
be easier & simpler? Then different ElementHandler's could push, pop, peek
the stack and so forth in any way they like?

James
----- Original Message -----
From: "Laurent Caillette" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, September 20, 2001 9:54 PM
Subject: [dom4j-dev] More on Context-passing


>
> A few more explainations about what I mean by 'Context-passing'.
>
> The setContext( Object ) method does not only set a kind of global
> variable. It acts as an implicit 'push' when done at a deeper Element
> level during the document parsing. The pop is also implicit, implicit
> meaning "done when the ElementStack decreases". The top of the Context
> stack is the last Context object pushed in, until :
> - another Context object is pushed in by a setContext( ... ), while in
> the same "branch" of Elements,
> - the stack decreases and pops the Context object automatically.
>
> Now a little scenario :
>
> step 1 -----
>  >>  <module id="1">
>       <module id="1.1" />
>       <module id="1.2">
>         <module id="1.2.1" />
>       <module id="1.2.2" />
>     </module>
>
>   Context stack :
>   module(1)
>
> step 2 -----
>     <module id="1">
>  >>    <module id="1.1" />
>       <module id="1.2">
>         <module id="1.2.1" />
>       <module id="1.2.2" />
>     </module>
>
>   Context stack :
>   module(1.1)
>   module(1)
>
> step 3 -----
>     <module id="1">
>       <module id="1.1" />
>  >>    <module id="1.2">
>         <module id="1.2.1" />
>       <module id="1.2.2" />
>     </module>
>
>   Context stack :
>   module(1.2)
>   module(1)
>
> step 4 -----
>     <module id="1">
>       <module id="1.1" />
>       <module id="1.2">
>  >>      <module id="1.2.1" />
>       <module id="1.2.2" />
>     </module>
>
>   Context stack :
>   module(1.2.1)
>   module(1.2)
>   module(1)
>
>
> Please note what happens in step 3 : the top of the stack is now
> module(1.2), replacing module(1.1).
>
> My initial solution would cause some type-unsafety problems, and
> impacted modifying code. Ok, let's try something smarter.
>
>
> First, the generic class.
>
>
>   public class ContextSupport implements ElementHandler {
>
>     private ElementHandler delegate = null ;
>
>     /** Allows to act as a wrapper.
>      */
>     public ContextSupport( ElementHandler handler ) {
>       this.delegate = handler ;
>     }
>
>     /** Used when another ElementHandler wants to control
>      * kinematic. Also allows switching between
>      * ContextSupports.
>      */
>     public ContextSupport() {
>       this.delegate = null ;
>     }
>
>     public void setDelegate( ElementHandler eh ) {
>       delegate = eh ;
>     }
>
>     // ArrayList used instead of Stack for accessing
>     // bottom (known as 'root')
>     private ArrayList contextStack = new ArrayList() ;
>
>     private int top = -1 ;
>
>     public final void onStart( ElementPath ep ) {
>       Object lowerContext = null ;
>       if( top >= 0 ) {
>         lowerContext = contextStack.get( top ) ;
>       }
>       top++ ;
>       contextStack.set( top, lowerContext ) ;
>       if( delegate != null ) {
>         delegate.onStart( ep ) ;
>       }
>     }
>
>     public final void onEnd( ElementPath ep ) {
>       top-- ;
>       if( delegate != null ) {
>         delegate.onEnd( ep ) ;
>       }
>     }
>
>     public final void setContext( Object context ) {
>       contextStack.set( top, lowerContext ) ;
>     }
>
>     public final Object getContext() {
>       return contextStack.get( top ) ;
>     }
>
>     public final Object getRoot() {
>       if( contextStack.size() > 0 ) {
>         return contextStack.get( 0 ) ;
>       } else {
>         return null ;
>       }
>     }
>
>   }
>
>
>
> Use it asfollows :
>
>   // Subclassing for type-safety
>
>   private class ModuleContext extends ContextSupport {
>
>     public Module getModuleContext() {
>       return ( Module ) getContext() ;
>     }
>
>     public void setModuleContext( Module module ) {
>       setContext( module ) ;
>     }
>
>     public Module getRootModule() {
>       return ( Module ) getRoot() ;
>     }
>   }
>
>   // Now the handler
>
>   PatternHandler ph = new PatternHandler() ;
>   final ModuleContext mc = new ModuleContext( ph ) ;
>
>   ph.add(
>       "/module",
>       new ElementHandler() {
>         public void onStart( ElementPath ep ) {
>           Module rootModule = new Module(
>               ep.getCurrentAttribute( "id" ) ;
>           )
>           mc.setModuleContext( rootModule ) ;
>         }
>         public void onEnd( ElementPath ep ) { }
>       }
>   ) ;
>
>   ph.add(
>       "module",
>       new ElementHandler() {
>         public void onStart( ElementPath ep ) {
>           Module module = new Module(
>               ep.getCurrentAttribute( "id" ) ;
>           )
>           Module parent = mc.getModuleContext() ;
>           parent.add( module ) ;
>         }
>         public void onEnd( ElementPath ep ) { }
>       }
>
>   ) ;
>
>   ContextSupport cs = new ContextSupport( ph ) ;
>   reader.setDefaultHandler( mc ) ;
>   reader.read( input ) // standard parsing ;
>   Module rootModule = mc.getRootContext() ;
>
>
> OK, I started with a small example in mind an I finished with a
> near-complete implementation of what I need ; I did not test it yet,
> though.
>
> The new ContextSupport also allows switching between different
> ContextSupports, becoming a delegate instead of delegating.
> This could be useful when the Composite pattern appears in a case like
> this :
>
>   <module id="1">
>     <module id="1.1" />
>     <module id="1.2">
>       <module id="1.2.1">
>         <part id="a" />
>         <part id="b">
>           <part id="b.a">
>           <part id="b.b">
>         </part>
>         <part id="a" />
>       </module>
>       <module id="1.2.2" />
>     </module>
>   </module>
>
> I'll try to implement this case in order to validate this last idea.
>
>
> _______________________________________________
> dom4j-dev mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/dom4j-dev
>


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


_______________________________________________
dom4j-dev mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dom4j-dev

Reply via email to