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 Brian,
Thanks for you comments! I am currently preparing the third version of 
the proposal so they came in on time.
See below for my answers to your questions:

Brian Smith wrote:
> It seems that XMIReader and XMIWriter do not implement
> javax.jmi.xmi.XmiReader and javax.jmi.xmi.XmiWriter any more. I wonder 
> if there is going to be a confusion because the MDR XMIReader and 
> XMIWriter operate using a different model than the JMI XmiWriter and 
> XmiReader, but they have nearly identical names.

Hopefuly not. But anyway, do you have better names?

> The new API is notably more complex than the previous one. More tutorial 
> documentation will need to be provided. As a potential user of this API, 
> I would like to see how it works in a "chain" of XML processing like 
> Holger mentioned before: Repository -> XMIWriter -> XSLT processing -> 
> file; file -> XSLT processing -> XMIReader -> repository.

I guess that what Holger had in mind was that there needs to be no file 
in between. Instead, you would do a transformation using transformers 
that consume XMIWriter's output (by implementing ContentHandler 
interfaces), transform it and produce transformed output to another 
ContentHandler which can be either another transformer or XMIReader (as 
it implements ContentHandler interface). The simplest use of this is to 
chain XMIWriter and XMIReader directly without using any transformer in 
between. This way you can e.g. copy content of one extent to another extent.

> Also, I would 
> like to see how the JMI XMI API maps to the MDR XMI API. I.e., how can 
> one acheive the effects of the methods javax.jmi.xmi.XmiReader and 
> XmiWriter using just the MDR API.

It is very straightforward. With the currently proposed API it would 
look like this (it will change a bit in the version 3):
read(InputStream stream, String uri, RefPackage packageExtent):
     XMIReader reader = XMIReaderFactory.getDefault().createXMIReader();
     reader.getExtents().add(pacakgeExtent);
     InputSource is = new InputSource(stream);
     is.setSystemId(uri);
     return reader.read(is);

write(OutputStream stream, RefPackage extent, String xmiVersion):
     XMIWriter writer = XMIWriterFactory.getDefault().createXMIWriter();
     writer.getObjects().add(extent);
     writer.setVersion(xmiVersion);
     writer.write(new OutputTarget(stream));

> 1. I wonder if XMIReference is even needed? Perhaps XMIReferenceProvider
> should have methods like:
>      java.lang.String getXmiId(RefObject o);
>      java.lang.String getDocumentURI(RefObject o);
> 
> This could possibly result in fewer objects being allocated,
> and it would be simpler for the MDR client application to implement one 
> interface instead of two. It also makes the API simpler in the sense 
> that there is "less API."

1) XMIReference is a class, not an interface. It can be even made final. 
I think it is more effective to have one method that resolves both 
documentURI and xmiId as there can be some computation needed for that 
and calling to separate methods can cause that two similar computation 
occur where one could be enough.

> 2. The names "XMIReference" and "XMIReferenceProvider" were good before
> because each instance of XMI Reference represented a single link to a
> serialized object. But, now XMIReference represents the location of that
> object (instead of the link to that location). For example, it is
> possible to generate different kinds of references (xmi.idref, href)
> using the same XMIReference object. So, perhaps "XMILocation" and
> "XMILocationProvider" or "XMILocation" and "XMILocator" would be better
> names? The idea being that XMILocation represents the "serialized 
> location" of the object.

OK, I will try to come up with a better name, but maybe I will leave it 
as is.

> 3. How are document URI's to be compared? Are they just compared by
> String.equals(), or is any URI canonicalization done?

What canonicalization do you mean?

> 4. Since there are numerous XMI-specific classes/interfaces now, with
> more likely on the way, perhaps they should be in a package
> org.netbeans.api.mdr.xmi?

I will think about it.

> 5. How will you document the valid property mappings? It would be nice 
> to have some table of the known values.
> 
> 6. When I add or change a property's value, is it checked for validity? 
> (e.g. does
>     xmiWriter.getProperties().put(XMIReferenceProvider.class,
>                                   <myReferenceProvider>);
> check that <myReferenceProvider> implements XMIReferenceProvider?
> 
> 7. Instead of #5 and #6, maybe XMIReader/XMIWriter could be abstract 
> classes with methods like this (for XMIWriter):
>     XMIReferenceProvider getReferenceProvider();
>     void setReferenceProvider(XMIReferenceProvider p);
>     XMIExtensionProvider getExtensionProvider();
>     void setExtensionProvider(XMIExtensionProvider p);
>     XMIHeaderProvider getHeaderProvider();
>     void setHeaderProvider(XMIHeaderProvider p);
> The idea is that these "property" methods would never be abstract or 
> final, so new ones could be added to the API over time without breaking 
> existing (old) XMIReader/Writer implementations. The advantage is that 
> the classes would be self documenting (see #5 above) and statically 
> type-checked (see #6 above).

I like this approach. I think I will use it.

> 
> 8. I recommend renaming methods in OutputTarget as follows:
>    rename getByteStream      to getOutputStream
>    rename getCharacterStream to getWriter
> These are the names used for similar methods in 
> javax.servlet.ServletResponse.

I wanted to be consistent with xml API, rather than servlet API. In 
org.xml.sax there is a class called InputSource. OutputTarget was meant 
to be the same thing but for output. So I used the same names as in 
InputSource.

> 9. Shouldn't XMIWriter.getObjects() be in OutputTarget? Otherwise, I 
> wouldn't be able to use the same XMIWriter to write multiple documents. 
> Does XMIWriter.getObjects() contain references to _all_ the objects in 
> the XMI document, or just the top-level (uncontained) ones? If I want to 
> serialize a whole package extent, how would I go about doing that?

Objects in getObjects collection are used the same way as objects passed 
in collection to the standard XmiWriter.write method from JMI - i.e. 
they are serialized together with their components transitively.
As documented, you can add also whole RefPackage into this collection,
which causes that the whole extent will be serialized. I should probably 
make it somehow mutualy exclusive.

> 10. Could XMIWriter.getObjects() return java.util.List instead of 
> java.util.Collection? I would like to be able to control the order that 
> top-level (uncontained) objects get written in.

Maybe :)

> 11. Would "XMIDocument" be a better name for OutputTarget? Or, does 
> OutputTarget not really represent an XMI Document?

I think I will remove OutputTarget class from the API. But if not, I 
like the name OutputTarget better because of the mentioned duality with 
InputSource.

> 12. I am confused about OutputTarget.getSystemId(). Is this the same as 
> XMIReference.getDocumentURI()? What is the difference? Similarly, what 
> does OutputTarget.getPublicId() represent? My (limited) understanding of 
> XML is that documents don't really have system and public identifiers 
> but that only XML DTD's and XML notations do.

Again - it was taken from InputSource. SystemId is InputSources name for 
URI I guess, so yes, systemID is identical to documentURI.
Martin
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.