Re: PROPOSAL (round 3): Extensions to MDR XMI API
Martin Matula <[email protected]>
| Newsgroups | gmane.comp.java.netbeans.modules.mdr.devel |
|---|---|
| Message-ID | <[email protected]> |
Brian,
I looked at jaxp transform API and it seems to me that it would be much
better to provide XMIContentHandler (implementing ContentHandler - would
implement reading of XMI documents) and XMIProducer (implementing
XMLReader) - this way the user will be able to create SAXSource easily
by passing XMIProducer as XMLReader to the constructor, which is exactly
what you want to do (you don't want to have factory for XMISAXSource,
because the only thing that would make it SAXSource would be a specific
implementation of XMLReader in its XMLReader property. But it does not
make it obvious that if somebody changes this property, the "XMI" in the
SAXSource's name is in fact gone).
The same holds for SAXResult, where XMIContentHandler can be passed to
the constructor.
Martin
Brian Smith wrote:
> Martin Matula wrote:
>
>> Hi Brian,
>> Brian Smith wrote:
>>
>>> I agree with Holger. The interface does not make it obvious that
>>> sometimes the content handler is used and sometimes it is not used.
>>
>>
>> I did not say that content handler is not used. In fact, the default
>> implementation of XmiWriter methods in XMIWriter would _use_ content
>> handler - thus in case when a non-default content handler is set, they
>> would ignore the output stream.
>
>
> Sorry, this was what I meant: sometimes the output stream would not be
> used.
>
>>
>>> I also think that XMIReader is trying to be too many things at once.
>>> Sometimes it is a SAX content handler and sometimes it is an
>>> interface to I/O stream-based I/O. "extent" is a property for the
>>> SAX-related
>>
>>
>> OK, it seems that we are moving back and forth....The XMIReader and
>> XMIWriter interfaces did not extend XmiReader and XmiWriter. I added
>> the inheritance mainly because of your comments. If you wish, I can
>> revert it back and remove inheritance from XmiReader/XmiWriter from
>> our XMI interfaces. This will also solve your problem with the
>> xmiVersion...
>> I don't like adding two more interfaces. If we come to a conclusion
>> that the current set of interfaces/abstract classes is not enough, I
>> would rather abandon the whole idea of ContentHandlers and return back
>> to simple reader and writer.
>
>
> Well, I really think that the SAX-related stuff could/should be
> completely seperated from the XmiReader/XmiWriter stuff anyway. The
> problem I had before with XMIReader/XMIWriter not implementing
> XmiReader/XmiWriter was really soley based on the fact that I thought
> the naming was overly confusing. If nothing else, the seperation of the
> JMI and SAX-specific stuff would let you defer adding the SAX-based API
> until an obviously-superior design emerges. But, then you will likely
> have to add more classes/interfaces when the SAX support is added later.
>
> The other issue is that I couldn't figure out how to get the
> second-round proposal or the third-round proposal to integrate with
> JAXP's transformation API. Presumably, the MDR-XMI-API user would have
> to still write the "glue" to get XSLT transformations to work with
> MDR-generated XMI documents. But, I thought that the point of these
> SAX-ContentHandler proposals was to provide this glue for the client.
>
> Anyway, if you are still interested in doing stuff like this, I have a
> completely different idea that tries to reuse as much of JAXP as
> infrastructure as possible. It is in the attached HTML file.
>
> Thanks,
> Brian
>
> ------------------------------------------------------------------------
>
>
> Summary
>
> * XMIWriter and XMIReader are removed. XMIWriter had three types of
> functionality: (a) configuration, which was moved to
> XmiWriterConfiguration, (b) SAX-event generating, which was moved
> to XmiSAXSourceFactory, and (c) getDefault(), which was removed
> since XMIWriter became uninteresting. Analogous changes resulted
> in the removal of XMIReader. Note that the interfaces for
> XmixxxFactory classes and the XmiSAXxxxFactory classes are a
> asymmetric in how they handle the configuration. If symmetry is
> important, there would need to be XmiSAXxxxFactoryFactory classes
> which I think are excessive (unless, there is a way to use
> NetBeans lookup to create an instance of a class using a
> non-default constructor).
> * An open issue is how to deal with the XMIReferenceResolver
> callback that was in XMIReader. If a callback-style interface is
> really needed, then presumably a new interface would need to be
> added to this proposal to contain the callback method. But, I am
> hoping that another, non-callback approach can solve the same
> problem, if only to keep the implementations of the API simpler.
> * In the third round propsal, XMIReader had get/setExtent methods. I
> think that these are not necessary with the TrAX-based proposal.
> * The capitalization of "XMI" (i.e. "Xmi" or "XMI") is not
> consistent in the below interfaces. It just needs to be decided
> which to use.
> * The choice of abstract classes over interfaces was based only on
> what I think are NetBeans conventions.
>
>
> Proposed Interfaces
>
> (currently untested; no Javadoc, sorry)
>
> public abstract class XmiReaderFactory {
> public javax.jmi.xmi.XmiReader createXmiReader() {
> return createXmiReader(XmiReaderConfiguration.getDefault());
> }
> public abstract javax.jmi.xmi.XmiReader createXmiReader(
> XmiReaderConfiguration conf);
> public static XmiReaderFactory getDefault();
> }
>
> public abstract class XmiWriterFactory {
> public javax.jmi.xmi.XmiWriter createXmiWriter() {
> return createXmiWriter(XmiWriterConfiguration.getDefault());
> }
> public abstract javax.jmi.xmi.XmiWriter createXmiWriter(
> XmiWriterConfiguration conf);
>
> public static XmiReaderFactory getDefault() {
> return Lookup.getDefault().lookup(XmiWriterFactory.class);
> }
> }
>
> public abstract class XmiSAXSourceFactory {
> public javax.jmi.transform.sax.SAXSource createSAXSource(
> RefPackage extent) {
> return createSAXSource(extent,
> XmiReaderConfiguration.getDefault());
> }
> public abstract javax.jmi.transform.sax.SAXSource createSAXSource(
> RefPackage extent, XmiReaderConfiguration conf);
>
> public javax.jmi.transform.sax.SAXSource createSAXSource(
> Collection objects) {
> return createSAXSource(objects,
> XmiReaderConfiguration.getDefault());
> }
>
> public abstract javax.jmi.transform.sax.SAXSource createSAXSource(
> Collection objects, XmiReaderConfiguration conf);
>
> public static XmiSAXSourceFactory getDefault() { ... }
> }
>
> public abstract class XmiSAXResultFactory {
> public javax.xml.transform.sax.SAXResult createSAXResult(
> RefPackage extent) {
> return createSAXResult(extent,
> XmiReaderConfiguration.getDefault());
> public abstract javax.xml.transform.sax.SAXResult createSAXResult(
> RefPackage extent, XmiReaderConfiguration conf);
>
> public static XmiSAXResultFactory getDefault() { ... }
> }
>
> public class XmiWriterConfiguration {
> public void setReferenceProvider(XMIReferenceProvider) {...}
> public XMIREferenceProvider getReferenceProvider() { ... }
> public String getXmiVersion() { ... }
> public void setXmiVersion() { ... }
> public static XmiWriterConfiguration getDefault() { ... }
> }
>
> public class XmiReaderConfiguration {
> public void setReferenceResolver(XMIReferenceResolver);
> public XMIReferenceResolver getReferenceResolver();
> public static XmiReaderConfiguration getDefault() { ... }
> }
>
>
>
> Costs and Benefits
>
> An Extra Library Dependency: TrAX
> The "third round" proposal added a dependency on the SAX 2.0
> library. SAX 2.0 might be considered a low-impact dependency because
> a SAX implementation will almost certainly be needed by any
> implementation of |XmiReader| and |XmiWriter| anyway. In contrast,
> the "TrAX-based" proposal adds a dependency on the JAXP 1.1
> (|javax.xml.transform.*|) package, which is not as ubiquitous. TrAX
> is also not a required dependency for implementing |XmiWriter| and
> |XmiReader|. However, the request for a SAX-based XMI API were based
> on the idea of doing efficient pipelined processing of XMI
> documents. This is the exact purpose of the TrAX API. Also, in the
> third-round proposal there was an implied dependency on Dave
> Megginson's XMLWriter <http://www.megginson.com/Software/index.html>
> class. In TrAX, the equivalent functionality is obtained by using
> the built-in "identity transformation", tranforming a |SAXSource| to
> an equivalent |StreamSource|. (TrAX is available in J2SDK 1.4 and
> also can be added as part of the JAXP 1.1 standard extension for
> previous JDK versions.)Dependencies on SAX and JAXP are isolated
> The SAX-specific features from XMIWriter and XMIReader are factored
> into seperate classes. This makes it easier to iteratively define
> and refine the SAX-specific API. In particular, they can be added to
> the API after a proof-of-concept implemntation has been "approved"
> by users. Factoring out the SAX-specific features makes it easier to
> implement alternative versions of |XmiWriter| and/or the SAX
> mapping. For example, I could provide my own |XmiSAXSourceFactory|
> implementation that generated simplified "Canonical XMI" SAX streams
> and register it as the default |XmiSAXSourceFactory|. If the
> MDR-provided |XmiWriter| implementation is implemented in terms of
> the default |XmiSAXSourceFactory|, then my implementation will be
> used automatically, and I won't have to create my own |XmiWriter|
> implementation.
> SAX-Specific Customizations are Expanded and Encapsulated Handler
> Third Round Proposal TrAX-based Proposal
> ContentHandler xmiWriter.setContentHandler(handler)
> saxSource.getXMLReader().setContentHandler(handler)
> DTDHandler saxSource.getXMLReader().setDTDHandler(handler)
> EntityResolver saxSource.getXMLReader().setEntityResolver(resolver)
> ErrorHandler saxSource.getXMLReader().setErrorHandler(handler)
> LexicalHandler
> (comments, etc.) saxSource.getXMLReader().setProperty(
> "http://xml.org/sax/properties/lexical-handler", handler)
> System ID xmiWriter.write(..., systemId)
> saxSource.setSystemId(systemId) or
> saxSource.getInputSource().setSystemId(systemId)
> Public ID saxSource.getInputSource().setPublicId(publicId)
> Character Encoding saxSource.getInputSource().setEncoding(encoding)
>
> No need for |org.netbeans.api.mdr.XMIReader| and
> |org.netbeans.api.mdr.XMIWriter|
> These could still exist, but they would be "just like the JMI
> interfaces but different." The original |XMIWriter| and |XMIReader|
> interfaces offered only cosmetic advantages over the JMI-defined
> interfaces, except that they provided a place for extensionExtensible to
> "Live" DOM API
> By adding a |XmiDOMSourceFactory| class analogous to the proposed
> |XmiSAXSourceFactory| class, it will be possible to add support for
> a "live" repository-based DOM implementation. That is, it should be
> possible to create an live view of the repository using the DOM API.
> When the repository is modified, the DOM tree will reflect those
> modifications (and, possibly also fire DOM events
> <http://www.w3.org/TR/DOM-Level-2-Events/>). This would enable, for
> example, rapid prototyping of XSLT stylesheets; as the developer
> creates a stylesheet, she can modify the repository using custom
> scripts or MDR explorer, and get immediate feedback via a
> transformed document.
>
>
> Usage Examples
>
> Yep, these are all untested too, sorry...
>
>
> Copy one extent to another using SAX events
>
>
> Third Round Proposal
>
> XMIReader reader = XMIReaderFactory.getDefault().createXMIReader();
> XMIWriter writer = XMIWriterFactory.getDefault().createXMIWriter();
>
> reader.setExtent(myDestinationExtent);
> writer.setContentHandler(reader);
> writer.setXmiVersion("1.2");
> writer.write(mySourceExtent, null /*outputStream*/, mySystemURI);
>
>
> TrAX-based Proposal
>
> XmiSAXResultFactory resultFactory = XmiSAXResultFactory.getDefault();
> XmiSAXSourceFactory sourceFactory = XmiSAXSourceFactory.getDefault();
>
> SAXResult result = resultFactory.createSAXResult(myDestinationExtent);
> SAXSource source = resultFactory.createSAXSource(mySourceExtent);
> source.setSystemId(mySystemUri);
>
> // the parameter-less newTransformer() call requests the "identity transformation"
> transformerFactory.newTransformer().transform(source, result);
>
>
> Write an XMI document to an output stream, transforming the output
> with an XSLT stylesheet
>
>
> Third Round Proposal
>
> ???
>
>
> TrAX-based Proposal
>
> XmiSAXSourceFactory sourceFactory = XmiSAXSourceFactory.getDefault();
>
> StreamResult result = new StreamResult(destinationURI);
> SAXSource source = sourceFactory.createSAXSource(mySourceExtent);
> source.setSystemId(mySystemUri);
>
> StreamSource stylesheet = new StreamSource(myStylesheetURI);
> transformerFactory.newTransformer(stylesheet).transform(source, result);
>
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]