OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

 


 

   SAX IoC Errors (Was: SAXException, checked, buy why?)

[ Lists Home | Date Index | Thread Index ]

* Peter Hunsberger <peter.hunsberger@gmail.com> [2005-01-05 15:52]:
> On Wed, 5 Jan 2005 15:19:25 -0500, Alan Gutierrez
> <alan-xml-dev@engrm.com> wrote:
> > * Peter Hunsberger <peter.hunsberger@gmail.com> [2005-01-05 10:27]:
> > > On Tue, 4 Jan 2005 22:45:22 -0500, Alan Gutierrez
> > > <alan-xml-dev@engrm.com> wrote:
> > > > * Karl Waclawek <karl@waclawek.net> [2005-01-04 19:30]:
> > > > >
> > > > >
> > > > > Alan Gutierrez wrote:

> > > I wish I had time to take in everything you've been bouncing back and
> > > forth here.  It's a little unusual for xml-dev but it appears to apply
> > > to much of what we are doing.  The reason why I'm commenting here is
> > > that the above caught my eye and -- without really understanding the
> > > whole issue -- suggests that you might have a inversion of control
> > > (IOC) pattern that often shows up in frameworks?
> > 
> >    Yup. Yup.
> > 
> >    Thanks for reminding me. I'd forgotten about all that IOC
> >    reading I'd done earlier in this year.

    I've retitled the thread finally, because this has not been a
    discussion of Java triva for quite some time.

> > > If so, I'm guessing, you might explore using the Exception or Error
> > > itself to encapsulate much of the details on how to handle itself.  In
> > > our case we do something like:
> > 
> > > public class XXException extends Exception {

> >    [snip]
> > 
> > >    public void test( int level ) throws XXException {
> > >        if ( msgV.size() > 0 && highestLevel >= level )
> > >            throw this;
> > >    }
> > 
> >    [snip]
> > 
> >    Interesting. A severity flag.

> Doesn't have to be severity, you could add more formal types...

    The exception tests itself? Contains the throw decisions?

> > >    }
> > >
> > >    // Create an SAX stream for the output messages
> > >    public void generateSaxMsgs( XMLConsumer xmlConsumer, String
> > > namespace, String prefix ) {
> > 
> >    Are you indicating here, that one option is to stream the error
> >    report to the next handler? That's common in what I'm doing.
> > 
> >    Clever.

> Yes, but also turning the exception into a regular data object that
> can be passed around.  A Composition pattern can be used to wrap the
> various data objects with object specific versions of a generic
> interface, eg: something that builds a SAX stream or whatever.

> > >    }
> > 
> > > The things here that I suspect might be relevant to your discussion are:
> > 
> > > 1) you can pass one of these beasts around as an accumulator, the
> > > game's not over on the first error. In particular, the vector wouldn't
> > > have to be straight Strings;
> > 
> >    I keep a stack of "state of procesing" objects in a SAX
> >    Content/LexicalHandler.
> > 
> >    The Content/LexicalHandler is a Fascade to a Composition of
> >    event processing Strategies which Decorate and Delegate.
> > 
> >    (Strategies can hand off control to other strategies, for a
> >        any sub-tree. A Strategy could hand off a sub-tree to
> >        document builder Strategy. The document is returned to the
> >        delegating Strategy when when the endElement event occurs.
> > 
> >        Hence the stack.)
> > 
> >    This state of processing object is where I'd put two chains of
> >    objects.
> > 
> >        ~ ErrorResponder
> >            - This is called to allow client code the opporuntiy to
> >              respond to an exceptional condition before it is
> >              thrown and processing is aborted. The error responder
> >              can ignore, raise, suspend processing, log, or fix for
> >              retry. (Suspend processing means to ignore the events
> >              until we return a place were we can continue.)
> > 
> >        ~ ThrowResponder
> >            - These are registered by participents withing the
> >              SAX Content/LexicalHandler to restore state if an
> >              event is thrown.
> > 
> >        ! IoC exception handling.

> Hmm, maybe you should just treat the exceptions like any other
> Strategy?  Don't even distinguish between them except for someway to
> "test" them?  That seems more-or-less what you're doing but you seem
> to have two interfaces where I'd have one...

    I have two, because the first interface cares about the error,
    it's type, it's contents, the second only cares that an error
    occured. The first is error handling, the second is cleanup.

    I've implemented the second interface as something like:

    public interface Cleaner {
        public void cleanup(Campaign campaign);
    }

    It is called when a strategy pops off the strategy stack for any
    reason. I'm using one to rm -r a working directory, for example.

