[XML-DEV Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] RE: Parser2 considered harmful
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, http://www.cs.wustl.edu/~schmidt/PLoP-96/gamma.txt (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(); p.setProperty ("http://xml.org/sax/properties/dtd-handler", myDTDHandler); 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() { Parser p; // Original stuff elided try { p.getProperty("dummy"); // we get here if we're SAX2 compatible ... return p; } catch(NoSuchMethodException ex) { // ... we get here if we're not. return new SAX1ParserAdapter(p); } } Where SAX1ParserAdapter is defined as follows, class SAX1ParserAdapter implements Parser { 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 (DocumentHandler handler) { // cache locally ... itsDocumentHandler = handler; // forward to underlying SAX1 parser ... itsBaseParser.setDocumentHandler(handler); } // 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 about NoSuchMethodExceptions. 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). Cheers, Miles -- Miles Sabin Cromwell Media Internet Systems Architect 5/6 Glenthorne Mews +44 (0)181 410 2230 London, W6 0LJ msabin@c... England xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev@i... 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@i... the following message; (un)subscribe xml-dev To subscribe to the digests, mailto:majordomo@i... the following message; subscribe xml-dev-digest List coordinator, Henry Rzepa (mailto:rzepa@i...)
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|