Bug 56184

Summary: Support loading of foreign XMI file formats
Product: [Applications] umbrello Reporter: Sven Fischer <sven>
Component: generalAssignee: Umbrello Development Group <umbrello-devel>
Status: REOPENED ---    
Severity: wishlist CC: okellogg, ralf.habacker
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Debian testing   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: uml14.xmi (demonstrates XMI format from nsuml)
demonstrates XMI format from Unisys
DiagramDynamic.xmi - state diagram created by TogetherSoft
EAExample-DesignModel-xmi12.xmi - XMI file created by Enterprise Architect
poseidon321.xmi - XMI file exported from Poseidon 3.2.1
http://fisheye.codehaus.org/browse/~raw,r=2486/mapbuilder/tags/mapbuilder-lib-1_5-rc1/mapbuilder/design/uml/mapbuilder.xmi
eclipse_uml_demo.xmi
https://github.com/csware/argouml/blob/master/www/tours/enroll.zargo
http://argouml.tigris.org/tours/enroll_usecase.zargo
Demo file for the format generated by Embarcadero's "Describe" UML tool
XMI 2.1 demo file generated using Enterprise Architect 12
Demo XMI file showing the format used by OMG
Demo XMI file showing the format used by OMG
Demo XMI file showing the format used by Software Ideas Modeler

Description Sven Fischer 2003-03-20 16:56:24 UTC
Version:            (using KDE KDE 3.1)
Installed from:    Debian testing/unstable Packages
OS:          Linux

The file save format of Umbrello should conform to the file format specified with the uml13.dtd to increase interoperability with other tools like ArgoUML, Rhapsody etc. which are also using XMI with this DTD.
Comment 1 Stevan White 2003-04-30 05:16:52 UTC
I just tried to read an Umbrello 1.1.1 file with Poseidon UML CE 1.6.1 (see
http://www.gentleware.com).  No luck.  I don't know whose fault this is.  I'll
let you hash it out.
Comment 2 Oliver Kellogg 2003-10-26 10:49:05 UTC
The file format used by Umbrello does not conform to any version
of the XMI standard.

For some further discussion see e.g.
 http://www.dstc.edu.au/ListArchive/xmi/archive/2003/01/msg00009.html

I'm starting work on changing the file format to at least remotely
resemble XMI (the tricky part being to continue supporting the
old format), but unfortunately the repair of this problem
won't make it into umbrello-1.2.
Comment 3 Oliver Kellogg 2003-12-26 15:48:14 UTC
Some progress was made, we now have a <UML:Model> tag.
Associations are saved using the <UML:Association> tag
appropriately (i.e. using the inner tags
<UML:Association.connection> and <UML:AssociationEnd>).
Generalizations are saved using the <UML:Generalization>
tag, but no use is made of the "generalization" attribute
(to be checked: is this okay?)

Still on the TODO list (i.e. not ready for version 1.2)
are at least the following:

* Get rid of the non-standard tags such as <docsettings>,
  <diagrams>, <listview>, i.e. use the proper XMI extension
  mechanism. (Furthermore, for <diagram> use SVG.)
* Saving of realizations. With the ID-based logic that
  Umbrello currently uses for saving/loading UMLAssociations,
  we would need a <UML:Realization> tag, but there is no such
  thing.
* Validate the XMI produced.
Comment 4 Oliver Kellogg 2004-01-06 23:15:25 UTC
A first interop test:

http://www.jeckle.de/example1_xmiv11.xml

Checkins to follow shortly.
Comment 5 Oliver Kellogg 2004-04-24 15:45:02 UTC
Created attachment 5760 [details]
uml14.xmi (demonstrates XMI format from nsuml)
Comment 6 Oliver Kellogg 2004-04-24 15:48:35 UTC
I plan to have the following two files loadable by umbrello shortly:

  http://cvs.sourceforge.net/viewcvs.py/nsuml/nsuml1_4/model/uml14.xml

and the above attachment. For requests of interoperation with a
specific tool, please give a URL of a sample, or create an attachment.
Comment 7 Oliver Kellogg 2004-05-01 01:41:46 UTC
We're getting there: The classes (including attributes) and
packages from the demo files are getting loaded.
XMI tags not currently supported are UML:Tag, UML:Import,
UML:Reference, UML:Multiplicity.
Comment 8 Oliver Kellogg 2004-05-04 06:55:17 UTC
Setting to works-for-me to indicate that in principle,
the XMI format used by umbrello is now standards compliant.
Operations need a little more work, which will be done
within the next few days.
Comment 9 Oliver Kellogg 2004-07-25 19:04:45 UTC
Unfortunately the save format for template and stereotypes is not yet
standards compliant, which probably means it will be that way in Umbrello 1.3.
Generally the template and stereotype handling code in Umbrello needs
major work.
Comment 10 Oliver Kellogg 2004-08-05 22:51:54 UTC
> Unfortunately the save format for template and stereotypes is not yet 
> standards compliant, [...]

Minor update: I managed to correct the save format for stereotypes
just in time before the total freeze for 1.3.

Another remark for 1.3: I've tried loading foreign XMI files into umbrello
but haven't tried loading Umbrello generated files into other tools.
Comment 11 Oliver Kellogg 2004-08-12 01:31:33 UTC
Need to reopen this because the "type" attribute of
<UML:Attribute> should be an xmi.id not a plain name.
Fix is forthcoming.
Comment 12 Oliver Kellogg 2004-08-14 18:29:02 UTC
The "type" attribute of <UML:Attribute> and <UML:Parameter> is now an
xmi.id not a plain name.
(Unfortunately this change didn't make it into 1.3.)
Also XML comments are handled properly. For example, it is now
possible to load the following file:

http://ncicb.nci.nih.gov/content/ncicblfs/caBIOmdlandxmi/caCORE2.1_XMI_Pub.xmi

Nevertheless I leave this REOPENED because there is still more work to do.
Comment 13 Oliver Kellogg 2004-08-26 09:43:26 UTC
Further tests with foreign XMI files show that forward references
are ubiquitously used.
However, until recently Umbrello only did ad hoc xmi.id resolution
(the object referred to by an xmi.id must already be known at the
point of reference during load.)
Work is currently underway for adding a deferred type resolution pass.
Comment 14 Oliver Kellogg 2004-09-12 13:02:03 UTC
The separate xmi.id resolution pass is now in place.
Also, Umbrello's internal storage type for xmi.id's
is now string (before, it was int) and this normalizes
the ID handling across foreign vs. native XMI files.
Comment 15 Oliver Kellogg 2004-10-27 08:09:45 UTC
From http://mde.abo.fi/tools/Coral/documentation/compatibility/ :

> Umbrello 1.3 does not generate XMI files correctly since it does not
> include the name of the properties in composition associations.
> Therefore, Coral cannot load models generated by Umbrello.
Comment 16 Oliver Kellogg 2004-10-29 23:12:50 UTC
From Ivan Porres (developer of Coral, http://sourceforge.net/projects/coral)

<quote>
 The main problem with the generated XMI is that it does not add the names of
 the properties in compositions. For example:
 
 Umbrello generates:

 <UML:Model>
    <UML:Stereotype visibility="public" xmi.id="13" name="actor" />
    <UML:Stereotype visibility="public" xmi.id="15" name="class" />
    <UML:Stereotype visibility="public" xmi.id="17" name="datatype" />
    <UML:DataType stereotype="17" visibility="public" xmi.id="16" name="void" />
   <UML:Class visibility="public" xmi.id="6" name="UMLListView" >
 ...

 When it should generate:

 <UML:Model>
   <UML:ModelElement.stereotype>
    <UML:Stereotype visibility="public" xmi.id="13" name="actor" />
    <UML:Stereotype visibility="public" xmi.id="15" name="class" />
    <UML:Stereotype visibility="public" xmi.id="17" name="datatype" />
   </UML:ModelElement.stereotype>

   <UML:Namespace.ownedElement>

   <UML:DataType stereotype="17" visibility="public" xmi.id="16" name="void" />
   <UML:Class visibility="public" xmi.id="6" name="UMLListView" >
    <UML:Classifier.feature>
     <UML:Operation visibility="public" xmi.id="77" type="16" name="contentsMousePressEvent" />
     <UML:Operation visibility="public" xmi.id="80" type="16" name="popupMenuSel" />
     <UML:Operation visibility="public" xmi.id="32" type="16"
name="addNewItem" />
     <UML:Operation visibility="public" xmi.id="53" type="16"
name="slotItemRenamed" />
     <UML:Operation visibility="public" xmi.id="56" type="16"
name="createChildUMLObject" />
    </UML:Classifier.feature>


 Also, Umbrello does not conform to the UML 1.3 standard. IIRC, A UML 1.3
 Operation does not have a property called type. Check the standard.  Is this
 the return type of the operation? This is modeled by creating a  Parameter
 with direction "return" and the desired type.
</quote>

Implemented these suggestions and updated the sample file
http://uml.sourceforge.net/developers/CreateOperationUsingRightMousebuttonInListView.xmi
Comment 17 Oliver Kellogg 2004-11-05 09:46:07 UTC
Might close this PR when Umbrello satisfies all of the following:

http://www.innoq.com/iqgen/help-r2.1.0/basic-html/ch04s07.html
Comment 18 Oliver Kellogg 2004-12-12 23:44:43 UTC
If on loading a foreign file nothing is displayed in the
list view, try saving the model under a different name,
and loading the saved file. Usually the list view is then
properly populated.
Comment 19 Oliver Kellogg 2004-12-14 22:34:40 UTC
Created attachment 8666 [details]
demonstrates XMI format from Unisys

This file showcases recent work on umbrello cvs head
for loading foreign files (in particular, associations
are now getting loaded.)
Comment 20 Oliver Kellogg 2004-12-19 20:54:08 UTC
From Marcus Alanen (developer of Coral, http://sourceforge.net/projects/coral)

<quote>
What is XMI.exporterEncoding ?? XMI 1.2 does not have it.

The timestamp is missing. I suggest using RFC822-conformant dates.
See man strftime, and use "%a,  %d  %b  %Y  %H:%M:%S  %z" or take the 
code from Coral.

XMI.model requires xmi.version. (or leave the whole XMI.model out, it's 
not required)

UML 1.3 namespace is "http://schema.omg.org/spec/UML/1.3", or is the
"omg.org/UML/1.3" some compatibility namespace? Poseidon uses an unofficial
namespace as well for UML 1.4 + Diagrams. Not important...

Packages (and thus also UML:Model) lacks
- isAbstract="false"
- isLeaf="false"
- isRoot="false"
- isSpecification="false">

[...]
Classes lack:
- isAbstract="false"
- isLeaf="false"
- isRoot="false"
- isSpecification="false">

Generalization lacks:
- name = ""
- discriminator = ""
- isSpecification = "false"
Additionally, each subClass needs a
     <UML:GeneralizableElement.generalization>
      <UML:Generalization xmi.idref="e5" />
     </UML:GeneralizableElement.generalization>
where "e5" here means the id of the Generalization.
There ought to be a similar thing for superclasses,
     <UML:GeneralizableElement.specialization>
      <UML:Generalization xmi.idref="e5" />
     </UML:GeneralizableElement.specialization>
but some tools skip this...

Actors lack:
- isAbstract="false"
- isRoot="false"
- isSpecification="false"
- isLeaf="false"

[...]

Dependency is completely missing!
</quote>

<UML:Dependency> is now implemented.
Further adjustments will follow shortly.
Comment 21 Oliver Kellogg 2004-12-21 23:39:41 UTC
From Marcus Alanen (maalanen_AT_ra.abo.fi)
<quote>

Stereotype should have an icon="" and baseClass="" attribute.

[...]
AssociationEnds should not have isLeaf, isRoot, isAbstract. 
(isSpecification should be there)

AssociationEnds should further have
- isNavigable = "(true|false)"
- type = "id"  where id is the id of the class where we point to
- ordering = "(unordered|ordered)" if order of elements matters
- aggregation = "(none|aggregate|composite)" (nothing, empty diamond, 
black diamond)
- targetScope = "(instance|classifier)"  if it points to objects or classes
- changeability = "(changeable|frozen|addOnly)"

Above, I've tried to give the "most suitable" enumeration value first.

Classes should have:
     <UML:Classifier.associationEnd>
      <UML:AssociationEnd xmi.idref="e3" />
     </UML:Classifier.associationEnd>

where e3 is the AssociationEnd they have. By the way you can add several 
 easily with
     <UML:Classifier.associationEnd>
      <UML:AssociationEnd xmi.idref="e3" />
      <UML:AssociationEnd xmi.idref="e4" />
      <UML:AssociationEnd xmi.idref="e5" />
       ....
     </UML:Classifier.associationEnd>

instead of

     <UML:Classifier.associationEnd>
      <UML:AssociationEnd xmi.idref="e3" />
     </UML:Classifier.associationEnd>
     <UML:Classifier.associationEnd>
      <UML:AssociationEnd xmi.idref="e4" />
     </UML:Classifier.associationEnd>
      ...

This goes for any such constructs.

All AssociationEnds must have exactly one Multiplicity element as well:
       <UML:AssociationEnd.multiplicity>
        <UML:Multiplicity xmi.id="e7" >
            ....
        </UML:Multiplicity>
       </UML:AssociationEnd.multiplicity>

There can be 0 to many MultiplicityRanges inside a Multiplicity.
        <UML:Multiplicity.range>
          <UML:MultiplicityRange xmi.id="e8" lower = "0" upper = "5" />
          <UML:MultiplicityRange xmi.id="e8" lower = "12" upper = "14" />
          <UML:MultiplicityRange xmi.id="e8" lower = "100" upper = "-1" />
        </UML:Multiplicity.range>

Regarding XMI.extensions, I think you should declare the XML namespace
(with xmlns:umbrello="http://blahblah/") either
- at top-level XMI together with the xmlns:UML definition,
- at XMI.extensions
- at *every* top-level element inside XMI.extensions:

I think the first one is easiest, and hopefully doesn't cause any 
compatibility problems with other tools. Anyway, you need then a 
"umbrello:" prefix for every top-level element inside XMI.extensions:
  <umbrello:docsettings viewid="118" documentation="" uniqueid="133" />
  <umbrello:diagrams> ....</ >
  <umbrello:listview> ....</ >
   ... etc..

The string doesn't have to be "umbrello", it can be anything you want, 
since the xmlns declaration is the key.

</quote>
Comment 22 Marcus Alanen 2004-12-23 14:09:29 UTC
*** 

Currently, AssociationEnds sometimes have and sometimes don't
the isNavigable and aggregation attributes. They are both mandatory.

e.g. I get

      <UML:AssociationEnd ... aggregation="none" type="146" name="" />
      <UML:AssociationEnd ... type="145" name="" />

as well as

      <UML:AssociationEnd ... aggregation="none" type="145" name="" />
      <UML:AssociationEnd ... isNavigable="true" type="147" name="" />

***

Adding containment between a Class and another Class makes it
use the "feature" property, which is incorrect (very much so, since
feature ought to contain Feature-types, not Classes). It should use
"ownedElement" instead. I.e.

    <UML:Class ... name="new_class" >
     <UML:Classifier.feature>
      <UML:Class name="new_class_1" />
     </UML:Classifier.feature>
    </UML:Class>

becomes s/feature/ownedElement.

*** 

Dependency mustn't have isLeaf, isRoot, isAbstract.

*** 

Generalization mustn't have isLeaf, isRoot, isAbstract.


Comment 23 Oliver Kellogg 2005-01-02 00:52:59 UTC
CVS commit by okellogg: 

Comment by M. Alanen:
> Additionally, each subClass needs a 
>      <UML:GeneralizableElement.generalization> 
>       <UML:Generalization xmi.idref="e5" /> 
>      </UML:GeneralizableElement.generalization> 
> where "e5" here means the id of the Generalization. 
CCBUG:56184


  M +15 -0     classifier.cpp   1.65


--- kdesdk/umbrello/umbrello/classifier.cpp  #1.64:1.65
@@ -432,4 +432,19 @@ void UMLClassifier::saveToXMI(QDomDocume
                 qElement.appendChild( tmplElement );
         }
+        //save generalizations (we are the subclass, the other end is the superclass)
+        UMLAssociationList generalizations = getSpecificAssocs(Uml::at_Generalization);
+        if (generalizations.count()) {
+                QDomElement genElement = qDoc.createElement("UML:GeneralizableElement.generalization");
+                for (UMLAssociation *a = generalizations.first(); a; a = generalizations.next()) {
+                        // We are the subclass if we are at the role A end.
+                        if (m_nId != a->getObjectId(Uml::A))
+                                continue;
+                        QDomElement gElem = qDoc.createElement("UML:Generalization");
+                        gElem.setAttribute( "xmi.idref", ID2STR(a->getID()) );
+                        genElement.appendChild(gElem);
+                }
+                if (genElement.hasChildNodes())
+                        qElement.appendChild( genElement );
+        }
 }
 


Comment 24 Oliver Kellogg 2005-01-02 16:40:57 UTC
Marcus Alanen wrote:
> AssociationEnds should further have 
> - isNavigable = "(true|false)" 
> - type = "id"  where id is the id of the class where we point to
> - ordering = "(unordered|ordered)" if order of elements matters
> - aggregation = "(none|aggregate|composite)" (nothing, empty diamond,
>  black diamond) 

Just to make sure I am understanding, here are my assumptions:

1) Simple (undirected) association between class A and class B

AssociationEnd A:  isNavigable="true"
AssociationEnd B:  isNavigable="true

2) Directed association from class A to class B
   (arrowhead at B)

AssociationEnd A:  isNavigable="false"
AssociationEnd B:  isNavigable="true"

3) Aggregation: A has a reference to B
   (hollow diamond at A)

