Re: PROPOSAL (round 2): Extensions to MDR XMI API
Martin Matula <[email protected]>
| Newsgroups | gmane.comp.java.netbeans.modules.mdr.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Holger,
Holger Krug wrote:
> Why then is their a method XMIReader.read(InputSource) ?
It is there for convenience. For the same reason I put
write(OutputTarget) into the XMIWriter interface so that user of XMI
interfaces will not need to know about SAX classes when working with it.
Otherwise the user will not be able to use the XMI API without
hardcoding use of a specific implementation of ContentHandler into their
application. To be able to do that, users will either need to include
the implementation of the ContentHandler in their module (this would
result in having many copies of the same implementation accross
different modules) or I can include the default implementation in MDR
module - this would cause that it would be no longer enough for modules
to depend only on mdrapi, they would also need to depend on the mdr
module itself. Another possibility is to create a separate module
containing just the implementation of ContentHandler, which is also not
so cool.
> As I understand the usual design of XML interfaces it should be done
> this way:
>
> /**
> * Instances of classes implementing this interfaces are supposed
> * to be used in the following way:
> * <pre>
> * XMLReader.parser = XMLReaderFactory.createXMLReader();
> * parser.setContentHandler(xmiReader);
> * parser.parse(inputSource);
> *
> */
> public interface XMIReader extends ContentHandler, Cloneable {
> ... additional interface methods but no read method ...
> }
>
> Having the read(..) method in the interface gives a misleading hint to
> implementors that they are free to implement read(..) as they
> like. But if this would be the case a user would be forced to choose:
> Shall I use the instance of XMIReader I have at hand as ContentHandler
> (see the javadoc above) or directly via read(..). This is ugly, because
> the user has no clue what the difference is. Hence I would recommend
> either to remove read (the preferred solution), or at least to
> document that read(..) is simply a convenience for the user and *must*
> be implemented in a way semantically equivalent to the code given in
> the Javadoc above.
I admit this is a problem. One solution could be to move the read method
into XMIReaderFactory (read(InputSource, XMIReader)) and implement it
there (because XMIReaderFactory is a class). I can even make it final
there although I don't see a reason.
Although this would make the interfaces asymetric with XMIWriterFactory
and XMIWriter.
> Why do you allow to define a collection of extents whereto to write ?
> Do you suppose that a XMIReader should write simultaneously to all
> those extents ? I yes, I think that should be documented in the interface.
I will change XMIReader to take only one extent. See below.
> Here I similarily do not understand why a ContentHandler is one of the
> parameters no the only one:
>
> public interface XMIWriter {
> .. additional parameters but no further write method ..
>
> /**
> * To write to a stream or other kind of output target user
> * can use code like:
> *
> * <pre>
> * Writer writer = ... ;
> * ContentHandler handler = new com.megginson.sax.XMLWriter(writer);
> * xmiWriter.write(handler);
> * </pre>
> *
> * <code>XMLWriter</code> is in the public domain and can be downloaded
> * from <a href="http://www.megginson.com/Software/">here</a>.
> */
> public void write(ContentHandler handler);
>
> }
>
> Having written this I now understand that you need the document URI to
> be able to support the XMIReferenceProvider. OK, so why not simply
> allow the document URI as optional second parameter of write.(..).
OK. But as I said earlier, I would also like to have method that does
not take ContentHandler, or have getDefaultContentHandler method somewhere.
>>- XMIHRefResolver.resolve now receives also a pointer to XMIReader. This
>>is to make it possible for the resolver to clone the instance of
>>XMIReader (this will make a new copy with preserved properties and
>>extents) and read a new XMI file if necessary.
>
>
> Read the new XMI file into which extent(s) ?
Extents can be distinguished by their types, but it is true that now
that we have XMIHRefResolver, it is enough to support only one extent
for each XMIReader and XMIHRefResolver will control which extent goes
where. This will also solve the problem when there are links between
extents of the same type.
So I will change getExtents() method to setExtent(RefPackage).
>
> Do circular references between XMI files pose problems ?
>
Currently yes. We are working on a solution.
> If the XMIHRefResolver shall be able to open a new XMI file and if the
> URI of the new XMI file is given relatively to the original one, it
> must know the URI of the original XMI file.
Yes, it gets it in systemId parameter.
> But the XMIReader may be
> used as ContentHandler and, as such, it does not in every case know
> about the URI, because XML parsers are not forced to call
> ContentHandler.setDocumentLocator(Locator). A solution would be to
> document, that references given by relative URI's may be resolved only
> if ContentHandler.setDocumentLocator(Locator) is called.
Yes, we will document it.
Martin