This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 24266 - XMIReader can't load model written by XMIWriter
Summary: XMIReader can't load model written by XMIWriter
Status: RESOLVED FIXED
Alias: None
Product: java
Classification: Unclassified
Component: Unsupported (show other bugs)
Version: 3.x
Hardware: PC Windows XP
: P3 blocker (vote)
Assignee: Daniel Prusa
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-05-31 01:59 UTC by Mark McKinlay
Modified: 2002-07-19 15:23 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
XMI Meta-model fro list issue (52.36 KB, text/xml)
2002-05-31 02:01 UTC, Mark McKinlay
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mark McKinlay 2002-05-31 01:59:37 UTC
I have a meta-model where the following classes and 
aggregations are present:

LogicGraph - aggregates a collection of of LogicNode
LogicNode - has two aggregation associations of LogicLink. 
One aggregation represents the node's input links, and one 
aggregation represents node's output links.

If I create a model with two LogicNode objects, and one 
LogicLink between the two LogicNodes, then one of the the 
LogicNodes has the LogicLink in its input collection and 
the other LogicNode has the LogicLink in its output 
collection. This is modelled OK (using the Unisys MOF 
plugin for Rose), and I can successfully add instances to 
the MDR using the following code: (where "pkg" is an MDR 
RefPackage extent)

        // Create a simple Graph and two nodes
        LogicGraph graph = pkg.getLogicGraph
().createLogicGraph();
        graph.setName("MyGraph");
        StartLogicNode start = pkg.getStartLogicNode
().createStartLogicNode();
        start.setName("Start Node");
        EndLogicNode end = pkg.getEndLogicNode
().createEndLogicNode();
        end.setName("End Node");
        // Add both nodes to the graph's nodes Collection
        graph.getNodes().add(start);
        graph.getNodes().add(end);
        // Add a link between the nodes by addding the link
        // to one node's input collection and the other 
node's
        // output collection
        LogicLink link = pkg.getLogicLink().createLogicLink
();
        link.setName("StartToEndLink");
        start.getOutLinks().add(link);
        end.getInLinks().add(link);

This is also persisted OK using 
org.netbeans.api.mdr.XMIWriter.getDefault() which produces 
the following XMI fragment:

  <XMI.content>
    <APML.LogicGraph xmi.id = 'a1' name = 'MyGraph'>
      <APML.LogicGraph.nodes>
        <APML.EndLogicNode xmi.id = 'a2' name = 'End Node' 
success = 'false'>
          <APML.LogicNode.inLinks>
            <APML.LogicLink xmi.id = 'a3' name 
= 'StartToEndLink'/>
          </APML.LogicNode.inLinks>
        </APML.EndLogicNode>
        <APML.StartLogicNode xmi.id = 'a4' name = 'Start 
Node'>
          <APML.LogicNode.outLinks>
            <APML.LogicLink xmi.id = 'a3' name 
= 'StartToEndLink'/>
          </APML.LogicNode.outLinks>
        </APML.StartLogicNode>
      </APML.LogicGraph.nodes>
    </APML.LogicGraph>
  </XMI.content>

However, when attempting to load the XMI file into an 
extent using the XMIReader 
(org.netbeans.api.mdr.XMIReader.getDefault()) the 
following exception is thrown.

org.netbeans.lib.jmi.util.DebugException: The same value 
of xmi.idref used second time: a3
	at org.apache.crimson.parser.Parser2.parseInternal
(Parser2.java:524)
	at org.apache.crimson.parser.Parser2.parse
(Parser2.java:305)
	at org.apache.crimson.parser.XMLReaderImpl.parse
(XMLReaderImpl.java:442)
	at javax.xml.parsers.SAXParser.parse
(SAXParser.java:393)
	at org.netbeans.lib.jmi.xmi.XmiSAXReader.read
(XmiSAXReader.java:99)
	at org.netbeans.lib.jmi.xmi.XmiSAXReader.read
(XmiSAXReader.java:71)
	at org.netbeans.lib.jmi.xmi.XMISaxReaderImpl.read
(XMISaxReaderImpl.java:37)
	at 
net.agentis.apml.domain.examples.persist.LoadExtent.execute
(LoadExtent.java:99)
	at 
