Commit 811994e7 authored by Oliver Kellogg's avatar Oliver Kellogg
Browse files

(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.

CCBUG:56184
parent c473c5bb
......@@ -315,6 +315,7 @@ bool UMLAssociation::load(QDomElement & element)
if (Model_Utils::isCommonXMIAttribute(tag))
continue;
if (!UMLDoc::tagEq(tag, QLatin1String("Association.connection")) &&
!UMLDoc::tagEq(tag, QLatin1String("Association.end")) && // Embarcadero's Describe
!UMLDoc::tagEq(tag, QLatin1String("Namespace.ownedElement")) &&
!UMLDoc::tagEq(tag, QLatin1String("Namespace.contents"))) {
uWarning() << "unknown child node " << tag;
......@@ -330,8 +331,10 @@ bool UMLAssociation::load(QDomElement & element)
return false;
}
tag = tempElement.tagName();
if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
!UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
if (UMLDoc::tagEq(tag, QLatin1String("NavigableEnd"))) { // Embarcadero's Describe
m_AssocType = Uml::AssociationType::UniAssociation;
} else if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
!UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
uWarning() << "unknown child (A) tag " << tag;
return false;
}
......@@ -347,8 +350,10 @@ bool UMLAssociation::load(QDomElement & element)
return false;
}
tag = tempElement.tagName();
if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
!UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
if (UMLDoc::tagEq(tag, QLatin1String("NavigableEnd"))) { // Embarcadero's Describe
m_AssocType = Uml::AssociationType::UniAssociation;
} else if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
!UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
uWarning() << "unknown child (B) tag " << tag;
return false;
}
......
......@@ -1530,6 +1530,7 @@ bool UMLClassifier::load(QDomElement& element)
if (UMLDoc::tagEq(tag, QLatin1String("ModelElement.templateParameter")) ||
UMLDoc::tagEq(tag, QLatin1String("Classifier.feature")) ||
UMLDoc::tagEq(tag, QLatin1String("Namespace.ownedElement")) ||
UMLDoc::tagEq(tag, QLatin1String("Element.ownedElement")) || // Embarcadero's Describe
UMLDoc::tagEq(tag, QLatin1String("Namespace.contents"))) {
load(element);
// Not evaluating the return value from load()
......
......@@ -268,10 +268,13 @@ bool UMLEnum::load(QDomElement& element)
return false;
}
m_List.append(pEnumLiteral);
} else if (UMLDoc::tagEq(tag, QLatin1String("Enumeration.literal"))) { // Embarcadero's Describe
if (! load(tempElement))
return false;
} else if (tag == QLatin1String("stereotype")) {
uDebug() << name() << ": losing old-format stereotype.";
} else {
uWarning() << "unknown child type in UMLEnum::load";
uWarning() << "unknown child type: " << tag;
}
node = node.nextSibling();
}//end while
......
......@@ -384,6 +384,8 @@ UMLObject* makeObjectFromXMI(const QString& xmiTag,
pObject = new UMLAssociation(Uml::AssociationType::Realization);
} else if (UMLDoc::tagEq(xmiTag, QLatin1String("Dependency"))) {
pObject = new UMLAssociation(Uml::AssociationType::Dependency);
} else if (UMLDoc::tagEq(xmiTag, QLatin1String("Aggregation"))) { // Embarcadero's Describe
pObject = new UMLAssociation(Uml::AssociationType::Aggregation);
} else if (UMLDoc::tagEq(xmiTag, QLatin1String("Child2Category"))) {
pObject = new UMLAssociation(Uml::AssociationType::Child2Category);
} else if (UMLDoc::tagEq(xmiTag, QLatin1String("Category2Parent"))) {
......
......@@ -508,28 +508,33 @@ bool UMLOperation::load(QDomElement & element)
QDomElement attElement = node.toElement();
while (!attElement.isNull()) {
QString tag = attElement.tagName();
if (UMLDoc::tagEq(tag, QLatin1String("BehavioralFeature.parameter"))) {
if (UMLDoc::tagEq(tag, QLatin1String("BehavioralFeature.parameter")) ||
UMLDoc::tagEq(tag, QLatin1String("Element.ownedElement"))) { // Embarcadero's Describe
if (! load(attElement))
return false;
} else if (UMLDoc::tagEq(tag, QLatin1String("Parameter"))) {
QString kind = attElement.attribute(QLatin1String("kind"));
if (kind.isEmpty()) {
// Perhaps the kind is stored in a child node:
for (QDomNode n = attElement.firstChild(); !n.isNull(); n = n.nextSibling()) {
if (n.isComment())
continue;
QDomElement tempElement = n.toElement();
QString tag = tempElement.tagName();
if (!UMLDoc::tagEq(tag, QLatin1String("kind")))
continue;
kind = tempElement.attribute(QLatin1String("xmi.value"));
break;
kind = attElement.attribute(QLatin1String("direction")); // Embarcadero's Describe
if (kind.isEmpty()) {
// Perhaps the kind is stored in a child node:
for (QDomNode n = attElement.firstChild(); !n.isNull(); n = n.nextSibling()) {
if (n.isComment())
continue;
QDomElement tempElement = n.toElement();
QString tag = tempElement.tagName();
if (!UMLDoc::tagEq(tag, QLatin1String("kind")))
continue;
kind = tempElement.attribute(QLatin1String("xmi.value"));
break;
}
}
if (kind.isEmpty()) {
kind = QLatin1String("in");
}
}
if (kind == QLatin1String("return")) {
if (kind == QLatin1String("return") ||
kind == QLatin1String("result")) { // Embarcadero's Describe
QString returnId = Model_Utils::getXmiId(attElement);
if (!returnId.isEmpty())
m_returnId = Uml::ID::fromString(returnId);
......
......@@ -420,6 +420,7 @@ bool UMLPackage::load(QDomElement& element)
if (Model_Utils::isCommonXMIAttribute(type))
continue;
if (UMLDoc::tagEq(type, QLatin1String("Namespace.ownedElement")) ||
UMLDoc::tagEq(type, QLatin1String("Element.ownedElement")) || // Embarcadero's Describe
UMLDoc::tagEq(type, QLatin1String("Namespace.contents"))) {
//CHECK: Umbrello currently assumes that nested elements
// are ownedElements anyway.
......
......@@ -2036,6 +2036,7 @@ bool UMLDoc::loadFromXMI(QIODevice & file, short encode)
QString tag = element.tagName();
if (tag == QLatin1String("umlobjects") // for bkwd compat.
|| tagEq(tag, QLatin1String("Subsystem"))
|| tagEq(tag, QLatin1String("Project")) // Embarcadero's Describe
|| tagEq(tag, QLatin1String("Model"))) {
if(!loadUMLObjectsFromXMI(element)) {
uWarning() << "failed load on objects";
......@@ -2246,6 +2247,7 @@ bool UMLDoc::loadUMLObjectsFromXMI(QDomElement& element)
}
if (tagEq(type, QLatin1String("Namespace.ownedElement")) ||
tagEq(type, QLatin1String("Namespace.contents")) ||
tagEq(type, QLatin1String("Element.ownedElement")) || // Embarcadero's Describe
tagEq(type, QLatin1String("Model"))) {
//CHECK: Umbrello currently assumes that nested elements
// are ownedElements anyway.
......
......@@ -921,14 +921,10 @@ bool UMLObject::loadFromXMI(QDomElement & element)
m_name = element.attribute(QLatin1String("name"));
QString id = Model_Utils::getXmiId(element);
if (id.isEmpty() || id == QLatin1String("-1")) {
if (m_BaseType == ot_Role) {
// Before version 1.4, Umbrello did not save the xmi.id
// of UMLRole objects.
m_nId = UniqueID::gen();
} else {
uError() << m_name << ": nonexistent or illegal xmi.id";
return false;
}
// Before version 1.4, Umbrello did not save the xmi.id of UMLRole objects.
// Some tools (such as Embarcadero's) do not have an xmi.id on all attributes.
m_nId = UniqueID::gen();
uWarning() << m_name << ": xmi.id not present, generating a new one";
} else {
Uml::ID::Type nId = Uml::ID::fromString(id);
if (m_BaseType == ot_Role) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment