umbrello API Documentation

package.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   copyright (C) 2003-2006                                               *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 // own header file
00013 #include "package.h"
00014 
00015 // system includes
00016 #include <kdebug.h>
00017 #include <klocale.h>
00018 
00019 // local includes
00020 #include "uml.h"
00021 #include "umldoc.h"
00022 #include "classifier.h"
00023 #include "association.h"
00024 #include "object_factory.h"
00025 #include "model_utils.h"
00026 #include "umllistview.h"
00027 #include "umllistviewitem.h"
00028 
00029 using namespace Uml;
00030 
00031 UMLPackage::UMLPackage(const QString & name, Uml::IDType id)
00032         : UMLCanvasObject(name, id) {
00033     init();
00034 }
00035 
00036 UMLPackage::~UMLPackage() {
00037 }
00038 
00039 void UMLPackage::init() {
00040     m_BaseType = ot_Package;
00041 }
00042 
00043 void UMLPackage::copyInto(UMLPackage *rhs) const
00044 {
00045     UMLCanvasObject::copyInto(rhs);
00046 
00047     m_objects.copyInto(&(rhs->m_objects));
00048 }
00049 
00050 UMLObject* UMLPackage::clone() const
00051 {
00052     UMLPackage *clone = new UMLPackage();
00053     copyInto(clone);
00054 
00055     return clone;
00056 }
00057 
00058 void UMLPackage::addAssocToConcepts(UMLAssociation* a) {
00059     if (! UMLAssociation::assocTypeHasUMLRepresentation(a->getAssocType()) )
00060         return;
00061     Uml::IDType AId = a->getObjectId(Uml::A);
00062     Uml::IDType BId = a->getObjectId(Uml::B);
00063     UMLObject *o;
00064     for (UMLObjectListIt it(m_objects); (o = it.current()) != NULL; ++it) {
00065         UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
00066         if (c == NULL)
00067             continue;
00068         if (AId == c->getID() || (BId == c->getID())) {
00069             if (c->hasAssociation(a))
00070                 kDebug() << "UMLPackage::addAssocToConcepts: " << c->getName()
00071                     << " already has association id=" << ID2STR(a->getID())
00072                     << endl;
00073             else
00074                c->addAssociationEnd(a);
00075         }
00076         UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
00077         if (pkg)
00078             pkg->addAssocToConcepts(a);
00079     }
00080 }
00081 
00082 void UMLPackage::removeAssocFromConcepts(UMLAssociation *assoc)
00083 {
00084     UMLObject *o;
00085     for (UMLObjectListIt it(m_objects); (o = it.current()) != NULL; ++it) {
00086         UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
00087         if (c == NULL)
00088             continue;
00089         if (c->hasAssociation(assoc))
00090             c->removeAssociationEnd(assoc);
00091         UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
00092         if (pkg)
00093             pkg->removeAssocFromConcepts(assoc);
00094     }
00095 }
00096 
00097 bool UMLPackage::addObject(UMLObject *pObject) {
00098     if (pObject == NULL) {
00099         kError() << "UMLPackage::addObject is called with a NULL object"
00100             << endl;
00101         return false;
00102     }
00103     if (m_objects.find(pObject) != -1) {
00104         kDebug() << "UMLPackage::addObject: " << pObject->getName()
00105                   << " is already there" << endl;
00106         return false;
00107     }
00108     if (pObject->getBaseType() == Uml::ot_Association) {
00109         UMLAssociation *assoc = static_cast<UMLAssociation*>(pObject);
00110         // Adding the UMLAssociation at the participating concepts is done
00111         // again later (in UMLAssociation::resolveRef()) if they are not yet
00112         // known right here.
00113         if (assoc->getObject(Uml::A) && assoc->getObject(Uml::B)) {
00114             UMLPackage *pkg = pObject->getUMLPackage();
00115             if (pkg != this) {
00116                kError() << "UMLPackage " << m_Name << " addObject: "
00117                    << "assoc's UMLPackage is " << pkg->getName() << endl;
00118             }
00119             addAssocToConcepts(assoc);
00120         }
00121     }
00122     m_objects.append( pObject );
00123     return true;
00124 }
00125 
00126 void UMLPackage::removeObject(UMLObject *pObject) {
00127     if (pObject->getBaseType() == Uml::ot_Association) {
00128         UMLObject *o = const_cast<UMLObject*>(pObject);
00129         UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
00130         removeAssocFromConcepts(assoc);
00131     }
00132     if (m_objects.findRef(pObject) == -1)
00133         kDebug() << m_Name << " removeObject: object with id="
00134             << ID2STR(pObject->getID()) << "not found." << endl;
00135     else
00136         m_objects.remove(pObject);
00137 }
00138 
00139 void UMLPackage::removeAllObjects() {
00140     UMLCanvasObject::removeAllChildObjects();
00141     UMLObject *o;
00142     while ((o = m_objects.first()) != NULL) {
00143         UMLPackage *pkg = dynamic_cast<UMLPackage*>(o);
00144         if (pkg)
00145             pkg->removeAllObjects();
00146         removeObject(o);
00147         //delete o;
00148         // CHECK: Direct usage of the destructor crashes on associations.
00149         o->deleteLater();
00150     }
00151 }
00152 
00153 UMLObjectList UMLPackage::containedObjects() {
00154     return m_objects;
00155 }
00156 
00157 UMLObject * UMLPackage::findObject(const QString &name) {
00158     const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
00159     for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
00160         UMLObject *obj = oit.current();
00161         if (caseSensitive) {
00162             if (obj->getName() == name)
00163                 return obj;
00164         } else if (obj->getName().lower() == name.lower()) {
00165             return obj;
00166         }
00167     }
00168     return NULL;
00169 }
00170 
00171 UMLObject * UMLPackage::findObjectById(Uml::IDType id) {
00172     return Model_Utils::findObjectInList(id, m_objects);
00173 }
00174 
00175 void UMLPackage::appendClassifiers(UMLClassifierList& classifiers,
00176                                    bool includeNested /* = true */) {
00177     for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
00178         UMLObject *o = oit.current();
00179         Object_Type ot = o->getBaseType();
00180         if (ot == ot_Class || ot == ot_Interface ||
00181                 ot == ot_Datatype || ot == ot_Enum || ot == ot_Entity) {
00182             classifiers.append((UMLClassifier *)o);
00183         } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
00184             UMLPackage *inner = static_cast<UMLPackage *>(o);
00185             inner->appendClassifiers(classifiers);
00186         }
00187     }
00188 }
00189 
00190 void UMLPackage::appendClasses(UMLClassifierList& classes,
00191                                bool includeNested /* = true */) {
00192     for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
00193         UMLObject *o = oit.current();
00194         Object_Type ot = o->getBaseType();
00195         if (ot == ot_Class) {
00196             UMLClassifier *c = static_cast<UMLClassifier*>(o);
00197             classes.append(c);
00198         } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
00199             UMLPackage *inner = static_cast<UMLPackage *>(o);
00200             inner->appendClasses(classes);
00201         }
00202     }
00203 }
00204 
00205 void UMLPackage::appendClassesAndInterfaces(UMLClassifierList& classifiers,
00206         bool includeNested /* = true */) {
00207     for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
00208         UMLObject *o = oit.current();
00209         Object_Type ot = o->getBaseType();
00210         if (ot == ot_Class || ot == ot_Interface) {
00211             UMLClassifier *c = static_cast<UMLClassifier*>(o);
00212             classifiers.append(c);
00213         } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
00214             UMLPackage *inner = static_cast<UMLPackage *>(o);
00215             inner->appendClassesAndInterfaces(classifiers);
00216         }
00217     }
00218 }
00219 
00220 void UMLPackage::appendInterfaces( UMLClassifierList& interfaces,
00221                                    bool includeNested /* = true */) {
00222     for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
00223         UMLObject *o = oit.current();
00224         Object_Type ot = o->getBaseType();
00225         if (ot == ot_Interface) {
00226             UMLClassifier *c = static_cast<UMLClassifier*>(o);
00227             interfaces.append(c);
00228         } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
00229             UMLPackage *inner = static_cast<UMLPackage *>(o);
00230             inner->appendInterfaces(interfaces);
00231         }
00232     }
00233 }
00234 
00235 bool UMLPackage::resolveRef() {
00236     bool overallSuccess = UMLCanvasObject::resolveRef();
00237     for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
00238         UMLObject *obj = oit.current();
00239         if (! obj->resolveRef()) {
00240             Uml::Object_Type ot = obj->getBaseType();
00241             if (ot != Uml::ot_Package && ot != Uml::ot_Folder)
00242                 m_objects.remove(obj);
00243             overallSuccess = false;
00244         }
00245     }
00246     return overallSuccess;
00247 }
00248 
00249 void UMLPackage::saveToXMI(QDomDocument& qDoc, QDomElement& qElement) {
00250     QDomElement packageElement = UMLObject::save("UML:Package", qDoc);
00251     QDomElement ownedElement = qDoc.createElement("UML:Namespace.ownedElement");
00252     UMLObject *obj;
00253     // save classifiers etc.
00254     for (UMLObjectListIt oit(m_objects); (obj = oit.current()) != NULL; ++oit)
00255         obj->saveToXMI (qDoc, ownedElement);
00256     // save associations
00257     for (UMLObjectListIt ait(m_List); (obj = ait.current()) != NULL; ++ait)
00258         obj->saveToXMI (qDoc, ownedElement);
00259 
00260     packageElement.appendChild(ownedElement);
00261     qElement.appendChild(packageElement);
00262 }
00263 
00264 bool UMLPackage::load(QDomElement& element) {
00265     for (QDomNode node = element.firstChild(); !node.isNull();
00266             node = node.nextSibling()) {
00267         if (node.isComment())
00268             continue;
00269         QDomElement tempElement = node.toElement();
00270         QString type = tempElement.tagName();
00271         if (Model_Utils::isCommonXMIAttribute(type))
00272             continue;
00273         if (tagEq(type, "Namespace.ownedElement") ||
00274                 tagEq(type, "Namespace.contents")) {
00275             //CHECK: Umbrello currently assumes that nested elements
00276             // are ownedElements anyway.
00277             // Therefore these tags are not further interpreted.
00278             if (! load(tempElement))
00279                 return false;
00280             continue;
00281         }
00282         UMLObject *pObject = Object_Factory::makeObjectFromXMI(type);
00283         if( !pObject ) {
00284             kWarning() << "UMLPackage::load: "
00285                 << "Unknown type of umlobject to create: "
00286                 << type << endl;
00287             continue;
00288         }
00289         pObject->setUMLPackage(this);
00290         if (!pObject->loadFromXMI(tempElement)) {
00291             removeObject(pObject);
00292             delete pObject;
00293         }
00294     }
00295     return true;
00296 }
00297 
00298 #include "package.moc"
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:58 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003