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