> >    I feel that the chaining and accumulation, can be done through
> >    composition of the ErrorRepsonder interface. Which is:
> > 
> >    public interface ErrorResponder {
> >        public void error(Context context, Event event, StrategyError error)
> >        throws SomeSortOfException {
> >        }
> >    }
> > 
> >    You can have a DispatchingErrorResponder, or an ErrorResponderList,
> >    and so on.

> Yes, but why add the extra interface?  Why not just re-use the same
> interfaces you already have and implement them in the error objects? 
> If no error happens you get back the normal objects and they produce
> they normal SAX stream, otherwise you get back an error object and it
> produces the error SAX stream unless you care to "test" it in which
> case it bubbles up the problems to to whom ever the "tester"
> (Responder?) is?

    Are you thinking that I ought to use the Strategy interface? Or
    are you talking about my idea to have two error interfaces?

> > > 2) it knows how to test itself for certain situations, you can have
> > > additional methods for other situations and the details of what to do
> > > for each case might be built in;
> > 
> >    That's hard. I'd like to provide an object like the one you
> >    described, but I would make it final, and spare. I'd compose
> >    error handling logic using the responders.

> Not sure I see the need for the extra level of complexity, but then
> again, I haven't been following closely...  The overall idea seems
> similar to what I'd do.

    This thing above, the StrategyError (SAXError) with the
    breakers, is supposed to provide complexity if needed.

    At one level, it's a bucket. It is also an exception wrapper if
    an unchecked exception is needed. It is also provides some
    obvious flags to control the shuffling around of the error as event.

> > > 3) it knows the details of how to represent itself as a SAX stream or
> > > a DOM or a String or whatever you might need: in your case that might
> > > be some form of event wrapper.
> > 
> >    This is also new. I'm not thinking it through, but I think this
> >    would be logic in a responder. One could create a generic
> >    responder that does this. The responder gets a reference to the
> >    next SAX handler through the processing context object.

> Perhaps, I tend to end up with Interfaces wrapping Interfaces for
> cases where I want to extend generic code with really special case
> code.  That sometimes leads to "instanceof" type if/else blocks but
> mostly polymorphism handles the whole thing cleanly and I don't have
> to distinguish between "retry", "pass", etc. except for the
> polymorphic versions of the methods.  In particular, a polymorphic
> constructor or initializer on your Responder (I think) might handle
> Strategy vs. ErrorStrategy in such cases?

    Oh, you seem to think that Strategy and ErrorStrategy ought to
    be the same thing. Right?

    Here's Strategy as it stands: 
    
    public interface Strategy {
        void launched(Campaign campaign, Event event);
        void startElement(Campaign campaign, Event event);
        void characters(Campaign campaign, Event event);
        void processingInstruction(Campaign campaign, Event event);
        void skippedEntity(Campaign campaign, Event event);
        void comment(Campaign campaign, Event event);
        void endElement(Campaign campaign, Event event, Campaign concluded);
        void concluding(Campaign campaign, Event event);
    }


    What you've suggested, in a number of ways, is the idea that
    errors flow forward to the next SAX handler. I'm not there yet.
    
    I'm still trying to figure out how a SAX handler, composed of
    Strategies, handles it's own errors. How do errors flow back to
    the head of the SAX chain?

    In this discussion, I saw my Strategy stack as an event conduit
    in itself.

    A Campaign is the context for a Strategy. I made these changes
    last night.

    public interface Campaign {
        // Stackyness.
        Campagin    getParent();
        Map         getVariables();
        Strategy    getStrategy();
        Event       getLauchEvent();

        // Delegate.
        void        launch(Strategy strategy);

        // Other stuff snipped.
    }

    To.

    public interface Campiagn {
        // Delegate push strategy on stack, popped on end element.
        void        launch(Strategy strategy); 

        // Messages coming from up stack.
        void        post(CampaignKey key, Object data);
        void        hook(CampaignKey key, Receptionist receptionist);

        void        except(Catcher catcher);

        void        cleanup(Cleaner cleaner);

        // Variables for access here and down stack.
        Object      put(CampaignKey key, Object value);

        Object      get(CampaignKey key);

        Object      seek(CampaignKey key);
        Iterator    seekAll(CampaignKey key);

        // Other stuff snipped. 
        // The exposed stack via getParent()/getVariables() is on the way out.
    }

    The code based on this library is suddenly /much/ cleaner.

--
Alan Gutierrez - alan@engrm.com




 

News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS