summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/package.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'umbrello/umbrello/package.cpp')
-rw-r--r--umbrello/umbrello/package.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/umbrello/umbrello/package.cpp b/umbrello/umbrello/package.cpp
new file mode 100644
index 00000000..54dc18a5
--- /dev/null
+++ b/umbrello/umbrello/package.cpp
@@ -0,0 +1,298 @@
+/***************************************************************************
+ * *
+ * 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) 2003-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header file
+#include "package.h"
+
+// system includes
+#include <kdebug.h>
+#include <klocale.h>
+
+// local includes
+#include "uml.h"
+#include "umldoc.h"
+#include "classifier.h"
+#include "association.h"
+#include "object_factory.h"
+#include "model_utils.h"
+#include "umllistview.h"
+#include "umllistviewitem.h"
+
+using namespace Uml;
+
+UMLPackage::UMLPackage(const QString & name, Uml::IDType id)
+ : UMLCanvasObject(name, id) {
+ init();
+}
+
+UMLPackage::~UMLPackage() {
+}
+
+void UMLPackage::init() {
+ m_BaseType = ot_Package;
+}
+
+void UMLPackage::copyInto(UMLPackage *rhs) const
+{
+ UMLCanvasObject::copyInto(rhs);
+
+ m_objects.copyInto(&(rhs->m_objects));
+}
+
+UMLObject* UMLPackage::clone() const
+{
+ UMLPackage *clone = new UMLPackage();
+ copyInto(clone);
+
+ return clone;
+}
+
+void UMLPackage::addAssocToConcepts(UMLAssociation* a) {
+ if (! UMLAssociation::assocTypeHasUMLRepresentation(a->getAssocType()) )
+ return;
+ Uml::IDType AId = a->getObjectId(Uml::A);
+ Uml::IDType BId = a->getObjectId(Uml::B);
+ UMLObject *o;
+ for (UMLObjectListIt it(m_objects); (o = it.current()) != NULL; ++it) {
+ UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
+ if (c == NULL)
+ continue;
+ if (AId == c->getID() || (BId == c->getID())) {
+ if (c->hasAssociation(a))
+ kDebug() << "UMLPackage::addAssocToConcepts: " << c->getName()
+ << " already has association id=" << ID2STR(a->getID())
+ << endl;
+ else
+ c->addAssociationEnd(a);
+ }
+ UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
+ if (pkg)
+ pkg->addAssocToConcepts(a);
+ }
+}
+
+void UMLPackage::removeAssocFromConcepts(UMLAssociation *assoc)
+{
+ UMLObject *o;
+ for (UMLObjectListIt it(m_objects); (o = it.current()) != NULL; ++it) {
+ UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
+ if (c == NULL)
+ continue;
+ if (c->hasAssociation(assoc))
+ c->removeAssociationEnd(assoc);
+ UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
+ if (pkg)
+ pkg->removeAssocFromConcepts(assoc);
+ }
+}
+
+bool UMLPackage::addObject(UMLObject *pObject) {
+ if (pObject == NULL) {
+ kError() << "UMLPackage::addObject is called with a NULL object"
+ << endl;
+ return false;
+ }
+ if (m_objects.find(pObject) != -1) {
+ kDebug() << "UMLPackage::addObject: " << pObject->getName()
+ << " is already there" << endl;
+ return false;
+ }
+ if (pObject->getBaseType() == Uml::ot_Association) {
+ UMLAssociation *assoc = static_cast<UMLAssociation*>(pObject);
+ // Adding the UMLAssociation at the participating concepts is done
+ // again later (in UMLAssociation::resolveRef()) if they are not yet
+ // known right here.
+ if (assoc->getObject(Uml::A) && assoc->getObject(Uml::B)) {
+ UMLPackage *pkg = pObject->getUMLPackage();
+ if (pkg != this) {
+ kError() << "UMLPackage " << m_Name << " addObject: "
+ << "assoc's UMLPackage is " << pkg->getName() << endl;
+ }
+ addAssocToConcepts(assoc);
+ }
+ }
+ m_objects.append( pObject );
+ return true;
+}
+
+void UMLPackage::removeObject(UMLObject *pObject) {
+ if (pObject->getBaseType() == Uml::ot_Association) {
+ UMLObject *o = const_cast<UMLObject*>(pObject);
+ UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
+ removeAssocFromConcepts(assoc);
+ }
+ if (m_objects.findRef(pObject) == -1)
+ kDebug() << m_Name << " removeObject: object with id="
+ << ID2STR(pObject->getID()) << "not found." << endl;
+ else
+ m_objects.remove(pObject);
+}
+
+void UMLPackage::removeAllObjects() {
+ UMLCanvasObject::removeAllChildObjects();
+ UMLObject *o;
+ while ((o = m_objects.first()) != NULL) {
+ UMLPackage *pkg = dynamic_cast<UMLPackage*>(o);
+ if (pkg)
+ pkg->removeAllObjects();
+ removeObject(o);
+ //delete o;
+ // CHECK: Direct usage of the destructor crashes on associations.
+ o->deleteLater();
+ }
+}
+
+UMLObjectList UMLPackage::containedObjects() {
+ return m_objects;
+}
+
+UMLObject * UMLPackage::findObject(const QString &name) {
+ const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
+ for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
+ UMLObject *obj = oit.current();
+ if (caseSensitive) {
+ if (obj->getName() == name)
+ return obj;
+ } else if (obj->getName().lower() == name.lower()) {
+ return obj;
+ }
+ }
+ return NULL;
+}
+
+UMLObject * UMLPackage::findObjectById(Uml::IDType id) {
+ return Model_Utils::findObjectInList(id, m_objects);
+}
+
+void UMLPackage::appendClassifiers(UMLClassifierList& classifiers,
+ bool includeNested /* = true */) {
+ for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
+ UMLObject *o = oit.current();
+ Object_Type ot = o->getBaseType();
+ if (ot == ot_Class || ot == ot_Interface ||
+ ot == ot_Datatype || ot == ot_Enum || ot == ot_Entity) {
+ classifiers.append((UMLClassifier *)o);
+ } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
+ UMLPackage *inner = static_cast<UMLPackage *>(o);
+ inner->appendClassifiers(classifiers);
+ }
+ }
+}
+
+void UMLPackage::appendClasses(UMLClassifierList& classes,
+ bool includeNested /* = true */) {
+ for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
+ UMLObject *o = oit.current();
+ Object_Type ot = o->getBaseType();
+ if (ot == ot_Class) {
+ UMLClassifier *c = static_cast<UMLClassifier*>(o);
+ classes.append(c);
+ } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
+ UMLPackage *inner = static_cast<UMLPackage *>(o);
+ inner->appendClasses(classes);
+ }
+ }
+}
+
+void UMLPackage::appendClassesAndInterfaces(UMLClassifierList& classifiers,
+ bool includeNested /* = true */) {
+ for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
+ UMLObject *o = oit.current();
+ Object_Type ot = o->getBaseType();
+ if (ot == ot_Class || ot == ot_Interface) {
+ UMLClassifier *c = static_cast<UMLClassifier*>(o);
+ classifiers.append(c);
+ } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
+ UMLPackage *inner = static_cast<UMLPackage *>(o);
+ inner->appendClassesAndInterfaces(classifiers);
+ }
+ }
+}
+
+void UMLPackage::appendInterfaces( UMLClassifierList& interfaces,
+ bool includeNested /* = true */) {
+ for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
+ UMLObject *o = oit.current();
+ Object_Type ot = o->getBaseType();
+ if (ot == ot_Interface) {
+ UMLClassifier *c = static_cast<UMLClassifier*>(o);
+ interfaces.append(c);
+ } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
+ UMLPackage *inner = static_cast<UMLPackage *>(o);
+ inner->appendInterfaces(interfaces);
+ }
+ }
+}
+
+bool UMLPackage::resolveRef() {
+ bool overallSuccess = UMLCanvasObject::resolveRef();
+ for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
+ UMLObject *obj = oit.current();
+ if (! obj->resolveRef()) {
+ Uml::Object_Type ot = obj->getBaseType();
+ if (ot != Uml::ot_Package && ot != Uml::ot_Folder)
+ m_objects.remove(obj);
+ overallSuccess = false;
+ }
+ }
+ return overallSuccess;
+}
+
+void UMLPackage::saveToXMI(QDomDocument& qDoc, QDomElement& qElement) {
+ QDomElement packageElement = UMLObject::save("UML:Package", qDoc);
+ QDomElement ownedElement = qDoc.createElement("UML:Namespace.ownedElement");
+ UMLObject *obj;
+ // save classifiers etc.
+ for (UMLObjectListIt oit(m_objects); (obj = oit.current()) != NULL; ++oit)
+ obj->saveToXMI (qDoc, ownedElement);
+ // save associations
+ for (UMLObjectListIt ait(m_List); (obj = ait.current()) != NULL; ++ait)
+ obj->saveToXMI (qDoc, ownedElement);
+
+ packageElement.appendChild(ownedElement);
+ qElement.appendChild(packageElement);
+}
+
+bool UMLPackage::load(QDomElement& element) {
+ for (QDomNode node = element.firstChild(); !node.isNull();
+ node = node.nextSibling()) {
+ if (node.isComment())
+ continue;
+ QDomElement tempElement = node.toElement();
+ QString type = tempElement.tagName();
+ if (Model_Utils::isCommonXMIAttribute(type))
+ continue;
+ if (tagEq(type, "Namespace.ownedElement") ||
+ tagEq(type, "Namespace.contents")) {
+ //CHECK: Umbrello currently assumes that nested elements
+ // are ownedElements anyway.
+ // Therefore these tags are not further interpreted.
+ if (! load(tempElement))
+ return false;
+ continue;
+ }
+ UMLObject *pObject = Object_Factory::makeObjectFromXMI(type);
+ if( !pObject ) {
+ kWarning() << "UMLPackage::load: "
+ << "Unknown type of umlobject to create: "
+ << type << endl;
+ continue;
+ }
+ pObject->setUMLPackage(this);
+ if (!pObject->loadFromXMI(tempElement)) {
+ removeObject(pObject);
+ delete pObject;
+ }
+ }
+ return true;
+}
+
+#include "package.moc"