Parser2 considered harmful
msabin at cromwellmedia.co.uk
Tue May 18 16:54:49 BST 1999
David Megginson wrote,
> Miles Sabin writes:
> > It's not diamond inheritance per-se which is the
> > problem, it's (as you point out) the potential for a
> > combinatorial explosion of derived interfaces which is
> > nasty.
> Some concrete examples might be helpful -- I know that
> the get/setFeature/Property methods in Parser2 are not a
> silver bullet, but under what circumstances might people
> want to subclass Parser2 further in the future?
Err ... no, that's not what I meant. getProperty() deals
with things quite nicely. It's an example of something
Erich Gamma calls the 'Extension Objects Pattern'. See,
(only an abstract I'm afraid).
My point was more along the lines of getProperty() etc.
are (or, at least, will be) core Parser functionality,
and that they should, if possible, be defined in the main
Parser interface, rather than relegated to an auxilliary
extension interface. The various discussions on the DOM
IG seem to have come to the conclusion that augmenting
interfaces in this way isn't problematic in Java, and
that it's the cleanest and most comprehensible solution
to the interface evolution problem.
The biggest problem with the Parser2 route is that it
interacts badly with ParserFactory. ParserFactory's
methods return Parsers, so if getProperty() is defined
on Parser2 I have to cast before I can call it, and that's
ugly, particularly since the cast might fail.
ParserFactory can't be modified so that it's methods
return Parser2s without breaking signature compatability
with SAX1, but we can add the new methods directly to
Parser without causing any problems.
Actually, this probably needs a bit of clarification. I
guess a rejoinder might be: doesn't this break
compatibility with parsers which only implement the
current Parser interface? Ie. with a current parser,
wouldn't the effect of,
Parser p = ParserFactory.makeParser();
be to throw a NoSuchMethodException?
In fact this doesn't need to happen, because the SAX2
ParserFactory could do something like this,
public static Parser makeParser()
// Original stuff elided
// we get here if we're SAX2 compatible ...
// ... we get here if we're not.
return new SAX1ParserAdapter(p);
Where SAX1ParserAdapter is defined as follows,
private Parser itsBaseParser;
private DocumentHandler itsDocumentHandler = null;
private DTDHandler itsDTDHandler = null;
private EntityResolver itsEntityResolver = null;
private ErrorHandler itsErrorHandler = null;
private Locale itsLocale = null;
public SAX1ParserAdapter(Parser baseParser)
itsBaseParser = baseParser;
public void setDocumentHandler
// cache locally ...
itsDocumentHandler = handler;
// forward to underlying SAX1 parser ...
// etc. for for other Parser methods that can be
// safely forwarded to a SAX1 parser.
public void setFeature
(String featureId, boolean state)
// throw relevant exceptions
public boolean getFeature(String featureId)
// return SAX1 compatible results or throw
// relevant exceptions
public void setProperty
(String propertyId, Object value)
// call SAX1 Parser.setXXXHandler() methods
// where appropriate (and cache locally), or
// throw relevant exceptions.
public Object getProperty(String propertyId)
// return locally cached handlers where
// appropriate, or throw relevant exceptions.
This should work with all possible combinations of
SAX parsers, and SAX client applications.
Case 1: SAX1 parser, SAX1 client
No problem, it's the current situation.
Case 2: SAX1 parser, SAX2 client
No problem, dealt with by adapter as above. SAX2 client
can use SAX2 methods without casting and without having
to worry about NoSuchMethodExceptions.
Case 3: SAX2 parser, SAX1 client
No problem, SAX2 interfaces are backwards compatible.
Case 4: SAX2 parser, SAX2 client.
No problem. As in case 2, the SAX2 client can use SAX2
methods without casting and without having to worry
Note that this assumes that a SAX2 client can only be
built against SAX2 interfaces and classes (which is fine
because that's guaranteed), and that a SAX2 client will
be able to ensure that the SAX2 ParserFactory is on its
classpath at runtime (which shouldn't be a problem).
Miles Sabin Cromwell Media
Internet Systems Architect 5/6 Glenthorne Mews
+44 (0)181 410 2230 London, W6 0LJ
msabin at cromwellmedia.co.uk England
xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev at ic.ac.uk
Archived as: http://www.lists.ic.ac.uk/hypermail/xml-dev/ and on CD-ROM/ISBN 981-02-3594-1
To (un)subscribe, mailto:majordomo at ic.ac.uk the following message;
To subscribe to the digests, mailto:majordomo at ic.ac.uk the following message;
List coordinator, Henry Rzepa (mailto:rzepa at ic.ac.uk)
More information about the Xml-dev