AssociationEnd A:  isNavigable="false" aggregation="aggregate"
AssociationEnd B:  isNavigable="true" aggregation="none"

4) Composition: A contains an instance of B
   (solid diamond at A)

AssociationEnd A:  isNavigable="false" aggregation="composite"
AssociationEnd B:  isNavigable="true" aggregation="none"

aggregation="none" if not stated otherwise,
targetScope="instance" and ordering="false" in all cases.

Okay?
Comment 25 Marcus Alanen 2005-01-02 18:58:01 UTC
> 1) Simple (undirected) association between class A and class B
> 
> AssociationEnd A:  isNavigable="true"
> AssociationEnd B:  isNavigable="true

Yes, OK.

> 2) Directed association from class A to class B
>    (arrowhead at B)
> 
> AssociationEnd A:  isNavigable="false"
> AssociationEnd B:  isNavigable="true"

I had to check... This is how we're doing it as well. OK.

> 3) Aggregation: A has a reference to B
>    (hollow diamond at A)
> 
> AssociationEnd A:  isNavigable="false" aggregation="aggregate"
> AssociationEnd B:  isNavigable="true" aggregation="none"

OK, although there's no reason why isNavigable couldn't be true
also at the A end. The way you do it above, you should draw it
as a hollow diamond at A, and an arrowhead at B. (In programming you
even quite often have this case, where the "B" objects have a pointer
to their parent "A" element)

> 4) Composition: A contains an instance of B
>    (solid diamond at A)
> 
> AssociationEnd A:  isNavigable="false" aggregation="composite"
> AssociationEnd B:  isNavigable="true" aggregation="none"

Ditto here.

> aggregation="none" if not stated otherwise,
> targetScope="instance" and ordering="false" in all cases.

OK.

Comment 26 Oliver Kellogg 2005-01-03 06:55:48 UTC
CVS commit by okellogg: 

Comment by M. Alanen:
> Currently, AssociationEnds sometimes have and sometimes don't
> the isNavigable and aggregation attributes. They are both mandatory. 
CCBUG:56184


  M +10 -0     association.cpp   1.64
  M +15 -2     association.h   1.33
  M +27 -11    umlrole.cpp   1.37



Comment 27 Oliver Kellogg 2005-01-10 15:20:51 UTC
Created attachment 9024 [details]
DiagramDynamic.xmi - state diagram created by TogetherSoft

While Umbrello is approaching standard conformance for class diagram related
objects, there is still much work to do for sequence and state diagram related 
objects. This file demonstrates the XMI for objects of a state diagram.
Comment 28 Oliver Kellogg 2005-02-12 08:18:41 UTC
With the checkins of yesterday and today, Umbrello basically loads all of the samples from the XMI interop test presented at http://www.ida.his.se/~pesn/study/Study.pdf (see http://sourceforge.net/mailarchive/forum.php?thread_id=6540126&forum_id=472).
More fine tuning is required. For example, after loading some of the files Umbrello appears to be empty. The trick in that case is to save the seemingly empty model, close Umbrello, and reload the saved file.
Thanks to Anna Persson for providing the sample XMI files.
Comment 29 Oliver Kellogg 2005-02-12 17:39:22 UTC
CVS commit by okellogg: 

load(): Fix loading of multiplicities from foreign XMI files.
CCBUG:56184


  M +1 -0      umlrole.cpp   1.39


--- kdesdk/umbrello/umbrello/umlrole.cpp  #1.38:1.39
@@ -225,4 +225,5 @@ bool UMLRole::load( QDomElement & elemen
                                 continue;
                         }
+                        tempElement = n.toElement();
                         tag = tempElement.tagName();
                         if (!Uml::tagEq(tag, "Multiplicity")) {


Comment 30 Oliver Kellogg 2005-05-08 17:25:13 UTC
The newly added support for association classes is not yet standard
compliant (we should create the <UML:AssociationClass> element)
Comment 31 graeme foster 2005-06-27 08:42:44 UTC
Some observatiosn regarding compliance of the classes:

1) Attribute doesn't inherit from GeneralizableElement and so it shoudln't have isRoot, isLeaf or isAbstract

2) isRoot always appears to be set to false. Is shoudl be true for root classes and Operations.
Comment 32 Marcus Alanen 2005-06-27 12:32:23 UTC
> Some observatiosn regarding compliance of the classes:
> 
> 1) Attribute doesn't inherit from GeneralizableElement and so it shoudln't 
> have isRoot, isLeaf or isAbstract

Verified. They should indeed be removed.

> 2) isRoot always appears to be set to false. Is shoudl be true for root 
> classes and Operations.