net.agentis.apml.domain.examples.persist.LoadExtent.perform
Action(LoadExtent.java:70)
	at 
org.openide.util.actions.CallableSystemAction.actionPerform
ed(CallableSystemAction.java:69)
	at org.netbeans.core.ModuleActions$1.run
(ModuleActions.java:105)
	at org.openide.util.Task.run(Task.java:152)
	at 
org.openide.util.RequestProcessor$ProcessorThread.run
(RequestProcessor.java:622)
javax.jmi.xmi.MalformedXMIException: 
org.netbeans.lib.jmi.util.DebugException: The same value 
of xmi.idref used second time: a3
	at org.netbeans.lib.jmi.xmi.XMISaxReaderImpl.read
(XMISaxReaderImpl.java:43)
	at 
net.agentis.apml.domain.examples.persist.LoadExtent.execute
(LoadExtent.java:99)
	at 
net.agentis.apml.domain.examples.persist.LoadExtent.perform
Action(LoadExtent.java:70)
	at 
org.openide.util.actions.CallableSystemAction.actionPerform
ed(CallableSystemAction.java:69)
	at org.netbeans.core.ModuleActions$1.run
(ModuleActions.java:105)
	at org.openide.util.Task.run(Task.java:152)
	at 
org.openide.util.RequestProcessor$ProcessorThread.run
(RequestProcessor.java:622)
javax.jmi.xmi.MalformedXMIException: 
org.netbeans.lib.jmi.util.DebugException: The same value 
of xmi.idref used second time: a3

Clearly the SAXParser complains when both LogicNode 
objects refer to the same instance of LogicLink ('a3').

Should the MDR implementation allow such aggregations, or 
is there a problem with XMIReader?

I notice that if I try to aggregate the same instance of 
an object to multiple container objects via specific 
attributes, e.g.

      // Create one instance of a Graphic
	Graphic myGraphic = pkg.getGraphic().createGraphic
();
      // Create two Logic Graphs
	LogicGraph graphA = pkg.getLogicGraph
().createLogicGraph();
	LogicGraph graphB = pkg.getLogicGraph
().createLogicGraph();
      // Attempt to add the same Graphic to multiple graphs
      graphA.setGraphic(myGraphic);
      graphB.setGraphic(myGraphic); // Oh dear - this 
won't work

Then an exception is thrown when attempting to aggregate 
to the second "graph" object in the MDR.
So should I be able to aggregate to multiple objects via 
Collections (as the original LogicGraph, LogicNode, 
LogicLink example does) or not. If so then I should be 
able to persist and reload the model. If not, then MDR 
probably shouldn't let me aggregate the same object 
instance to multiple aggregated collections.
Comment 1 Mark McKinlay 2002-05-31 02:01:32 UTC
Created attachment 6018 [details]
XMI Meta-model fro list issue
Comment 2 Daniel Prusa 2002-06-05 08:44:12 UTC
I have investigated the attached APML metamodel and I have found out 
that the association end "dest" in the association "LogicInLinks" and 
the association end "src" in "LogicOutLinks" are both of the 
"composite" aggregation type. 
If we have an association containing ends E1 and E2, where e.g. E2 is 
composite, and there exists a link (o1, o2) related to the 
association, then object o1 is considered to be a component of o2. It 
is a simililar situation as in case of attributes' values and it holds 
that an object can be a component of at most one composite object.

Your code performs:
start.getOutLinks().add(link); /* "link" become a component of "start" 
node */
end.getInLinks().add(link); /* a JMI exception should be thrown here, 
"link" cannot become a component of another object */

So the conclusions are: 
1) There is a bug in mdr - it does not check composite relations when 
links are added.
2) XMI Writer does not generate correct XMI files when requirements on 
compositions are not satisfied.
3) Since LogicLink is expected to be connected with two Nodes I 
suggest you to change "composite" aggregation type in both cases to 
"none" aggregation type.
Comment 3 Martin Matula 2002-06-27 21:47:46 UTC
Dan,
can we close this issue?
Comment 4 Daniel Prusa 2002-07-16 10:30:07 UTC
Yes, it can be closed, since checking of composite 
relations has been implemented (point (3) is fixed).