You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
632 lines
23 KiB
632 lines
23 KiB
15 years ago
|
/***************************************************************************
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
* copyright (C) 2006-2007 *
|
||
|
* Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
|
||
|
***************************************************************************/
|
||
|
|
||
|
// own header
|
||
|
#include "petaltree2uml.h"
|
||
|
// qt/kde includes
|
||
|
#include <qregexp.h>
|
||
|
#include <kdebug.h>
|
||
|
// app includes
|
||
|
#include "petalnode.h"
|
||
|
#include "codeimport/import_utils.h"
|
||
|
#include "package.h"
|
||
|
#include "classifier.h"
|
||
|
#include "attribute.h"
|
||
|
#include "operation.h"
|
||
|
#include "association.h"
|
||
|
#include "umlrole.h"
|
||
|
#include "actor.h"
|
||
|
#include "usecase.h"
|
||
|
#include "component.h"
|
||
|
#include "node.h"
|
||
|
#include "uml.h"
|
||
|
#include "umldoc.h"
|
||
|
#include "umllistview.h"
|
||
|
#include "umllistviewitem.h"
|
||
|
|
||
|
namespace Import_Rose {
|
||
|
|
||
|
/**
|
||
|
* Return the given string without surrounding quotation marks.
|
||
|
* Also remove a possible prefix "Logical View::", it is not modeled in Umbrello.
|
||
|
*/
|
||
|
QString clean(const QString& s) {
|
||
|
if (s.isNull())
|
||
|
return QString();
|
||
|
QString str = s;
|
||
|
str.remove("\"");
|
||
|
str.remove(QRegExp("^Logical View::"));
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Extract the quid attribute from a petal node and return it as a Uml::IDType.
|
||
|
*/
|
||
|
Uml::IDType quid(const PetalNode *node) {
|
||
|
QString quidStr = node->findAttribute("quid").string;
|
||
|
if (quidStr.isEmpty())
|
||
|
return Uml::id_None;
|
||
|
quidStr.remove("\"");
|
||
|
return STR2ID(quidStr);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Extract the quidu attribute from a petal node.
|
||
|
*/
|
||
|
QString quidu(const PetalNode *node) {
|
||
|
QString quiduStr = node->findAttribute("quidu").string;
|
||
|
if (quiduStr.isEmpty())
|
||
|
return QString();
|
||
|
quiduStr.remove("\"");
|
||
|
return quiduStr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Determine the model type corresponding to a name.
|
||
|
* If the given name consists only of letters, digits, underscores, and
|
||
|
* scope separators, then return Uml::ot_Class, else return Uml::ot_Datatype.
|
||
|
*/
|
||
|
Uml::Object_Type typeToCreate(const QString& name) {
|
||
|
QString n = name;
|
||
|
n.remove(QRegExp("^.*::")); // don't consider the scope prefix, it may contain spaces
|
||
|
Uml::Object_Type t = (n.contains(QRegExp("\\W")) ? Uml::ot_Datatype : Uml::ot_Class);
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Transfer the Rose attribute "exportControl" to the Umbrello object given.
|
||
|
*
|
||
|
* @param from Pointer to PetalNode from which to read the "exportControl" attribute
|
||
|
* @param to Pointer to UMLObject in which to set the Uml::Visibility
|
||
|
*/
|
||
|
void transferVisibility(const PetalNode *from, UMLObject *to) {
|
||
|
QString vis = from->findAttribute("exportControl").string;
|
||
|
if (!vis.isEmpty()) {
|
||
|
Uml::Visibility v = Uml::Visibility::fromString(clean(vis.lower()));
|
||
|
to->setVisibility(v);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* ClassifierListReader factors the common processing for attributes, operations,
|
||
|
* and operation parameters.
|
||
|
*/
|
||
|
class ClassifierListReader {
|
||
|
public:
|
||
|
/// constructor
|
||
|
ClassifierListReader(const char* attributeTag,
|
||
|
const char* elementName,
|
||
|
const char* itemTypeDesignator) :
|
||
|
m_attributeTag(attributeTag),
|
||
|
m_elementName(elementName),
|
||
|
m_itemTypeDesignator(itemTypeDesignator) {
|
||
|
}
|
||
|
/// destructor
|
||
|
virtual ~ClassifierListReader() {}
|
||
|
|
||
|
/**
|
||
|
* Return a UMLClassifierListItem of the specific type desired.
|
||
|
* Abstract method to be implemented by inheriting classes.
|
||
|
*/
|
||
|
virtual UMLObject *createListItem() = 0;
|
||
|
|
||
|
virtual void setTypeReferences(UMLObject *item,
|
||
|
const QString& quid, const QString& type) {
|
||
|
if (!quid.isEmpty()) {
|
||
|
item->setSecondaryId(quid);
|
||
|
}
|
||
|
if (!type.isEmpty()) {
|
||
|
item->setSecondaryFallback(type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Insert the given UMLClassifierListItem at the parent Umbrello object.
|
||
|
* Abstract method to be implemented by inheriting classes.
|
||
|
* NB the parent Umbrello object is not included in the ClassifierListReader
|
||
|
* class - it must be added at inheriting classes.
|
||
|
*
|
||
|
* @param node The PetalNode which corresponds to the parent Umbrello object.
|
||
|
* @param o The UMLObject to insert.
|
||
|
*/
|
||
|
virtual void insertAtParent(const PetalNode *node, UMLObject *o) = 0;
|
||
|
|
||
|
/**
|
||
|
* Iterate over the attributes of the given PetalNode and for each recognized
|
||
|
* attribute do the following:
|
||
|
* - invoke createListItem()
|
||
|
* - fill common properties such as name, unique ID, visibility, etc. into
|
||
|
* the new UMLClassifierListItem
|
||
|
* - invoke insertAtParent() with the new classifier list item as the argument
|
||
|
* This is the user entry point.
|
||
|
*/
|
||
|
void read(const PetalNode *node, const QString& name) {
|
||
|
PetalNode *attributes = node->findAttribute(m_attributeTag).node;
|
||
|
if (attributes == NULL) {
|
||
|
#ifdef VERBOSE_DEBUGGING
|
||
|
kDebug() << "read(" << name << "): no " << m_attributeTag << " found"
|
||
|
<< endl;
|
||
|
#endif
|
||
|
return;
|
||
|
}
|
||
|
PetalNode::NameValueList attributeList = attributes->attributes();
|
||
|
for (uint i = 0; i < attributeList.count(); i++) {
|
||
|
PetalNode *attNode = attributeList[i].second.node;
|
||
|
QStringList initialArgs = attNode->initialArgs();
|
||
|
if (attNode->name() != m_elementName) {
|
||
|
kDebug() << "read(" << name << "): expecting " << m_elementName
|
||
|
<< ", " << "found " << initialArgs[0] << endl;
|
||
|
continue;
|
||
|
}
|
||
|
UMLObject *item = createListItem();
|
||
|
if (initialArgs.count() > 1)
|
||
|
item->setName(clean(initialArgs[1]));
|
||
|
item->setID(quid(attNode));
|
||
|
QString quidref = quidu(attNode);
|
||
|
QString type = clean(attNode->findAttribute(m_itemTypeDesignator).string);
|
||
|
setTypeReferences(item, quidref, type);
|
||
|
transferVisibility(attNode, item);
|
||
|
QString doc = attNode->findAttribute("documentation").string;
|
||
|
if (! doc.isEmpty())
|
||
|
item->setDoc(doc);
|
||
|
insertAtParent(attNode, item);
|
||
|
}
|
||
|
}
|
||
|
protected:
|
||
|
const QString m_attributeTag, m_elementName, m_itemTypeDesignator;
|
||
|
};
|
||
|
|
||
|
class AttributesReader : public ClassifierListReader {
|
||
|
public:
|
||
|
AttributesReader(UMLClassifier *c)
|
||
|
: ClassifierListReader("class_attributes", "ClassAttribute", "type") {
|
||
|
m_classifier = c;
|
||
|
}
|
||
|
virtual ~AttributesReader() {}
|
||
|
UMLObject *createListItem() {
|
||
|
return new UMLAttribute(m_classifier);
|
||
|
}
|
||
|
void insertAtParent(const PetalNode *, UMLObject *item) {
|
||
|
m_classifier->addAttribute(static_cast<UMLAttribute*>(item));
|
||
|
}
|
||
|
protected:
|
||
|
UMLClassifier *m_classifier;
|
||
|
};
|
||
|
|
||
|
class ParametersReader : public ClassifierListReader {
|
||
|
public:
|
||
|
ParametersReader(UMLOperation *op)
|
||
|
: ClassifierListReader("parameters", "Parameter", "type") {
|
||
|
m_operation = op;
|
||
|
}
|
||
|
virtual ~ParametersReader() {}
|
||
|
UMLObject *createListItem() {
|
||
|
return new UMLAttribute(m_operation);
|
||
|
}
|
||
|
void insertAtParent(const PetalNode *, UMLObject *item) {
|
||
|
m_operation->addParm(static_cast<UMLAttribute*>(item));
|
||
|
}
|
||
|
protected:
|
||
|
UMLOperation *m_operation;
|
||
|
};
|
||
|
|
||
|
class OperationsReader : public ClassifierListReader {
|
||
|
public:
|
||
|
OperationsReader(UMLClassifier *c)
|
||
|
: ClassifierListReader("operations", "Operation", "result") {
|
||
|
m_classifier = c;
|
||
|
}
|
||
|
virtual ~OperationsReader() {}
|
||
|
UMLObject *createListItem() {
|
||
|
return new UMLOperation(m_classifier);
|
||
|
}
|
||
|
void insertAtParent(const PetalNode *node, UMLObject *item) {
|
||
|
UMLOperation *op = static_cast<UMLOperation*>(item);
|
||
|
ParametersReader parmReader(op);
|
||
|
parmReader.read(node, m_classifier->getName());
|
||
|
m_classifier->addOperation(op);
|
||
|
}
|
||
|
protected:
|
||
|
UMLClassifier *m_classifier;
|
||
|
};
|
||
|
|
||
|
class SuperclassesReader : public ClassifierListReader {
|
||
|
public:
|
||
|
SuperclassesReader(UMLClassifier *c)
|
||
|
: ClassifierListReader("superclasses", "Inheritance_Relationship", "supplier") {
|
||
|
m_classifier = c;
|
||
|
}
|
||
|
virtual ~SuperclassesReader() {}
|
||
|
UMLObject *createListItem() {
|
||
|
return new UMLAssociation(Uml::at_Generalization);
|
||
|
}
|
||
|
/**
|
||
|
* Override parent implementation: The secondary data is not for the
|
||
|
* UMLAssociation itself but for its role B object.
|
||
|
*/
|
||
|
void setTypeReferences(UMLObject *item,
|
||
|
const QString& quid, const QString& type) {
|
||
|
UMLAssociation *assoc = static_cast<UMLAssociation*>(item);
|
||
|
if (!quid.isEmpty()) {
|
||
|
assoc->getUMLRole(Uml::B)->setSecondaryId(quid);
|
||
|
}
|
||
|
if (!type.isEmpty()) {
|
||
|
assoc->getUMLRole(Uml::B)->setSecondaryFallback(type);
|
||
|
}
|
||
|
}
|
||
|
void insertAtParent(const PetalNode *, UMLObject *item) {
|
||
|
UMLAssociation *assoc = static_cast<UMLAssociation*>(item);
|
||
|
assoc->setObject(m_classifier, Uml::A);
|
||
|
UMLApp::app()->getDocument()->addAssociation(assoc);
|
||
|
}
|
||
|
protected:
|
||
|
UMLClassifier *m_classifier;
|
||
|
};
|
||
|
|
||
|
class RealizationsReader : public ClassifierListReader {
|
||
|
public:
|
||
|
RealizationsReader(UMLClassifier *c)
|
||
|
: ClassifierListReader("realized_interfaces", "Realize_Relationship", "supplier") {
|
||
|
m_classifier = c;
|
||
|
}
|
||
|
virtual ~RealizationsReader() {}
|
||
|
UMLObject *createListItem() {
|
||
|
return new UMLAssociation(Uml::at_Realization);
|
||
|
}
|
||
|
/**
|
||
|
* Override parent implementation: The secondary data is not for the
|
||
|
* UMLAssociation itself but for its role B object.
|
||
|
*/
|
||
|
void setTypeReferences(UMLObject *item,
|
||
|
const QString& quid, const QString& type) {
|
||
|
UMLAssociation *assoc = static_cast<UMLAssociation*>(item);
|
||
|
if (!quid.isEmpty()) {
|
||
|
assoc->getUMLRole(Uml::B)->setSecondaryId(quid);
|
||
|
}
|
||
|
if (!type.isEmpty()) {
|
||
|
assoc->getUMLRole(Uml::B)->setSecondaryFallback(type);
|
||
|
}
|
||
|
}
|
||
|
void insertAtParent(const PetalNode *, UMLObject *item) {
|
||
|
UMLAssociation *assoc = static_cast<UMLAssociation*>(item);
|
||
|
assoc->setObject(m_classifier, Uml::A);
|
||
|
UMLApp::app()->getDocument()->addAssociation(assoc);
|
||
|
}
|
||
|
protected:
|
||
|
UMLClassifier *m_classifier;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Handle a controlled unit.
|
||
|
*
|
||
|
* @param node Pointer to the PetalNode which may contain a controlled unit
|
||
|
* @param name Name of the current node
|
||
|
* @param id QUID of the current node
|
||
|
* @param parentPkg Pointer to the current parent UMLPackage.
|
||
|
* @return True if the node actually contained a controlled unit.
|
||
|
*/
|
||
|
bool handleControlledUnit(PetalNode *node, const QString& name, Uml::IDType id, UMLPackage *parentPkg) {
|
||
|
if (node->findAttribute("is_unit").string != "TRUE")
|
||
|
return false;
|
||
|
bool is_loaded = (node->findAttribute("is_loaded").string != "FALSE");
|
||
|
QString file_name = node->findAttribute("file_name").string;
|
||
|
if (file_name.isEmpty()) {
|
||
|
kError() << "handleControlledUnit(" << name
|
||
|
<< "): attribute file_name not found (?)" << endl;
|
||
|
return true;
|
||
|
}
|
||
|
// To Be Continued.
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create an Umbrello object from a PetalNode of the Logical View.
|
||
|
*
|
||
|
* @return True for success.
|
||
|
* Given a PetalNode for which the mapping to Umbrello is not yet
|
||
|
* implemented umbrellify() is a no-op but also returns true.
|
||
|
*/
|
||
|
bool umbrellify(PetalNode *node, UMLPackage *parentPkg = NULL) {
|
||
|
if (node == NULL) {
|
||
|
kError() << "umbrellify: node is NULL" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
QStringList args = node->initialArgs();
|
||
|
QString objType = args[0];
|
||
|
QString name = clean(args[1]);
|
||
|
Uml::IDType id = quid(node);
|
||
|
|
||
|
if (objType == "Class_Category") {
|
||
|
UMLObject *o = Import_Utils::createUMLObject(Uml::ot_Package, name, parentPkg);
|
||
|
o->setID(id);
|
||
|
PetalNode *logical_models = node->findAttribute("logical_models").node;
|
||
|
if (logical_models) {
|
||
|
UMLPackage *localParent = static_cast<UMLPackage*>(o);
|
||
|
PetalNode::NameValueList atts = logical_models->attributes();
|
||
|
for (uint i = 0; i < atts.count(); i++) {
|
||
|
umbrellify(atts[i].second.node, localParent);
|
||
|
}
|
||
|
} else if (!handleControlledUnit(node, name, id, parentPkg)) {
|
||
|
kDebug() << "umbrellify: handling of " << objType << " " << name
|
||
|
<< " is not yet implemented" << endl;
|
||
|
}
|
||
|
|
||
|
} else if (objType == "Class") {
|
||
|
UMLObject *o = Import_Utils::createUMLObject(Uml::ot_Class, name, parentPkg);
|
||
|
o->setID(id);
|
||
|
UMLClassifier *c = static_cast<UMLClassifier*>(o);
|
||
|
// set stereotype
|
||
|
QString stereotype = clean(node->findAttribute("stereotype").string);
|
||
|
if (!stereotype.isEmpty()) {
|
||
|
if (stereotype.lower() == "interface")
|
||
|
c->setBaseType(Uml::ot_Interface);
|
||
|
else
|
||
|
c->setStereotype(stereotype);
|
||
|
}
|
||
|
// insert attributes
|
||
|
AttributesReader attReader(c);
|
||
|
attReader.read(node, c->getName());
|
||
|
// insert operations
|
||
|
OperationsReader opReader(c);
|
||
|
opReader.read(node, c->getName());
|
||
|
// insert generalizations
|
||
|
SuperclassesReader superReader(c);
|
||
|
superReader.read(node, c->getName());
|
||
|
// insert realizations
|
||
|
RealizationsReader realReader(c);
|
||
|
realReader.read(node, c->getName());
|
||
|
|
||
|
} else if (objType == "Association") {
|
||
|
PetalNode *roles = node->findAttribute("roles").node;
|
||
|
if (node == NULL) {
|
||
|
kError() << "umbrellify: cannot find roles of Association" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
UMLAssociation *assoc = new UMLAssociation(Uml::at_UniAssociation);
|
||
|
PetalNode::NameValueList roleList = roles->attributes();
|
||
|
for (uint i = 0; i <= 1; i++) {
|
||
|
PetalNode *roleNode = roleList[i].second.node;
|
||
|
if (roleNode == NULL) {
|
||
|
kError() << "umbrellify: roleNode of Association is NULL" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
if (roleNode->name() != "Role") {
|
||
|
kDebug() << "umbrellify(" << name << "): expecting Role, found \""
|
||
|
<< roleNode->name() << endl;
|
||
|
continue;
|
||
|
}
|
||
|
// index 0 corresponds to Umbrello roleB
|
||
|
// index 1 corresponds to Umbrello roleA
|
||
|
UMLRole *role = assoc->getUMLRole((Uml::Role_Type) !i);
|
||
|
QStringList initialArgs = roleNode->initialArgs();
|
||
|
if (initialArgs.count() > 1) {
|
||
|
QString roleName = clean(initialArgs[1]);
|
||
|
if (! roleName.startsWith("$UNNAMED"))
|
||
|
role->setName(roleName);
|
||
|
}
|
||
|
role->setID(quid(roleNode));
|
||
|
QString quidref = quidu(roleNode);
|
||
|
QString type = clean(roleNode->findAttribute("supplier").string);
|
||
|
if (!quidref.isEmpty()) {
|
||
|
role->setSecondaryId(quidref);
|
||
|
}
|
||
|
if (!type.isEmpty()) {
|
||
|
role->setSecondaryFallback(type);
|
||
|
}
|
||
|
QString label = clean(roleNode->findAttribute("label").string);
|
||
|
if (!label.isEmpty()) {
|
||
|
role->setName(label);
|
||
|
}
|
||
|
QString client_cardinality = clean(roleNode->findAttribute("client_cardinality").string);
|
||
|
if (!client_cardinality.isEmpty()) {
|
||
|
role->setMultiplicity(client_cardinality);
|
||
|
}
|
||
|
QString is_navigable = clean(roleNode->findAttribute("is_navigable").string);
|
||
|
if (is_navigable == "FALSE") {
|
||
|
assoc->setAssocType(Uml::at_Association);
|
||
|
}
|
||
|
QString is_aggregate = clean(roleNode->findAttribute("is_aggregate").string);
|
||
|
if (is_aggregate == "TRUE") {
|
||
|
assoc->setAssocType(Uml::at_Aggregation);
|
||
|
}
|
||
|
QString containment = clean(roleNode->findAttribute("Containment").string);
|
||
|
if (containment == "By Value") {
|
||
|
assoc->setAssocType(Uml::at_Composition);
|
||
|
}
|
||
|
QString doc = roleNode->findAttribute("documentation").string;
|
||
|
if (! doc.isEmpty())
|
||
|
role->setDoc(doc);
|
||
|
}
|
||
|
UMLApp::app()->getDocument()->addAssociation(assoc);
|
||
|
|
||
|
} else {
|
||
|
kDebug() << "umbrellify: object type " << objType
|
||
|
<< " is not yet implemented" << endl;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
Uml::ListView_Type folderType(UMLListViewItem *parent) {
|
||
|
Uml::ListView_Type type = Uml::lvt_Unknown;
|
||
|
switch (parent->getType()) {
|
||
|
case Uml::lvt_Logical_View:
|
||
|
case Uml::lvt_Logical_Folder:
|
||
|
type = Uml::lvt_Logical_Folder;
|
||
|
break;
|
||
|
case Uml::lvt_UseCase_View:
|
||
|
case Uml::lvt_UseCase_Folder:
|
||
|
type = Uml::lvt_UseCase_Folder;
|
||
|
break;
|
||
|
case Uml::lvt_Component_View:
|
||
|
case Uml::lvt_Component_Folder:
|
||
|
type = Uml::lvt_Component_Folder;
|
||
|
break;
|
||
|
case Uml::lvt_Deployment_View:
|
||
|
case Uml::lvt_Deployment_Folder:
|
||
|
type = Uml::lvt_Deployment_Folder;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return type;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create an Umbrello object from a PetalNode of the UseCase, Component,
|
||
|
* or Deployment View.
|
||
|
*
|
||
|
* @return True for success.
|
||
|
* Given a PetalNode for which the mapping to Umbrello is not yet
|
||
|
* implemented umbrellify() is a no-op but also returns true.
|
||
|
*/
|
||
|
bool umbrellify(PetalNode *node, const QString& modelsName, UMLListViewItem *parent) {
|
||
|
if (node == NULL) {
|
||
|
kError() << "umbrellify(" << modelsName << "): node is NULL" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
QStringList args = node->initialArgs();
|
||
|
QString objType = args[0];
|
||
|
QString name = clean(args[1]);
|
||
|
Uml::IDType id = quid(node);
|
||
|
UMLObject *obj = NULL;
|
||
|
UMLListViewItem *item = NULL;
|
||
|
|
||
|
if (objType == "Class_Category") {
|
||
|
Uml::ListView_Type lvType = folderType(parent);
|
||
|
item = new UMLListViewItem( parent, name, lvType, id );
|
||
|
} else if (objType == "Class") {
|
||
|
QString stereotype = clean(node->findAttribute("stereotype").string);
|
||
|
if (stereotype == "Actor") {
|
||
|
UMLActor *act = new UMLActor(name, id);
|
||
|
item = new UMLListViewItem(parent, name, Uml::lvt_Actor, act);
|
||
|
obj = act;
|
||
|
} else {
|
||
|
kDebug() << "umbrellify(" << name << "): handling of Class stereotype "
|
||
|
<< stereotype << " is not yet implemented" << endl;
|
||
|
}
|
||
|
} else if (objType == "UseCase") {
|
||
|
UMLUseCase *uc = new UMLUseCase(name, id);
|
||
|
item = new UMLListViewItem(parent, name, Uml::lvt_UseCase, uc);
|
||
|
obj = uc;
|
||
|
} else if (objType == "SubSystem") {
|
||
|
UMLComponent *comp = new UMLComponent(name, id);
|
||
|
item = new UMLListViewItem(parent, name, Uml::lvt_Component, comp);
|
||
|
obj = comp;
|
||
|
} else if (objType == "Processor" || objType == "Device") {
|
||
|
UMLNode *un = new UMLNode(name, id);
|
||
|
un->setStereotype(objType.lower());
|
||
|
item = new UMLListViewItem(parent, name, Uml::lvt_Node, un);
|
||
|
obj = un;
|
||
|
} else {
|
||
|
kDebug() << "umbrellify: object type " << objType
|
||
|
<< " is not yet implemented" << endl;
|
||
|
return true;
|
||
|
}
|
||
|
PetalNode *models = node->findAttribute(modelsName).node;
|
||
|
if (models) {
|
||
|
PetalNode::NameValueList atts = models->attributes();
|
||
|
for (uint i = 0; i < atts.count(); i++) {
|
||
|
if (! umbrellify(atts[i].second.node, modelsName, item))
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
if (obj) {
|
||
|
QString doc = node->findAttribute("documentation").string;
|
||
|
if (! doc.isEmpty())
|
||
|
obj->setDoc(doc);
|
||
|
UMLDoc *theDocument = UMLApp::app()->getDocument();
|
||
|
theDocument->addUMLObject(obj);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Auxiliary function for UseCase/Component/Deployment view import
|
||
|
*/
|
||
|
bool importView(PetalNode *root, const QString& rootName,
|
||
|
const QString& modelsName, UMLListViewItem *lvParent) {
|
||
|
PetalNode *viewRoot = root->findAttribute(rootName).node;
|
||
|
if (viewRoot == NULL) {
|
||
|
kDebug() << "importView: cannot find " << rootName << endl;
|
||
|
return false;
|
||
|
}
|
||
|
PetalNode *models = viewRoot->findAttribute(modelsName).node;
|
||
|
if (models == NULL) {
|
||
|
kError() << "importView: cannot find " << modelsName
|
||
|
<< " of " << rootName << endl;
|
||
|
return false;
|
||
|
}
|
||
|
PetalNode::NameValueList atts = models->attributes();
|
||
|
for (uint i = 0; i < atts.count(); i++) {
|
||
|
umbrellify(atts[i].second.node, modelsName, lvParent);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool petalTree2Uml(PetalNode *root) {
|
||
|
if (root == NULL) {
|
||
|
kError() << "petalTree2Uml: root is NULL" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
if (root->name() != "Design") {
|
||
|
kError() << "petalTree2Uml: expecting root name Design" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
/*************************** import Logical View ********************************/
|
||
|
PetalNode *root_category = root->findAttribute("root_category").node;
|
||
|
if (root_category == NULL) {
|
||
|
kError() << "petalTree2Uml: cannot find root_category" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
if (root_category->name() != "Class_Category") {
|
||
|
kError() << "petalTree2Uml: expecting root_category object Class_Category"
|
||
|
<< endl;
|
||
|
return false;
|
||
|
}
|
||
|
PetalNode *logical_models = root_category->findAttribute("logical_models").node;
|
||
|
if (logical_models == NULL) {
|
||
|
kError() << "petalTree2Uml: cannot find logical_models" << endl;
|
||
|
return false;
|
||
|
}
|
||
|
UMLDoc *umldoc = UMLApp::app()->getDocument();
|
||
|
umldoc->setCurrentRoot(Uml::mt_Logical);
|
||
|
Import_Utils::assignUniqueIdOnCreation(false);
|
||
|
PetalNode::NameValueList atts = logical_models->attributes();
|
||
|
for (uint i = 0; i < atts.count(); i++) {
|
||
|
umbrellify(atts[i].second.node);
|
||
|
}
|
||
|
|
||
|
/** Shorthand for UMLApp::app()->getListView() **/
|
||
|
UMLListView *lv = UMLApp::app()->getListView();
|
||
|
|
||
|
/*************************** import Use Case View ********************************/
|
||
|
umldoc->setCurrentRoot(Uml::mt_UseCase);
|
||
|
importView(root, "root_usecase_package", "logical_models", lv->theUseCaseView());
|
||
|
|
||
|
/*************************** import Component View *******************************/
|
||
|
umldoc->setCurrentRoot(Uml::mt_Component);
|
||
|
importView(root, "root_subsystem", "physical_models", lv->theComponentView());
|
||
|
|
||
|
/*************************** import Deployment View ******************************/
|
||
|
umldoc->setCurrentRoot(Uml::mt_Deployment);
|
||
|
importView(root, "process_structure", "ProcsNDevs", lv->theDeploymentView());
|
||
|
|
||
|
/*************************** wrap up ********************************/
|
||
|
umldoc->setCurrentRoot(Uml::mt_Logical);
|
||
|
Import_Utils::assignUniqueIdOnCreation(true);
|
||
|
umldoc->resolveTypes();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
} // namespace Import_Rose
|
||
|
|