No. UML 1.3 section 2.5.3.18 (part 1) states "A root cannot have any Generalizations: self.isRoot implies self.generalization->isEmpty". I take this to mean that if you set isRoot of a Class to true, then you cannot add superclasses to that class anymore (Similarly for isLeaf: you can't add subclasses).

The importance of using isRoot in the first place is quite questionable. Sometimes people would like to make their classes non-subclassable (i.e. isLeaf support), but even that is mostly bad design. But I _think_ Java's "final class..." supports this.

I wouldn't bother with isLeaf or isRoot, but I'm all talk, no code.

Comment 33 graeme foster 2005-06-27 14:46:15 UTC
Because Java has the final keyword this is where isLeaf is used (for
either classes or methods)

I must admit that I'd interpreted isRoot more as a doesn't have rather
than a can't have. Off the top of my head I can't think of a construct
that prevents superclassing (if that's a word?)

graeme

On 27 Jun 2005 10:32:24 -0000, Marcus Alanen <maalanen@abo.fi> wrote:
[bugs.kde.org quoted mail]
Comment 34 Marcus Alanen 2005-06-27 15:23:04 UTC
> I must admit that I'd interpreted isRoot more as a doesn't have rather
> than a can't have. Off the top of my head I can't think of a construct
> that prevents superclassing (if that's a word?)


I'd say the interpretation is still "can't have". The rule 2.5.3.18 
explictly says "A root cannot have any Generalizations". So if isRoot == 
true it indeed prevents superclassing. I don't understand why anybody 
would need such a thing, though.
Comment 35 Oliver Kellogg 2005-07-02 16:11:56 UTC
SVN commit 430870 by okellogg:

save(): Comment #31 From graeme foster 2005-06-27 08:42:
> 1) Attribute doesn't inherit from GeneralizableElement and so it shouldn't
> have isRoot, isLeaf or isAbstract

CCBUG:56184


 M  +3 -1      umlobject.cpp  


--- trunk/KDE/kdesdk/umbrello/umbrello/umlobject.cpp #430869:430870
@@ -451,7 +451,9 @@
 	*/
 	QDomElement qElement = qDoc.createElement(tag);
 	qElement.setAttribute( "isSpecification", "false" );
-	if (m_BaseType != Uml::ot_Association && m_BaseType != Uml::ot_Role) {
+	if (m_BaseType != Uml::ot_Association &&
+	    m_BaseType != Uml::ot_Role &&
+	    m_BaseType != Uml::ot_Attribute) {
 		qElement.setAttribute( "isLeaf", "false" );
 		qElement.setAttribute( "isRoot", "false" );
 		if (m_bAbstract)
Comment 36 Oliver Kellogg 2005-11-27 20:25:05 UTC
SVN commit 483699 by okellogg:

Give the <UML:Model> an xmi.id.
Add the attribute "namespace" when saving the XMI of UMLObjects.
These changes get Umbrello files imported into StarUML
(http://www.staruml.com)
CCBUG:56184


 M  +6 -0      umldoc.cpp  
 M  +7 -0      umldoc.h  
 M  +6 -0      umlobject.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umldoc.cpp #483698:483699
@@ -90,6 +90,7 @@
 
 UMLDoc::UMLDoc() {
     m_Name = i18n("UML Model");
+    m_modelID = "m1";
     m_currentView = 0;
     m_uniqueID = 0;
     m_count = 0;
@@ -1494,6 +1495,10 @@
     return m_Name;
 }
 
+Uml::IDType UMLDoc::getModelID() const {
+    return m_modelID;
+}
+
 void UMLDoc::saveToXMI(QIODevice& file, bool saveSubmodelFiles /* = false */) {
     QDomDocument doc;
 
@@ -1570,6 +1575,7 @@
     QDomElement contentNS = doc.createElement( "UML:Namespace.contents" );
 
     QDomElement objectsElement = doc.createElement( "UML:Model" );
+    objectsElement.setAttribute( "xmi.id", ID2STR(m_modelID) );
     objectsElement.setAttribute( "name", m_Name );
     objectsElement.setAttribute( "isSpecification", "false" );
     objectsElement.setAttribute( "isAbstract", "false" );
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umldoc.h #483698:483699
@@ -432,6 +432,12 @@
     QString getName() const;
 
     /**
+     * Return the m_modelID (currently this a fixed value:
+     * Umbrello supports only a single document.)
+     */
+    Uml::IDType getModelID() const;
+
+    /**
      * Used to give a unique ID to any sort of object.
      *
      * @return  A new unique ID.
@@ -931,6 +937,7 @@
     int m_uniqueID;
 
     QString m_Name; ///< name of this model as stored in the <UML:Model> tag
+    Uml::IDType m_modelID; ///< xmi.id of this model in the <UML:Model>
     int m_count;   ///< auxiliary counter for the progress bar
     bool m_modified;
     KURL m_doc_url;
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlobject.cpp #483698:483699
@@ -471,6 +471,12 @@
     }
     qElement.setAttribute( "xmi.id", ID2STR(m_nId) );
     qElement.setAttribute( "name", m_Name );
+    Uml::IDType nmSpc;
+    if (m_pUMLPackage)
+        nmSpc = m_pUMLPackage->getID();
+    else
+        nmSpc = UMLApp::app()->getDocument()->getModelID();
+    qElement.setAttribute( "namespace", ID2STR(nmSpc) );
     if (! m_Doc.isEmpty())
         qElement.setAttribute( "comment", m_Doc );  //CHECK: uml13.dtd compliance
 #ifdef XMI_FLAT_PACKAGES
Comment 37 Oliver Kellogg 2005-11-30 07:58:18 UTC
SVN commit 484294 by okellogg:

First set of changes motivated by comments from Tom Morris for loading
Umbrello files into ArgoUML-0.20alpha2.
CCBUG:56184


 M  +1 -0      THANKS  
 M  +2 -1      umbrello/attribute.cpp  
 M  +1 -1      umbrello/classifier.cpp  
 M  +10 -6     umbrello/umlobject.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/THANKS #484293:484294
@@ -46,6 +46,7 @@
 martin <mv123q3 @hotmail.com>
 Rene Meyer <Rene.Meyer @sturmit.de>
 Laurent Montel <montel @kde.org>
+Tom Morris <tfmorris @gmail.com>
 Lutz Mueller <lutz.mueller @gmx.de>
 Heiko Nardmann <heiko.nardmann @onlinehome.de>
 Dimitri Ognibene <ognibened @yahoo.it>
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/attribute.cpp #484293:484294
@@ -188,7 +188,8 @@
     } else {
         attributeElement.setAttribute( "type", ID2STR(m_pSecondary->getID()) );
     }
-    attributeElement.setAttribute( "initialValue", m_InitialValue );
+    if (! m_InitialValue.isEmpty())
+        attributeElement.setAttribute( "initialValue", m_InitialValue );
     qElement.appendChild( attributeElement );
 }
 
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/classifier.cpp #484293:484294
@@ -775,7 +775,7 @@
             genElement.appendChild(gElem);
         }
         if (genElement.hasChildNodes())
-            qElement.appendChild( genElement );
+            classifierElement.appendChild( genElement );
     }
 
     // save attributes
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlobject.cpp #484293:484294
@@ -471,12 +471,16 @@
     }
     qElement.setAttribute( "xmi.id", ID2STR(m_nId) );
     qElement.setAttribute( "name", m_Name );
-    Uml::IDType nmSpc;
-    if (m_pUMLPackage)
-        nmSpc = m_pUMLPackage->getID();
-    else
-        nmSpc = UMLApp::app()->getDocument()->getModelID();
-    qElement.setAttribute( "namespace", ID2STR(nmSpc) );
+    if (m_BaseType != Uml::ot_Operation &&
+            m_BaseType != Uml::ot_Role &&
+            m_BaseType != Uml::ot_Attribute) {
+        Uml::IDType nmSpc;
+        if (m_pUMLPackage)
+            nmSpc = m_pUMLPackage->getID();
+        else
+            nmSpc = UMLApp::app()->getDocument()->getModelID();
+        qElement.setAttribute( "namespace", ID2STR(nmSpc) );
+    }
     if (! m_Doc.isEmpty())
         qElement.setAttribute( "comment", m_Doc );  //CHECK: uml13.dtd compliance
 #ifdef XMI_FLAT_PACKAGES
Comment 38 Oliver Kellogg 2005-12-10 17:38:50 UTC
SVN commit 487430 by okellogg:

load(): In UML 1.4, the aggregation attribute has a value "aggregate"
instead of "shared". Thanks to Tom Morris for pointing this out.
CCBUG:56184


 M  +2 -1      umlrole.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlrole.cpp #487429:487430
@@ -298,7 +298,8 @@
         QString aggregation = element.attribute("aggregation", "none");
         if (aggregation == "composite")
             m_pAssoc->setAssocType(Uml::at_Composition);
-        else if (aggregation == "shared")
+        else if (aggregation == "shared"       // UML1.3
+              || aggregation == "aggregate")   // UML1.4
             m_pAssoc->setAssocType(Uml::at_Aggregation);
         /* else
                 m_pAssoc->setAssocType(Uml::at_Association);  */
Comment 39 Oliver Kellogg 2005-12-20 23:29:56 UTC
SVN commit 490149 by okellogg:

{set,get}{Name,Doc}, m_{Name,Doc}: Remove erroneous duplication from parent.
load(): StarUML puts the aggregation value at role B so load the aggregation
 attribute on both roles.
CCBUG:56184


 M  +11 -28    umlrole.cpp  
 M  +0 -31     umlrole.h  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlrole.cpp #490148:490149
@@ -55,14 +55,6 @@
     return m_Multi;
 }
 
-QString UMLRole::getName() const {
-    return m_Name;
-}
-
-QString UMLRole::getDoc() const {
-    return m_Doc;
-}
-
 void UMLRole::setObject (UMLObject *obj) {
     // because we will get the id of this role from the parent
     // object, we CANT allow UMLRoles to take other UMLRoles as
@@ -89,16 +81,6 @@
     emit modified();
 }
 
-void UMLRole::setName( const QString &roleName ) {
-    m_Name = roleName;
-    emit modified();
-}
-
-void UMLRole::setDoc( const QString &doc ) {
-    m_Doc = doc;
-    emit modified();
-}
-
 Uml::Role_Type UMLRole::getRole() {
     return m_role;
 }
@@ -294,16 +276,17 @@
     // the component roles/linked items needs to be done in order to get things
     // right. *sigh* -b.t.
 
-    if (m_role == Uml::A) {  // setting association type from the role (A)
-        QString aggregation = element.attribute("aggregation", "none");
-        if (aggregation == "composite")
-            m_pAssoc->setAssocType(Uml::at_Composition);
-        else if (aggregation == "shared"       // UML1.3
-              || aggregation == "aggregate")   // UML1.4
-            m_pAssoc->setAssocType(Uml::at_Aggregation);
-        /* else
-                m_pAssoc->setAssocType(Uml::at_Association);  */
-    }
+    // Setting association type from the role (A)
+    // Determination of the "aggregation" attribute used to be done only
+    // when (m_role == Uml::A) but some XMI writers (e.g. StarUML) place
+    // the aggregation attribute at role B.
+    // The role end with the aggregation unequal to "none" wins.
+    QString aggregation = element.attribute("aggregation", "none");
+    if (aggregation == "composite")
+        m_pAssoc->setAssocType(Uml::at_Composition);
+    else if (aggregation == "shared"       // UML1.3
+          || aggregation == "aggregate")   // UML1.4
+        m_pAssoc->setAssocType(Uml::at_Aggregation);
 
     if (!element.hasAttribute("isNavigable")) {
         /* Backward compatibility mode: In Umbrello version 1.3.x the
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlrole.h #490148:490149
@@ -67,20 +67,6 @@
     QString getMultiplicity() const;
 
     /**
-     * Returns the name assigned to the role.
-     *
-     * @return  The name assigned to the role.
-     */
-    QString getName() const;
-
-    /**
-     * Returns the documentation for the role.
-     *
-     * @return  The documentation text for the role.
-     */
-    QString getDoc() const;
-
-    /**
      * Sets the UMLObject playing the role in the association.
      *
      * @param obj               Pointer to the UMLObject of role.
@@ -101,20 +87,6 @@
      */
     void setMultiplicity ( const QString &multi );
 
-    /**
-     * Sets the name of the role.
-     *
-     * @param roleName  The name of role.
-     */
-    void setName( const QString &roleName );
-
-    /**
-     *  Sets the documentation on the role.
-     *
-     *  @param doc              The string with the documentation.
-     */
-    void setDoc( const QString &doc );
-
     UMLAssociation * getParentAssociation ();
 
     // Sets the m_SecondaryId
@@ -152,13 +124,10 @@
     /** do some initialization at construction time */
     void init (UMLAssociation * parent, UMLObject * parentObj, Uml::Role_Type r);
 
-    QString m_Doc;
     UMLAssociation * m_pAssoc;
     Uml::Role_Type m_role;
-    QString m_Name;
     QString m_Multi;
     Uml::Changeability_Type m_Changeability;
-
 };
 
 #endif
Comment 40 Oliver Kellogg 2005-12-25 19:08:30 UTC
Created attachment 14038 [details]
EAExample-DesignModel-xmi12.xmi - XMI file created by Enterprise Architect

This demonstrates the XMI format of Enterprise Architect 5.00.764,
XMI.exporterVersion 4.1.
On exporting, it is important to select the XMI version 1.2 in the
"Export Package to XMI" options.
Comment 41 Marcus Alanen 2005-12-29 18:10:08 UTC
> EAExample-DesignModel-xmi12.xmi - XMI file created by Enterprise Architect

> This demonstrates the XMI format of Enterprise Architect 5.00.764,
> XMI.exporterVersion 4.1. 

Hi, please note that Enterprise Architect creates very bad XMI files:

- AssociationEndRoles shouldn't have "type" and "isOrdered", I think.
- TaggedValues come directly after an element, even though there should be the slot name in-between.
- Constraint elements should be used as associations, not compositions. 
- The same "xmi.id" value is used multiple times for different elements. (!)
- Diagrams are serialized in some weird way, probably just their own invention.

In general XMI compliance between tools is nonexisting.
Comment 42 Oliver Kellogg 2006-01-01 01:41:05 UTC
SVN commit 492999 by okellogg:

Add Java code import (still work in progress.)
CCBUG:56184


 M  +1 -0      Makefile.am  
 AM            javaimport.cpp   [License: GPL (v2+)]
 AM            javaimport.h   [License: GPL (v2+)]
 M  +5 -0      uml.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/Makefile.am #492998:492999
@@ -52,6 +52,7 @@
 idlimport.cpp \
 import_utils.cpp \
 infowidget.cpp \
+javaimport.cpp \
 kstartuplogo.cpp \
 linepath.cpp \
 linkwidget.cpp \
** branches/KDE/3.5/kdesdk/umbrello/umbrello/javaimport.cpp #property svn:executable
   + *
** branches/KDE/3.5/kdesdk/umbrello/umbrello/javaimport.h #property svn:executable
   + *
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/uml.cpp #492998:492999
@@ -51,6 +51,7 @@
 #include "cppimport.h"
 #include "idlimport.h"
 #include "adaimport.h"
+#include "javaimport.h"
 #include "docwindow.h"
 #include "codegenerator.h"
 #include "generatorinfo.h"
@@ -1420,6 +1421,8 @@
     QString preselectedExtension;
     if (m_activeLanguage == "IDL") {
         preselectedExtension = i18n("*.idl|IDL Files (*.idl)");
+    } else if (m_activeLanguage == "Java") {
+        preselectedExtension = i18n("*.java|Java Files (*.java)");
     } else if (m_activeLanguage == "Ada") {
         preselectedExtension = i18n("*.ads *.ada|Ada Files (*.ads *.ada)");
     } else {
@@ -1432,6 +1435,8 @@
     const QString& firstFile = fileList.first();
     if (firstFile.endsWith(".idl"))
         classImporter = new IDLImport();
+    else if (firstFile.endsWith(".java"))
+        classImporter = new JavaImport();
     else if (firstFile.contains( QRegExp("\\.ad[sba]$") ))
         classImporter = new AdaImport();
     else
Comment 43 Oliver Kellogg 2006-01-03 17:44:42 UTC
Created attachment 14121 [details]
poseidon321.xmi - XMI file exported from Poseidon 3.2.1

(Sorry for the previous bogus post, I got the bug# wrong)
This file contains a directed aggregation from Klasse_2 to Klasse_1
(hollow diamond at Klasse2, stick arrowhead at Klasse_1).
The display of that is not yet implemented in Umbrello so the
stick arrowhead is missing.
Also there is a <UML:Abstraction> from Klasse_2 (client) to
Schnittstelle_1 (supplier) which Umbrello will deal with shortly.
Comment 44 Oliver Kellogg 2006-01-03 17:57:30 UTC
> ------- Additional Comment #41 From Marcus Alanen 2005-12-29 18:10
> [...]
> In general XMI compliance between tools is nonexisting. 

Hmm... The aim is to make Umbrello load the XMI from as many other tools
as ever possible. ATM I'm still concentrating on the static structure
elements of class diagrams. Please do give details if you find something
missing.
Comment 45 Oliver Kellogg 2006-01-03 18:44:33 UTC
SVN commit 493938 by okellogg:

Support loading of <UML:Abstraction> as demonstrated in
http://bugs.kde.org/attachment.cgi?id=14121&action=view
CCBUG:56184


 M  +7 -12     association.cpp  
 M  +5 -0      umldoc.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/association.cpp #493937:493938
@@ -192,7 +192,8 @@
     UMLDoc * doc = UMLApp::app()->getDocument();
     UMLObject * obj[2] = { NULL, NULL };
     if (m_AssocType == Uml::at_Generalization ||
-            m_AssocType == Uml::at_Dependency) {
+        m_AssocType == Uml::at_Realization ||
+        m_AssocType == Uml::at_Dependency) {
         for (unsigned r = Uml::A; r <= Uml::B; r++) {
             const QString fetch = (m_AssocType == Uml::at_Generalization ?
                                    r == Uml::A ? "child" : "parent"
@@ -221,15 +222,9 @@
                 QString tag = tempElement.tagName();
                 if (Model_Utils::isCommonXMIAttribute(tag))
                     continue;
-                bool isGeneralization = (m_AssocType == Uml::at_Generalization &&
-                                         (tagEq(tag, "child") || tagEq(tag, "parent") ||
-                                          tagEq(tag, "subtype") || tagEq(tag, "supertype")));
-                bool isDependency = (m_AssocType == Uml::at_Dependency &&
-                                     (tagEq(tag, "client") || tagEq(tag, "supplier")));
-                if (!isGeneralization && !isDependency) {
-                    kdDebug() << "UMLAssociation::load: cannot load " << tag << endl;
-                    continue;
-                }
+                // Permitted tag names:
+                //  roleA: "child" "subtype" "client"
+                //  roleB: "parent" "supertype" "supplier"
                 QString idStr = tempElement.attribute( "xmi.id", "" );
                 if (idStr.isEmpty())
                     idStr = tempElement.attribute( "xmi.idref", "" );
@@ -242,8 +237,8 @@
                 }
                 if (idStr.isEmpty()) {
                     kdError() << "UMLAssociation::load (type " << m_AssocType
-                    << ", id " << ID2STR(getID()) << "): "
-                    << "xmi id not given for " << tag << endl;
+                        << ", id " << ID2STR(getID()) << "): "
+                        << "xmi id not given for " << tag << endl;
                     continue;
                 }
                 // Since we know for sure that we're dealing with a non
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umldoc.cpp #493937:493938
@@ -2146,6 +2146,8 @@
         if (tagEq(type, "Association") ||
                 tagEq(type, "AssociationClass") ||
                 tagEq(type, "Generalization") ||
+                tagEq(type, "Realization") ||
+                tagEq(type, "Abstraction") ||
                 tagEq(type, "Dependency")) {
             if ( !status ) {
                 // Some interim umbrello versions saved empty UML:Associations,
@@ -2279,6 +2281,9 @@
         pObject = new UMLAssociation();
     } else if (tagEq(type, "Generalization")) {
         pObject = new UMLAssociation(Uml::at_Generalization);
+    } else if (tagEq(type, "Realization") ||
+               tagEq(type, "Abstraction")) {
+        pObject = new UMLAssociation(Uml::at_Realization);
     } else if (tagEq(type, "Dependency")) {
         pObject = new UMLAssociation(Uml::at_Dependency);
     }
Comment 46 Oliver Kellogg 2006-01-10 20:26:53 UTC
SVN commit 496548 by okellogg:

UMLRole::saveToXMI(): Change aggregation="shared" to "aggregate".
UMLAssociation::saveToXMI(): Save abstraction as <UML:Abstraction>.
Thanks to Tom Morris for clarifying.
CCBUG:56184
CCMAIL:tfmorris@gmail.com


 M  +8 -2      association.cpp  
 M  +1 -1      umlrole.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/association.cpp #496547:496548
@@ -161,8 +161,7 @@
 }
 
 void UMLAssociation::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) {
-    if (m_AssocType == Uml::at_Generalization ||
-            m_AssocType == Uml::at_Realization) {
+    if (m_AssocType == Uml::at_Generalization) {
         QDomElement assocElement = UMLObject::save("UML:Generalization", qDoc);
         assocElement.setAttribute( "discriminator", "" );
         assocElement.setAttribute( "child", ID2STR(getObjectId(A)) );
@@ -170,6 +169,13 @@
         qElement.appendChild( assocElement );
         return;
     }
+    if (m_AssocType == Uml::at_Realization) {
+        QDomElement assocElement = UMLObject::save("UML:Abstraction", qDoc);
+        assocElement.setAttribute( "client", ID2STR(getObjectId(A)) );
+        assocElement.setAttribute( "supplier", ID2STR(getObjectId(B)) );
+        qElement.appendChild( assocElement );
+        return;
+    }
     if (m_AssocType == Uml::at_Dependency) {
         QDomElement assocElement = UMLObject::save("UML:Dependency", qDoc);
         assocElement.setAttribute( "client", ID2STR(getObjectId(A)) );
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlrole.cpp #496547:496548
@@ -118,7 +118,7 @@
             roleElement.setAttribute("aggregation", "composite");
             break;
         case Uml::at_Aggregation:
-            roleElement.setAttribute("aggregation", "shared");
+            roleElement.setAttribute("aggregation", "aggregate");
             break;
         default:
             roleElement.setAttribute("aggregation", "none");
Comment 47 Oliver Kellogg 2006-01-10 20:37:38 UTC
From Tom Morris <tfmorris@gmail.com>
Subject: RE: Loading Umbrello file into Argo

[...]
> > - aggregation="shared" (no such value in UML 1.4.  Legal values are
> > none,
> > aggregate, composite)
>
> Ah. In XMI 1.2, it's "shared", see OMG document
> formal/02-01-01, pg. A-41 of
> the PDF:
> <!ELEMENT UML:AssociationEnd.aggregation EMPTY >
>
> <!ATTLIST UML:AssociationEnd.aggregation
>
>  xmi.value (none | shared | composite) #REQUIRED >

If you look at the introducation to that appendix, the DTD is described as
being generated from UML 1.1 specification using the XMI 1.2 generation
rules.  The DTD in the UML 1.3 specification on the other hand appears to
have been generated using the UML 1.3 spec, but the XMI 1.0 production
rules.  It appears there isn't a good ready-to-use DTD in either of these
specs.  If look page 2-78 of the UML 1.3 specification, you'll see values
allowed for the AggregationKind element.
Comment 48 Edward Nash 2006-02-02 13:56:58 UTC
The stereotypes of classes are 'lost' when importing an XMI file from argoUML (tested against argoUML 0.18 and 0.20)

I assume this links back to the file-format issue?
Comment 49 Oliver Kellogg 2006-02-19 13:17:05 UTC
SVN commit 511268 by okellogg:

Load and resolve stereotypes as generated by Sun's Metadata Repository
(http://mdr.netbeans.org) and as used by ArgoUML 0.20.
Thanks to Edward Nash for noticing the problem.
CCBUG:56184


 M  +4 -1      umldoc.cpp  
 M  +31 -3     umlobject.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umldoc.cpp #511267:511268
@@ -826,7 +826,10 @@
 }
 
 UMLObject* UMLDoc::findObjectById(Uml::IDType id) {
-    return Model_Utils::findObjectInList(id, m_objectList);
+    UMLObject *o = Model_Utils::findObjectInList(id, m_objectList);
+    if (o == NULL)
+        o = findStereotypeById(id);
+    return o;
 }
 
 UMLStereotype * UMLDoc::findStereotypeById(Uml::IDType id) {
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlobject.cpp #511267:511268
@@ -416,6 +416,11 @@
     if (! m_SecondaryId.isEmpty()) {
         m_pSecondary = pDoc->findObjectById(STR2ID(m_SecondaryId));
         if (m_pSecondary != NULL) {
+            if (m_pSecondary->getBaseType() == Uml::ot_Stereotype) {
+                m_pStereotype = static_cast<UMLStereotype*>(m_pSecondary);
+                m_pStereotype->incrRefCount();
+                m_pSecondary = NULL;
+            }
             m_SecondaryId = "";
             maybeSignalObjectCreated();
             return true;
@@ -665,9 +670,9 @@
     }
     /**** End of XMI_FLAT_PACKAGES and old files handling ****************/
 
-    // If the name is not set, let's check whether the attributes are saved
-    // as child nodes.
-    if (m_Name.isEmpty()) {
+    // If the node has child nodes, check whether attributes can be
+    // extracted from them.
+    if (element.hasChildNodes()) {
         QDomNode node = element.firstChild();
         if (node.isComment())
             node = node.nextSibling();
@@ -698,6 +703,29 @@
                 if (ownerScope.isEmpty())
                     ownerScope = elem.text();
                 m_bStatic = (ownerScope == "classifier");
+            } else if (Uml::tagEq(tag, "stereotype")) {
+                QString stereo = elem.attribute("xmi.value", "");
+                if (stereo.isEmpty() && elem.hasChildNodes()) {
+                    /* like so:
+                     <UML:ModelElement.stereotype>
+                       <UML:Stereotype xmi.idref = '07CD'/>
+                     </UML:ModelElement.stereotype>
+                     */
+                    QDomNode stereoNode = elem.firstChild();
+                    QDomElement stereoElem = stereoNode.toElement();
+                    tag = stereoElem.tagName();
+                    if (Uml::tagEq(tag, "Stereotype")) {
+                        stereo = stereoElem.attribute("xmi.idref", "");
+                    }
+                }
+                if (! stereo.isEmpty()) {
+                    Uml::IDType stereoID = STR2ID(stereo);
+                    m_pStereotype = umldoc->findStereotypeById(stereoID);
+                    if (m_pStereotype)
+                        m_pStereotype->incrRefCount();
+                    else
+                        m_SecondaryId = stereo;  // leave it to resolveRef()
+                }
             }
             node = node.nextSibling();
             if (node.isComment())
Comment 50 Philip Van Hoof 2006-04-12 12:02:35 UTC
Will documents created with v. 1.5.2 ever be usable with a standard XMI-supporting software like ArgoUML, Rational Rose or Poseidon?

I think it's a good idea to NOT name the generated files "XMI" files. If they don't validate, they aren't XMI. Nor does umbrello in that case support XMI. If you claim to support XMI, the resulting files should BE XMI files.

This confuses users A LOT.

Is there a way I can reconstruct the Umbrello file to a more or less usable XMI file? For example an XSLT or a list of incompatibilities that I'll have to remove?
Comment 51 Philip Van Hoof 2006-04-12 12:12:18 UTC
I propose renaming the "XMI file" item in the save dialog to "Umbrello XMI-like file" or "UMB file" or something like that. That way you wont confuse users. At this moment probably a lot people are editing their UML models using Umbrello with the false hope/idea that the resulting file is a XMI file. It isn't. Confusing.
Comment 52 Oliver Kellogg 2006-04-12 22:14:46 UTC
> Comment #50 From Philip Van Hoof
> Will documents created with v. 1.5.2 ever be usable
> with a standard XMI-supporting software like ArgoUML,
> Rational Rose or Poseidon?

As you may have noticed from the length of this PR, it's not so
simple. There exist many dialects of XMI and it's difficult enough
to grok most of them on importing, let alone concoct something
that will be understood by most other tools on the market.

We're always talking about specific problems between two specific
versions of two specific tools.

You can help in this effort by making detailed reports of the
problems you encounter. Please state the exact tools and versions
used; attach the XMI files(s) in question, and try to narrow down
the problem as far as possible, and be as specific as possible.

Thanks.
Comment 53 Marcus Alanen 2006-04-12 22:35:58 UTC
> ArgoUML, Rational Rose or Poseidon

I could add that none of these tools produce standards-compliant XMI as far as I know. However, there certainly is a point in realizing that Umbrello or other open-source tools should be as compatible as reasonably possible with tools with a large userbase.

Old Poseidon releases (and Argo?) is UML 1.4 by the way, Umbrello is 1.3 I think. So technically they even cannot be compatible. Newer Poseidon releases use a mixture of UML 1.4 and UML 2.0; I do not think it is worth spending time for compatibility purposes until they have migrated completely to UML 2.0.

I'm not sure which UML version Rational Rose uses.

My biggest gripe with the open-source UML tools in general is the lack of compatible diagram formats.
Comment 54 Oliver Kellogg 2006-12-23 16:11:18 UTC
SVN commit 616054 by okellogg:

Further fixes for loading Poseidon 4.1 xmi, e.g.
 http://uml2svg.sourceforge.net/samples/CoffeeMachine.xmi
CCBUG:56184


 M  +6 -3      classifier.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/classifier.cpp #616053:616054
@@ -877,8 +877,10 @@
                 tagEq(tag, "Classifier.feature") ||
                 tagEq(tag, "Namespace.ownedElement") ||
                 tagEq(tag, "Namespace.contents")) {
-            if (! load(element))
-                return false;
+            load(element);
+            // Not evaluating the return value from load()
+            // because we want a best effort.
+
         } else if ((child = makeChildObject(tag)) != NULL) {
             if (child->loadFromXMI(element)) {
                 switch (child->getBaseType()) {
@@ -908,7 +910,8 @@
             UMLDoc *umldoc = UMLApp::app()->getDocument();
             UMLObject *pObject = Object_Factory::makeObjectFromXMI(tag);
             if (pObject == NULL) {
-                totalSuccess = false;
+                // Not setting totalSuccess to false
+                // because we want a best effort.
                 continue;
             }
             pObject->setUMLPackage(this);
Comment 55 Oliver Kellogg 2007-07-25 00:04:19 UTC
Created attachment 21243 [details]
http://fisheye.codehaus.org/browse/~raw,r=2486/mapbuilder/tags/mapbuilder-lib-1_5-rc1/mapbuilder/design/uml/mapbuilder.xmi

This file demonstrates the XMI 1.2 produced by Netbeans XMI Writer 1.0,
metamodel version 1.4.3.
Comment 56 Oliver Kellogg 2007-07-25 00:10:41 UTC
SVN commit 692032 by okellogg:

UMLObject::loadStereotype(): New, factored from loadFromXMI().
Further adjustments for loading attachment 21243 [details] (Netbeans XMI)
CCBUG:56184


 M  +1 -0      model_utils.cpp  
 M  +3 -5      umldoc.cpp  
 M  +32 -23    umlobject.cpp  
 M  +8 -0      umlobject.h  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/model_utils.cpp #692031:692032
@@ -287,6 +287,7 @@
                    Uml::tagEq(tag, "isActive") ||
                    Uml::tagEq(tag, "namespace") ||
                    Uml::tagEq(tag, "ownerScope") ||
+                   Uml::tagEq(tag, "ModelElement.stereotype") ||
                    Uml::tagEq(tag, "GeneralizableElement.generalization") ||
                    Uml::tagEq(tag, "specialization") ||   //NYI
                    Uml::tagEq(tag, "clientDependency") || //NYI
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umldoc.cpp #692031:692032
@@ -1660,16 +1660,14 @@
         // From here on, it's support for stereotypes, pre 1.5.5 versions, and foreign files
         if (tagEq(type, "Namespace.ownedElement") ||
                 tagEq(type, "Namespace.contents") ||
-                tagEq(type, "Model") || tagEq(type, "ModelElement.stereotype")) {
+                tagEq(type, "Model")) {
             //CHECK: Umbrello currently assumes that nested elements
             // are ownedElements anyway.
             // Therefore the <UML:Namespace.ownedElement> tag is of no
             // significance.
             if( !loadUMLObjectsFromXMI( tempElement ) ) {
-                if (! tagEq(type, "ModelElement.stereotype")) {  // not yet implemented
-                    kWarning() << "failed load on " << type << endl;
-                    return false;
-                }
+                kWarning() << "failed load on " << type << endl;
+                return false;
             }
             continue;
         }
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlobject.cpp #692031:692032
@@ -543,6 +543,36 @@
     return true;
 }
 
+bool UMLObject::loadStereotype(QDomElement & element) {
+    QString tag = element.tagName();
+    if (!Uml::tagEq(tag, "stereotype"))
+        return false;
+    QString stereo = element.attribute("xmi.value", "");
+    if (stereo.isEmpty() && element.hasChildNodes()) {
+        /* like so:
+         <UML:ModelElement.stereotype>
+           <UML:Stereotype xmi.idref = '07CD'/>
+         </UML:ModelElement.stereotype>
+         */
+        QDomNode stereoNode = element.firstChild();
+        QDomElement stereoElem = stereoNode.toElement();
+        tag = stereoElem.tagName();
+        if (Uml::tagEq(tag, "Stereotype")) {
+            stereo = stereoElem.attribute("xmi.idref", "");
+        }
+    }
+    if (stereo.isEmpty())
+        return false;
+    Uml::IDType stereoID = STR2ID(stereo);
+    UMLDoc *pDoc = UMLApp::app()->getDocument();
+    m_pStereotype = pDoc->findStereotypeById(stereoID);
+    if (m_pStereotype)
+        m_pStereotype->incrRefCount();
+    else
+        m_SecondaryId = stereo;  // leave it to resolveRef()
+    return true;
+}
+
 bool UMLObject::loadFromXMI( QDomElement & element) {
     UMLDoc* umldoc = UMLApp::app()->getDocument();
     if (umldoc == NULL) {
@@ -674,29 +704,8 @@
                 if (ownerScope.isEmpty())
                     ownerScope = elem.text();
                 m_bStatic = (ownerScope == "classifier");
-            } else if (Uml::tagEq(tag, "stereotype")) {
-                QString stereo = elem.attribute("xmi.value", "");
-                if (stereo.isEmpty() && elem.hasChildNodes()) {
-                    /* like so:
-                     <UML:ModelElement.stereotype>
-                       <UML:Stereotype xmi.idref = '07CD'/>
-                     </UML:ModelElement.stereotype>
-                     */
-                    QDomNode stereoNode = elem.firstChild();
-                    QDomElement stereoElem = stereoNode.toElement();
-                    tag = stereoElem.tagName();
-                    if (Uml::tagEq(tag, "Stereotype")) {
-                        stereo = stereoElem.attribute("xmi.idref", "");
-                    }
-                }
-                if (! stereo.isEmpty()) {
-                    Uml::IDType stereoID = STR2ID(stereo);
-                    m_pStereotype = umldoc->findStereotypeById(stereoID);
-                    if (m_pStereotype)
-                        m_pStereotype->incrRefCount();
-                    else
-                        m_SecondaryId = stereo;  // leave it to resolveRef()
-                }
+            } else {
+                loadStereotype(elem);
             }
             node = node.nextSibling();
             if (node.isComment())
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlobject.h #692031:692032
@@ -303,6 +303,14 @@
     virtual bool loadFromXMI( QDomElement & element );
 
     /**
+     * Analyzes the given QDomElement for a reference to a stereotype.
+     *
+     * @param element    QDomElement to analyze.
+     * @return        True if a stereotype reference was found, else false.
+     */
+    bool loadStereotype(QDomElement & element);
+
+    /**
      * Returns true if this UMLObject has classifier scope,
      * otherwise false (the default).
      */
Comment 57 Oliver Kellogg 2012-02-01 08:50:12 UTC
@Ralf: Speaking of XMI test suite, I found this:

http://www.omgwiki.org/model-interchange/

There are several UML 2.3 based XMI files available there.
Comment 58 Ralf Habacker 2012-06-13 18:42:06 UTC
(In reply to comment #57)
> @Ralf: Speaking of XMI test suite, I found this:
> 
> http://www.omgwiki.org/model-interchange/
> 
@Oliver: Took a look .. there are several UML 2.3 based XMI files available there. I tried a few one, umbrello is not able to load them :-(
Comment 59 Ralf Habacker 2013-08-19 01:35:04 UTC
I imported an uml 1.3 dtd into umbrello source and added umbrello only diagrams dtd  see https://projects.kde.org/projects/kde/kdesdk/umbrello/repository/revisions/master/show/doc/xml and tried to validate the appended xmi files against that uml-1.3-umbrello dtd, which failed for all files. 

A load of the appended file with recent git master shows, that the following files are loadable:
- AExample-DesignModel-xmi12.xmi - XMI file created by Enterprise Architect 
- http://uml2svg.sourceforge.net/samples/CoffeeMachine.xmi
- poseidon321.xmi - XMI file exported from Poseidon 3.2.1  
-http://fisheye.codehaus.org/browse/~raw,r=2486/mapbuilder/tags/mapbuilder-lib-1_5-rc1/mapbuilder/design/uml/mapbuilder.xmi 

The following files are not loadable: 
 demonstrates XMI format from Unisys
 DiagramDynamic.xmi - state diagram created by TogetherSoft 

This shows that umbrello supports a higher uml version

In fact it supports mostly of uml 1.4 (although it pronounces 1.3 compatibility). For differences to the official uml version 1.4 see https://projects.kde.org/projects/kde/kdesdk/umbrello/repository/revisions/8473f5f9b3ea290dd4d535fe6cfc06db22685f76. 

Validating the appended xmi files with uml-1.4-umbrello.dtd, which is part of the umbrello source https://projects.kde.org/projects/kde/kdesdk/umbrello/repository/revisions/master/entry/doc/xml/uml-1.4-umbrello.dtd shown much less errors. 

Conclusion: uml 1.3 is not supported by umbrello since a couple of years.
Comment 60 Oliver Kellogg 2014-04-20 00:08:14 UTC
Created attachment 86180 [details]
eclipse_uml_demo.xmi

(In reply to comment #58)
> > http://www.omgwiki.org/model-interchange/
> > 
> @Oliver: Took a look .. there are several UML 2.3 based XMI files available
> there. I tried a few one, umbrello is not able to load them :-(

Understood.
As a preparation for adding support for XMI2, in commit 732b50a 
(http://commits.kde.org/umbrello/732b50aa7df42610e50ee95da70b598cf6ebff42)
I have added a few messages giving the exact reason of load failure.

Trying to load
 http://www.omgwiki.org/model-interchange/lib/exe/fetch.php?id=test_case_1_uml_2.3&cache=cache&media=release-12:test_case_1_valid.xmi
gives the message:
UMLDoc::encoding: Unknown tag at  "uml:Model"

Trying to load the current attachment gives:
UMLDoc::encoding: Expecting XMI.header at  "uml:Model"

BTW, shall we continue to use this PR to aggregate demo XMI files?
Comment 61 Oliver Kellogg 2014-04-20 17:30:54 UTC
Git commit a9d4efc360903eb884b1624de18a0f188c0cfdcf by Oliver Kellogg.
Committed on 20/04/2014 at 17:32.
Pushed by okellogg into branch 'master'.

umbrello/umldoc.h
- Add ENC_WINDOWS for use by encoding(QIODevice&)

umbrello/umldoc.cpp
- short UMLDoc::encoding(QIODevice & file) :
  - Introduce variable 'enc' with initial value ENC_UNKNOWN
  - In loop advancing over comments and processing instructions, if
    node.isProcessingInstruction() then analyze the
    node.toProcessingInstruction().data(); if attribute "encoding" is
    found then extract its value. Assign ENC_UNICODE to enc if value is
    "UTF-8"; assign ENC_WINDOWS to enc if value is "windows-1252"; else
    assign ENC_OLD_ENC to enc (indicating a not yet implemented encoding.)
  - Change uWarning() messages added in commit 732b50a to uDebug()
  - For premature returns, return variable 'enc' instead of ENC_UNKNOWN.
    Reason: Returning ENC_UNKNOWN here is overly strict, it precludes any
    further attempts at loading foreign XMI files. Rather, use the encoding
    attribute from the processing instruction if found.
- bool UMLDoc::loadFromXMI(QIODevice & file, short encode) :
  Extend check which makes sure it is an XMI file to permit "xmi:XMI" as
  root.tagName()

M  +31   -12   umbrello/umldoc.cpp
M  +2    -1    umbrello/umldoc.h

http://commits.kde.org/umbrello/a9d4efc360903eb884b1624de18a0f188c0cfdcf
Comment 62 Oliver Kellogg 2014-04-20 17:39:26 UTC
(In reply to comment #60)
> [...]
> BTW, shall we continue to use this PR to aggregate demo XMI files?

Since we already have many useful XMI files here, I take the liberty of doing so, and I am changing the bug title accordingly.
Comment 63 Oliver Kellogg 2014-04-20 21:34:47 UTC
Git commit c0d58b3b691dba2fd3442a34be922d6cad758eb1 by Oliver Kellogg.
Committed on 20/04/2014 at 21:35.
Pushed by okellogg into branch 'master'.

Initial work on loading UML2/XMI2 files, e.g.
  https://bugs.kde.org/attachment.cgi?id=86180 (Eclipse UML2)
and
  http://www.omg.org/spec/UML/20110701/Infrastructure.xmi

umbrello/model_utils.{h,cpp}
- New function getXmiId(QDomElement) encapsulates access to xmi.id (XMI-1)
  and xmi:id (XMI-2)

umbrello/{umlobject,folder,operation}.cpp
- Replace direct accesses to QDomElement::attribute("xmi.id") by
  Model_Utils::getXmiId()

umbrello/{folder,package}.cpp
- In function load(QDomElement&), decode UML2 tags packagedElement and
  ownedElement.

umbrello/umldoc.cpp
- In function loadFromXMI(QIODevice&, short), decode outerTag values
  "Model" and "Package" for UML2;
- In function loadUMLObjectsFromXMI(QDomElement&),
  - decode UML2 tags packagedElement and ownedElement;
  - admit XMI2 syntax "xmi:id" to the check for xmi.id presence.

umbrello/classifier.cpp
- In function makeChildObject(const QString&), support UML2 tags
  ownedOperation and ownedAttribute.

M  +4    -2    umbrello/classifier.cpp
M  +4    -1    umbrello/folder.cpp
M  +13   -2    umbrello/model_utils.cpp
M  +2    -1    umbrello/model_utils.h
M  +4    -3    umbrello/operation.cpp
M  +3    -0    umbrello/package.cpp
M  +15   -1    umbrello/umldoc.cpp
M  +1    -1    umbrello/umlobject.cpp

http://commits.kde.org/umbrello/c0d58b3b691dba2fd3442a34be922d6cad758eb1
Comment 64 Ralf Habacker 2014-04-20 22:50:04 UTC
(In reply to comment #63)
> Git commit c0d58b3b691dba2fd3442a34be922d6cad758eb1 by Oliver Kellogg.
> Committed on 20/04/2014 at 21:35.
> Pushed by okellogg into branch 'master'.
> 
> Initial work on loading UML2/XMI2 files, e.g.
Because http://en.wikipedia.org/wiki/XML_Metadata_Interchange states:
"... The 2.x versions are radically different from the 1.x series. ..." 

From inspecting both file formats I think it would be the easiest way to add a "14" postfix to recent xmi load/save methds (loadFromXMI(), saveToXMI(), load() and save()) [1], to add ...2() methods and while implementing xmi 2.x support to see which of the ...14() functions could be reused. Having different methods will result into smaller implementations and reduces the required testing effort, because testing could be limited to either 1.4 or 2.x. 
 
[1] I already have a local umbrello branch with the '14" method postfix and can merge this into master or push to a dedicated work branch (work/xmi2).
Comment 65 Oliver Kellogg 2014-04-21 18:18:19 UTC
Git commit 3ded4560aee065feeec55fda99e6db50d6f57a73 by Oliver Kellogg.
Committed on 21/04/2014 at 18:19.
Pushed by okellogg into branch 'master'.

Followup to commit c0d58b3 for loading UML2/XMI2 files

umbrello/object_factory.cpp function makeObjectFromXMI() :
- Map UML2 PrimitiveType to UMLClassifier with base type ot_Datatype.

umbrello/attribute.cpp function load() :
- Replace direct accesses to QDomElement::attribute("xmi.id") by
  Model_Utils::getXmiId()
- If no xmi.id attribute is found in tempElement then check for attribute
  "href". If href is found then look for a hashmark (#) in its value. If
  found then extract the substring following the hashmark and seek this
  name in the Datatypes folder. If found then set m_pSecondary to the
  datatype object found; else create a new datatype with this name, and
  set m_pSecondary to the new datatype object.

M  +25   -7    umbrello/attribute.cpp
M  +4    -2    umbrello/object_factory.cpp

http://commits.kde.org/umbrello/3ded4560aee065feeec55fda99e6db50d6f57a73
Comment 66 Oliver Kellogg 2014-04-21 18:32:05 UTC
(In reply to comment #64)
> Because http://en.wikipedia.org/wiki/XML_Metadata_Interchange states:
> "... The 2.x versions are radically different from the 1.x series. ..." 
> 
> From inspecting both file formats I think it would be the easiest way to add
> a "14" postfix to recent xmi load/save methods (loadFromXMI(), saveToXMI(),
> load() and save()) [1], to add ...2() methods and while implementing xmi 2.x
> support to see which of the ...14() functions could be reused. Having
> different methods will result into smaller implementations and reduces the
> required testing effort, because testing could be limited to either 1.4 or
> 2.x. 

Sounds reasonable.
So far, while implementing UML2/XMI2 support I am finding very large overlap with the existing code, i.e. I am reusing about 95% and only writing about 5% new code.

> [1] I already have a local umbrello branch with the '14" method postfix and
> can merge this into master or push to a dedicated work branch (work/xmi2).

Fine.
I went straight to master - as I felt that the required changes are sufficiently light-weight.
Comment 67 Oliver Kellogg 2014-04-22 21:38:41 UTC
Git commit 628a6cf77246c582c8251060781146fe9470f014 by Oliver Kellogg.
Committed on 22/04/2014 at 21:40.
Pushed by okellogg into branch 'master'.

Followup to commit 3ded456 for loading UML2/XMI2 files implements findings
from loading https://bugs.kde.org/attachment.cgi?id=85894 (bug 332612)

umbrello/enum.cpp function load() :
- Add decoding of UML2 tag "ownedLiteral".

umbrello/object_factory.cpp function makeObjectFromXMI() :
- Add decoding of UML2 tag "generalization".

umbrello/association.cpp function load() :
- Add decoding of UML2 generalization attribute "general".

M  +16   -2    umbrello/association.cpp
M  +1    -0    umbrello/enum.cpp
M  +2    -1    umbrello/object_factory.cpp

http://commits.kde.org/umbrello/628a6cf77246c582c8251060781146fe9470f014
Comment 68 Oliver Kellogg 2014-05-24 06:59:18 UTC
Created attachment 86794 [details]
https://github.com/csware/argouml/blob/master/www/tours/enroll.zargo

(In reply to comment #0)
> [...] to increase interoperability with other tools like ArgoUML,

For completeness, here is an ArgoUML demo file.
After unzipping the attachment, the file enroll.xmi can be loaded into Umbrello.
(ArgoUML keeps diagrams in separate files with ending ".pgml"; these cannot be loaded by Umbrello.)
Comment 69 Ralf Habacker 2014-05-24 19:34:30 UTC
Git commit 19e25728d83bc4e962c9f2b2b3ac7db17834a02a by Ralf Habacker.
Committed on 24/05/2014 at 10:25.
Pushed by habacker into branch 'master'.

Add zargo file import support (reading of embedded xmi file).

M  +1    -0    umbrello/CMakeLists.txt
A  +146  -0    umbrello/import_argo.cpp     [License: GPL (v2+)]
A  +37   -0    umbrello/import_argo.h     [License: GPL (v2+)]
M  +4    -2    umbrello/uml.cpp
M  +9    -0    umbrello/umldoc.cpp

http://commits.kde.org/umbrello/19e25728d83bc4e962c9f2b2b3ac7db17834a02a
Comment 70 Ralf Habacker 2014-05-24 21:34:41 UTC
Created attachment 86802 [details]
http://argouml.tigris.org/tours/enroll_usecase.zargo

argo uml demo file with use cases
Comment 71 Ralf Habacker 2014-05-24 21:37:49 UTC
(In reply to comment #68)
> After unzipping the attachment, the file enroll.xmi can be loaded into
> Umbrello.
> (ArgoUML keeps diagrams in separate files with ending ".pgml"; these cannot
> be loaded by Umbrello.)
umbrello master now has support to import a .zargo file with file->open (limited to the embedded xmi file)
Comment 72 Ralf Habacker 2014-05-26 10:20:43 UTC
Git commit 24afb594592c058fbd1012ae8b1dc44c68bcf5ea by Ralf Habacker.
Committed on 26/05/2014 at 10:18.
Pushed by habacker into branch 'master'.

Inform user about failed zargo file import.

M  +7    -4    umbrello/umldoc.cpp

http://commits.kde.org/umbrello/24afb594592c058fbd1012ae8b1dc44c68bcf5ea
Comment 73 Oliver Kellogg 2014-07-23 21:27:29 UTC
Created attachment 87920 [details]
Demo file for the format generated by Embarcadero's "Describe" UML tool

http://usuarios.upf.br/~78287/Pos/Java/fonte%20professor/pessoas/PessoasUML/PessoasUML.etd
renamed to extension ".xmi", and linebreaks inserted to make it human readable.
Umbrello does not complain on loading - but nothing is actually imported.
Comment 74 Oliver Kellogg 2014-07-25 04:15:29 UTC
Git commit 811994e78a0bf02ff0e717de67cd32da66d0b9af by Oliver Kellogg.
Committed on 25/07/2014 at 04:12.
Pushed by okellogg into branch 'master'.

(In reply to Oliver Kellogg from comment #73)
> Created attachment 87920 [details]
> Demo file for the format generated by Embarcadero's "Describe" UML tool
> [...]
> Umbrello does not complain on loading - but nothing is actually imported.

The following changes add support for loading the demo file:

umbrello/{association,classifier,enum,operation,package}.cpp function load()
- Support special tags used by Embarcadero Describe.

umbrello/object_factory.cpp function makeObjectFromXMI()
- Support association special tag <UML:Aggregation> used by Embarcadero.

umbrello/umldoc.cpp
- In function loadFromXMI(), support <UML:Model> equivalent tag <UML:Project>
  used by Embarcadero Describe.
- In function loadUMLObjectsFromXMI(), support <UML:Namespace.ownedElement>
  equivalent tag <UML:Element.ownedElement> used by Embarcadero Describe.

umbrello/umlobject.cpp fuction loadFromXMI()
- Generate new UniqueID for all cases of non existent xmi id.
- Downgrade non existence of xmi.id from error to warning.

M  +9    -4    umbrello/association.cpp
M  +1    -0    umbrello/classifier.cpp
M  +4    -1    umbrello/enum.cpp
M  +2    -0    umbrello/object_factory.cpp
M  +17   -12   umbrello/operation.cpp
M  +1    -0    umbrello/package.cpp
M  +2    -0    umbrello/umldoc.cpp
M  +4    -8    umbrello/umlobject.cpp

http://commits.kde.org/umbrello/811994e78a0bf02ff0e717de67cd32da66d0b9af
Comment 75 Oliver Kellogg 2015-11-22 21:01:24 UTC
Created attachment 95658 [details]
XMI 2.1 demo file generated using Enterprise Architect 12

Yet another demo file from EA, this time generated using Export to XMI 2.1.
After the export I applied following cleanups:
1. Removed "&amp;#13;" on each line ending (I was using EA under Wine/Linux, perhaps this has to do with the problem).
2. Added a first line
    <?xml version="1.0" encoding="UTF-8"?>
   for basic XML validity.
3. Edited line 19:
<upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:type="uml:LiteralInteger" xmi:id="EAID_LI000002_23CB_47d4_AD84_16941CB7BFD9" value="1"/>
  (removed 2nd xmi:type because xmllint reported invalid XML).

Some observations:
1. On loading this file, Umbrello complains:
UMLDoc::encoding: Expecting XMI.header at  "xmi:Documentation".
2. At Class2 the member c1data has Java type "long", this is not recognized by Umbrello (see XMI: <type xmi:idref="EAJava_long"/>).
3. At c1data there is a stereotype <<key>> applied; this does not appear in Umbrello.
Comment 76 Ralf Habacker 2019-12-28 21:15:43 UTC
Comment on attachment 5760 [details]
uml14.xmi (demonstrates XMI format from nsuml)

This file could be imported without any problems -> added nsuml to https://umbrello.kde.org/features.php
Comment 77 Ralf Habacker 2019-12-28 21:16:48 UTC
Git commit 2d497401fabf8ccb03111be4e754c4117545b10b by Ralf Habacker.
Committed on 28/12/2019 at 21:16.
Pushed by habacker into branch 'master'.

features.php: Add NSUML to list of supported 3rdparty file formats

M  +1    -0    features.php

https://invent.kde.org/websites/umbrello-kde-org/commit/2d497401fabf8ccb03111be4e754c4117545b10b
Comment 78 Ralf Habacker 2019-12-28 21:21:46 UTC
Comment on attachment 8666 [details]
demonstrates XMI format from Unisys

This file could be loaded without any problems.
Comment 79 Ralf Habacker 2019-12-28 22:34:27 UTC
Git commit 4b2d8903650e7cf3d2adf9015a1ed22257e73491 by Ralf Habacker.
Committed on 28/12/2019 at 22:34.
Pushed by habacker into branch 'master'.

features.php: Add UNISYS to list of supported 3rdparty file formats

M  +1    -0    features.php

https://invent.kde.org/websites/umbrello-kde-org/commit/4b2d8903650e7cf3d2adf9015a1ed22257e73491
Comment 80 Ralf Habacker 2019-12-28 23:24:30 UTC
Comment on attachment 9024 [details]
DiagramDynamic.xmi - state diagram created by TogetherSoft

This format shows two problems:
1. all tags are upper case, which is currently not supported by umbrello
 
2. This example includes an UML:ACTIVITYGRAPH xmi tag, which is supported by UML 1.3/1.4, but not implemented in umbrello.
Comment 81 Ralf Habacker 2019-12-28 23:31:30 UTC
Comment on attachment 14038 [details]
EAExample-DesignModel-xmi12.xmi - XMI file created by Enterprise Architect

This format can also be read without problems.
Comment 82 Ralf Habacker 2019-12-28 23:32:56 UTC
Git commit 4b6fcb55c8d6f281a0b4ab776e86eb1b8de3f00d by Ralf Habacker.
Committed on 28/12/2019 at 23:32.
Pushed by habacker into branch 'master'.

features.php: Add 'Enterprise Architect' as supported 3rdparty file format

M  +1    -0    features.php

https://invent.kde.org/websites/umbrello-kde-org/commit/4b6fcb55c8d6f281a0b4ab776e86eb1b8de3f00d
Comment 83 Ralf Habacker 2019-12-28 23:37:46 UTC
Comment on attachment 14121 [details]
poseidon321.xmi - XMI file exported from Poseidon 3.2.1

This file can be read with minor problems:

1. The size of imported class diagramm widgets is to small. 

A workaround is to apply an auto layout.
Comment 84 Ralf Habacker 2019-12-29 00:03:34 UTC
Comment on attachment 86794 [details]
https://github.com/csware/argouml/blob/master/www/tours/enroll.zargo

No uml objects are imported when loading this file.

One workaround is to unpack the zargo file and open the embedded xmi file.
Comment 85 Ralf Habacker 2019-12-29 00:03:51 UTC
Comment on attachment 86802 [details]
http://argouml.tigris.org/tours/enroll_usecase.zargo

No uml objects are imported when loading this file.

One workaround is to unpack the zargo file and open the embedded xmi file.
Comment 86 Ralf Habacker 2019-12-29 00:07:38 UTC
Comment on attachment 86180 [details]
eclipse_uml_demo.xmi

This file can be read without any problems
Comment 87 Ralf Habacker 2019-12-29 00:08:55 UTC
Comment on attachment 87920 [details]
Demo file for the format generated by Embarcadero's "Describe" UML tool

This file can be loaded without any problems.
Comment 88 Ralf Habacker 2019-12-29 00:15:11 UTC
Comment on attachment 95658 [details]
XMI 2.1 demo file generated using Enterprise Architect 12

The uml objects from this file are loaded, diagrams are not loaded.
Comment 89 Ralf Habacker 2019-12-29 18:02:23 UTC
(In reply to Ralf Habacker from comment #80)
> 2. This example includes an UML:ACTIVITYGRAPH xmi tag, which is supported by
> UML 1.3/1.4, but not implemented in umbrello.

This mentioned xmi tag is referenced at https://pdfs.semanticscholar.org/7287/7422214f1401327000db96f5b44e8a29c1ec.pdf
Comment 90 Ralf Habacker 2019-12-30 23:15:33 UTC
Git commit cc799cb6efffbd18fce4678932846703603ef6a7 by Ralf Habacker.
Committed on 30/12/2019 at 23:15.
Pushed by habacker into branch 'master'.

Add check for loading an unsupported xmi version

This helps to identify why zargo test cases cannot be loaded.

With this commit class UMLDoc gets a private class to hold loading errors
and Import_Argo::loadFromArgoFile returns error state in all cases.

M  +12   -9    umbrello/import_argo.cpp
M  +32   -5    umbrello/umldoc.cpp
M  +5    -0    umbrello/umldoc.h

https://invent.kde.org/kde/umbrello/commit/cc799cb6efffbd18fce4678932846703603ef6a7
Comment 91 Ralf Habacker 2020-01-01 23:52:24 UTC
Git commit affcff748299c38b2fb0a4e133314d2c4f540464 by Ralf Habacker.
Committed on 01/01/2020 at 23:52.
Pushed by habacker into branch 'master'.

Also check tag 'xmi:version' to find the version of the xmi file

This tag is used by xmi file version >= 2

M  +2    -0    umbrello/umldoc.cpp

https://invent.kde.org/kde/umbrello/commit/affcff748299c38b2fb0a4e133314d2c4f540464
Comment 92 Ralf Habacker 2020-01-03 23:44:18 UTC
Git commit dc2d79ae4ff62b31b7ed5b04f8d34c9340856e16 by Ralf Habacker.
Committed on 03/01/2020 at 23:44.
Pushed by habacker into branch 'master'.

Correct minimum xmi file version

According to https://www.omg.org/spec/UML/20010967/01-02-16.dtd
UML 1.4 uses file version 1.1.

M  +1    -1    umbrello/umldoc.cpp

https://invent.kde.org/kde/umbrello/commit/dc2d79ae4ff62b31b7ed5b04f8d34c9340856e16
Comment 93 Oliver Kellogg 2020-06-05 21:25:53 UTC
Created attachment 129085 [details]
Demo XMI file showing the format used by OMG

This is a copy from
https://www.omg.org/members/cgi-bin/doc?dtc/19-06-19.xmi
demonstrating the "generic" XMI format used by the Object Management Group.

Umbrello fails to load this because of:
- Expecting XMI.header at  "uml:Model"
- bad assoctype of UML:AssociationType::Enum  "31a2bd95-fbef-11e1-a364-456a62c2a10f"
Comment 94 Oliver Kellogg 2020-06-06 15:41:21 UTC
(In reply to Oliver Kellogg from comment #93)
> Demo XMI file showing the format used by OMG
> [...]
> Umbrello fails to load this because of:
> - Expecting XMI.header at  "uml:Model"
> - bad assoctype of UML:AssociationType::Enum 

The list was missing the error
" Unsupported xmi file version: "

Notice that after "version:" there is no version indication.
Comment 95 Oliver Kellogg 2020-06-06 15:53:00 UTC
Git commit c1aadd7c3333332c220eb8bce90fcdd4a0ad13e9 by Oliver Kellogg.
Committed on 06/06/2020 at 15:51.
Pushed by okellogg into branch 'release/20.04'.

Address https://bugs.kde.org/show_bug.cgi?id=56184#c94

> The list was missing the error
> " Unsupported xmi file version: "
>
> Notice that after "version:" there is no version indication.

umbrello/umldoc.cpp
- In function loadFromXMI1, if both "xmi.version" and "xmi:version" are
  not found then do not assume versionString.toDouble() as the version
  because in this case, versionString is empty.
  In the interest of best effort, attempt loading the file if the XMI
  version is unknown.

M  +8    -6    umbrello/umldoc.cpp

https://invent.kde.org/sdk/umbrello/commit/c1aadd7c3333332c220eb8bce90fcdd4a0ad13e9
Comment 96 Ralf Habacker 2020-06-09 07:31:12 UTC
(In reply to Oliver Kellogg from comment #93)
> Created attachment 129085 [details]
> Demo XMI file showing the format used by OMG
> 
On loading this file I get 
> umbrello(25049) UMLDoc::encoding: Expecting XMI.header at  "uml:Profile"
> umbrello(25049) UMLDoc::loadFromXMI1: skipping < "uml:Profile" >

If you want to add support for loading an xmi file using the "uml:Profile", which requires patches, I suggest to open a new bug for that to have it included in the  "implemented features" list and to link this bug here.
Comment 97 Oliver Kellogg 2020-06-13 19:26:28 UTC
Created attachment 129328 [details]
Demo XMI file showing the format used by OMG

(In reply to Ralf Habacker from comment #96)
> 
> If you want to add support for loading an xmi file using the "uml:Profile",
> which requires patches, I suggest to open a new bug for that to have it
> included in the  "implemented features" list and to link this bug here.

Good point - thanks for observing.
It was not my intention to load the "uml:Profile".
I had another look for XMI files available at OMG and found
https://www.omg.org/spec/FUML/20180501/fUML_Library.xmi

In this file, the xmi.version / xmi:version is also missing.
However, loading it on basis of umbrello master@e68dc9d is largely successful.
Comment 98 Oliver Kellogg 2020-12-22 00:00:32 UTC
Git commit 74c9c2d93d4a124116892a5d87cdbc1f2becc893 by Oliver Kellogg.
Committed on 22/12/2020 at 00:00.
Pushed by okellogg into branch 'master'.

umbrello/umldoc.cpp
- In function loadFromXMI1 case !versionString.isEmpty() lower version
  requirement to 1.0.
  This change restores loading of files produced the Unisys.JCR.1 Rose
  to XMI converter, see https://bugs.kde.org/attachment.cgi?id=8666

M  +1    -1    umbrello/umldoc.cpp

https://invent.kde.org/sdk/umbrello/commit/74c9c2d93d4a124116892a5d87cdbc1f2becc893
Comment 99 Oliver Kellogg 2021-12-26 05:36:52 UTC
Git commit dba3b12e9dfcb0e3eb69e13d56789736b2c4153c by Oliver Kellogg.
Committed on 26/12/2021 at 05:36.
Pushed by okellogg into branch 'master'.

Improve loading of files from https://www.eclipse.org/papyrus

umbrello/uml.cpp
- In function slotFileOpen call to QFileDialog::getOpenFileUrl argument
  `filter' add pattern "*.uml" for Eclipse PapyrusUML files.

umbrello/uml1model/association.cpp
- In function load1:
  - Use function Model_Utils::getXmiId to abstract away the difference
    in XMI ID attribute (UML1 "xmi.id" vs. UML2 "xmi:id").
  - Support loading of association content without an envelope element
    such as <Association.connection>, <Association.end> etc.
  - Prepare for supporting PapyrusUML element <ownedEnd>.
- In function saveToXMI1, if m_AssocType is a Generalization then do not
  produce unused/empty XML attribute "discriminator".

umbrello/version.h
- Increase XMI_FILE_VERSION to "1.7.4" due to changed <UML:Association>.

M  +2    -1    umbrello/uml.cpp
M  +15   -15   umbrello/uml1model/association.cpp
M  +1    -1    umbrello/version.h

https://invent.kde.org/sdk/umbrello/commit/dba3b12e9dfcb0e3eb69e13d56789736b2c4153c
Comment 100 Oliver Kellogg 2022-01-12 20:17:51 UTC
Git commit c9da2ac42873122be610cdf2ae6a004f591e0623 by Oliver Kellogg.
Committed on 12/01/2022 at 20:16.
Pushed by okellogg into branch 'master'.

Followup to commit dba3b12 - further preparation for loading files from https://www.eclipse.org/papyrus

umbrello/umlmodel/attribute.cpp
- In function load1 case m_SecondaryId.isEmpty() while-loop, if href is
  non empty then require href to contain "PrimitiveTypes" in addition to
  "#".  Reason: Papyrus concidentally uses the datatype name as the
  xmi:id, but only in the predefined UMLPrimitiveTypes.library.uml and
  JavaPrimitiveTypes.library.uml.
  Proper resolution of href would require nested loading of model files,
  which is not yet implemented for Papyrus.

umbrello/dialogs/codetexthighlighter.cpp
- In function keywords() return empty QStringList immediately if `pl' is
  `Reserved' (else we crash due to null pointer dereference).

umbrello/codegenerators/codegenfactory.cpp
- In function createObject return null immediately if `pl' is Reserved
  (else we crash due to null pointer dereference).

M  +2    -0    umbrello/codegenerators/codegenfactory.cpp
M  +4    -1    umbrello/dialogs/codetexthighlighter.cpp
M  +6    -4    umbrello/umlmodel/attribute.cpp

https://invent.kde.org/sdk/umbrello/commit/c9da2ac42873122be610cdf2ae6a004f591e0623
Comment 101 Oliver Kellogg 2022-01-15 12:20:29 UTC
Comment on attachment 14121 [details]
poseidon321.xmi - XMI file exported from Poseidon 3.2.1

Unfortunately I made an error on uploading the file poseidon321.xmi, it is not in Poseidon format but in Umbrello format. I no longer have access to Poseidon and cannot provide a replacement.
Comment 102 Oliver Kellogg 2022-01-15 15:39:43 UTC
Git commit d0ba65c0e86a0a5913153b5380aeb2dec1dd2dff by Oliver Kellogg.
Committed on 15/01/2022 at 15:39.
Pushed by okellogg into branch 'master'.

Followup to https://bugs.kde.org/show_bug.cgi?id=56184#c60 : Establish basic loading of UML2 files from OMG and PapyrusUML

umbrello/umldoc.cpp
- In function encoding(QIODevice&),
  1) in the interest of best effort give a more optimistic result value,
     meaning that if no encoding info is found then return ENC_UNICODE;
  2) reduce code to only test for processing instruction; there is
     little gain in more intricate tests given 1).
- In function loadFromXMI(QIODevice&, short) :
  - Do not return false if no <XMI> or <xmi:XMI> element is found.
    Reason: According to the XMI standard this element is optional.
  - If no <XMI> or <xmi:XMI> element is found then
    - if the tag stripped of XML namespace is "Model" or "Package" then
      call loadUMLObjectsFromXMI(root);
    - otherwise print an error "Unrecognized outer element" and return
      false.

umbrello/umlmodel/attribute.cpp function load1
- In case m_SecondaryId.isEmpty() while-loop :
  - Change the if-statement testing m_SecondaryId.isEmpty() to test
    !m_SecondaryId.isEmpty() with `break' to save an indentation level.
  - If href is non empty then
    - require the xmi:type to contain "PrimitiveTypes";
    - improve extraction of type name from the primitive type XMI ID.
  - More work is needed. Known shortcoming: The attribute or attribute
    type does not reliably show up in the list view, for unknown reason.

M  +158  -196  umbrello/umldoc.cpp
M  +41   -24   umbrello/umlmodel/attribute.cpp

https://invent.kde.org/sdk/umbrello/commit/d0ba65c0e86a0a5913153b5380aeb2dec1dd2dff
Comment 103 Oliver Kellogg 2022-02-05 07:57:20 UTC
Created attachment 146297 [details]
Demo XMI file showing the format used by Software Ideas Modeler
Comment 104 Oliver Kellogg 2022-02-05 08:12:54 UTC
Git commit b3c005b7c139d4900c44c188231be82a49cbaa35 by Oliver Kellogg.
Committed on 05/02/2022 at 08:12.
Pushed by okellogg into branch 'master'.

Support loading of XMI from https://www.softwareideas.net

umbrello/umldoc.cpp
- In function encoding(QIODevice&) while-loop case
  node.isProcessingInstruction() case (pos >= 0), compare encData
  to "UTF-8", "windows-1252" case insensitively.
- In function loadFromXMI case outerTag "xmi:XMI" loop over nodes,
  handle outerTag "packagedElement" alongside "Model" and "Package".

Thanks to Jess Jones for https://bugs.kde.org/attachment.cgi?id=146297

M  +4    -3    umbrello/umldoc.cpp

https://invent.kde.org/sdk/umbrello/commit/b3c005b7c139d4900c44c188231be82a49cbaa35
Comment 105 Oliver Kellogg 2022-04-06 19:23:50 UTC
Git commit 195720f95b88df37cc1deaa83929daf1df74abca by Oliver Kellogg.
Committed on 06/04/2022 at 19:22.
Pushed by okellogg into branch 'master'.

Support loading of attribute type from MagicDraw/Cameo href to PrimitiveTypes.xmi :

umbrello/umlmodel/attribute.cpp
- In function load1 case m_SecondaryId.isEmpty() while-loop over node
  case !href.isEmpty(),
  - bool isPrimitive is set to xmiType.contains("PrimitiveType") if
    xmiType is non empty, else is set to href.contains("PrimitiveType");
  - proceed with primitive type handling if isPrimitive is true and the
    href suffix conforms to primitive type syntax.

M  +6    -2    umbrello/umlmodel/attribute.cpp

https://invent.kde.org/sdk/umbrello/commit/195720f95b88df37cc1deaa83929daf1df74abca
Comment 106 Oliver Kellogg 2022-04-17 12:59:29 UTC
Git commit 5803dcd2a91e2e66c372376cbc7586a080a004d7 by Oliver Kellogg.
Committed on 17/04/2022 at 12:58.
Pushed by okellogg into branch 'master'.

umbrello/umldoc.cpp : Add basic support for loading StarUML v5 XMI v2.1

- In function loadUMLObjectsFromXMI loop of node over element children
  move the code
    if (tagEq(type, QLatin1String("packagedElement")) ||
               tagEq(type, QLatin1String("ownedElement"))) {
        type = tempElement.attribute(QLatin1String("xmi:type"));
    }
  up by a few lines to precede the test for tagEq(type, "Model").
  Reason: StarUML generates a model element
    <packagedElement [...] xmi:type="uml:Model">
  nested inside the outer envelope
    <uml:Model [...] xmi:type="uml:Model" name="RootModel">

M  +7    -6    umbrello/umldoc.cpp

https://invent.kde.org/sdk/umbrello/commit/5803dcd2a91e2e66c372376cbc7586a080a004d7
Comment 107 Oliver Kellogg 2022-05-16 19:18:39 UTC
Git commit a8037fbad138b311b88ac1136f797e59f4f9d92c by Oliver Kellogg.
Committed on 16/05/2022 at 19:18.
Pushed by okellogg into branch 'master'.

Followup to commit 5803dcd - add basic support for loading StarUML and MagicDraw/Cameo while preserving load of native XMI:

umbrello/model_utils.{h,cpp}
- New function loadCommentFromXMI returns the text of an <ownedComment>
  UML2 element from a QDomElement. It attempts to read the attribute
  "body" and if that returns empty then attempts to read the text of the
  nested element <body>.

umbrello/umldoc.cpp
- In function loadFromXMI case outerTag "XMI" or "xmi:XMI" for-loop of
  node:
  - If outerTag stripped of namespace is "Model" or "Package" or
    "packagedElement" and the call to loadUMLObjectsFromXMI(element)
    returns false then do not return false.
    Reason: This gives better results on loading foreign XMI formats.
  - Support tagEq(tag, "DataType") alongside "Package", "Class", etc.
  - Support tagEq(tag, "ownedComment") using
    Model_Utils::loadCommentFromXMI(element).
- In function loadUMLObjectsFromXMI for-loop of node:
  1) Move up declaration of xmiType and setting of type from xmiType to
     before handling of tagEq(type, "Model").
  2) Remove test (type == "packagedElement"), it is obsoleted by 1).
  3) If loadUMLObjectsFromXMI(tempElement) returns false then do not
     return false.
     Reason: This gives better results on loading foreign XMI formats.
  4) Support loading of <ownedComment> using Model_Utils::
     loadCommentFromXMI(tempElement).
  5) If pObject->loadFromXMI(tempElement) returns false then do not
     return false.
     Reason: This gives better results on loading foreign XMI formats.

umbrello/umlmodel/umlobject.cpp
- In function loadFromXMI case element.hasChildNodes() while-loop of
  elem add loading of <ownedComment> using Model_Utils::
  loadCommentFromXMI(elem).

M  +22   -0    umbrello/model_utils.cpp
M  +1    -0    umbrello/model_utils.h
M  +17   -14   umbrello/umldoc.cpp
M  +2    -0    umbrello/umlmodel/umlobject.cpp

https://invent.kde.org/sdk/umbrello/commit/a8037fbad138b311b88ac1136f797e59f4f9d92c