umbrello API Documentation

umlobject.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) 2002-2006                                               *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 // own header
00013 #include "umlobject.h"
00014 // qt/kde includes
00015 #include <qregexp.h>
00016 #include <kdebug.h>
00017 #include <kapplication.h>
00018 // app includes
00019 #include "uniqueid.h"
00020 #include "uml.h"
00021 #include "umldoc.h"
00022 #include "umllistview.h"
00023 #include "umllistviewitem.h"
00024 #include "package.h"
00025 #include "folder.h"
00026 #include "stereotype.h"
00027 #include "object_factory.h"
00028 #include "model_utils.h"
00029 #include "codeimport/import_utils.h"
00030 #include "docwindow.h"
00031 #include "dialogs/classpropdlg.h"
00032 
00033 UMLObject::UMLObject(const UMLObject * parent, const QString &name, Uml::IDType id)
00034         : QObject(const_cast<UMLObject*>(parent), "UMLObject" ) {
00035     init();
00036     if (id == Uml::id_None)
00037         m_nId = UniqueID::gen();
00038     else
00039         m_nId = id;
00040     m_Name = name;
00041 }
00042 
00043 UMLObject::UMLObject(const QString &name, Uml::IDType id)
00044         :  QObject(UMLApp::app()->getDocument()) {
00045     init();
00046     if (id == Uml::id_None)
00047         m_nId = UniqueID::gen();
00048     else
00049         m_nId = id;
00050     m_Name = name;
00051 }
00052 
00053 UMLObject::UMLObject(const UMLObject * parent)
00054         : QObject(const_cast<UMLObject*>(parent)) {
00055     init();
00056 }
00057 
00058 UMLObject::~UMLObject() {
00059 }
00060 
00061 void UMLObject::init() {
00062     m_BaseType = Uml::ot_UMLObject;
00063     m_nId = Uml::id_None;
00064     m_pUMLPackage = NULL;
00065     m_Name = "";
00066     m_Vis = Uml::Visibility::Public;
00067     m_pStereotype = NULL;
00068     m_Doc = "";
00069     m_bAbstract = false;
00070     m_bStatic = false;
00071     m_bInPaste = false;
00072     m_bCreationWasSignalled = false;
00073     m_pSecondary = NULL;
00074 }
00075 
00076 bool UMLObject::showProperties(int page, bool assoc) {
00077     DocWindow *docwindow = UMLApp::app()->getDocWindow();
00078     docwindow->updateDocumentation(false);
00079     ClassPropDlg* dlg = new ClassPropDlg((QWidget*)UMLApp::app(), this, page, assoc);
00080     bool modified = false;
00081     if (dlg->exec()) {
00082         docwindow->showDocumentation(this, true);
00083         UMLApp::app()->getDocument()->setModified(true);
00084         modified = true;
00085     }
00086     dlg->close(true); //wipe from memory
00087     return modified;
00088 }
00089 
00090 bool UMLObject::acceptAssociationType(Uml::Association_Type)
00091 {// A UMLObject accepts nothing. This should be reimplemented by the subclasses
00092     return false;
00093 }
00094 
00095 void UMLObject::setID(Uml::IDType NewID) {
00096     m_nId = NewID;
00097     emitModified();
00098 }
00099 
00100 void UMLObject::setName(const QString &strName) {
00101     m_Name = strName;
00102     emitModified();
00103 }
00104 
00105 QString UMLObject::getName() const {
00106     return m_Name;
00107 }
00108 
00109 QString UMLObject::getFullyQualifiedName(QString separator,
00110                                          bool includeRoot /* = false */) const {
00111     QString fqn;
00112     if (m_pUMLPackage) {
00113         bool skipPackage = false;
00114         if (!includeRoot) {
00115             UMLDoc *umldoc = UMLApp::app()->getDocument();
00116             if (umldoc->rootFolderType(m_pUMLPackage) != Uml::N_MODELTYPES ||
00117                 m_pUMLPackage == umldoc->getDatatypeFolder())
00118                 skipPackage = true;
00119         }
00120         if (!skipPackage) {
00121             if (separator.isEmpty())
00122                 separator = UMLApp::app()->activeLanguageScopeSeparator();
00123             fqn = m_pUMLPackage->getFullyQualifiedName(separator, includeRoot);
00124             fqn.append(separator);
00125         }
00126     }
00127     fqn.append(m_Name);
00128     return fqn;
00129 }
00130 
00131 bool UMLObject::operator==(UMLObject & rhs ) {
00132     if( this == &rhs )
00133         return true;
00134 
00135     //don't compare IDs, these are program specific and
00136     //don't mean the objects are the same
00137     //***** CHECK: Who put in this comment? What was the reason?
00138     //***** Currently some operator== in umbrello compare the IDs
00139     //***** while others don't.
00140 
00141     if( m_Name != rhs.m_Name )
00142         return false;
00143 
00144     // Packages create different namespaces, therefore they should be
00145     // part of the equality test.
00146     if( m_pUMLPackage != rhs.m_pUMLPackage )
00147         return false;
00148 
00149     // Making the type part of an object's identity has its problems:
00150     // Not all programming languages support declarations of the same
00151     // name but different type.
00152     // In such cases, the code generator is responsible for generating
00153     // the appropriate error message.
00154     if( m_BaseType != rhs.m_BaseType )
00155         return false;
00156 
00157     // The documentation should not be part of the equality test.
00158     // If two objects are the same but differ only in their documentation,
00159     // what does that mean?
00160     //if( m_Doc != rhs.m_Doc )
00161     //  return false;
00162 
00163     // The scope should not be part of the equality test.
00164     // What does it mean if two objects are the same but differ in their
00165     // scope? - I'm not aware of any programming language that would
00166     // support that.
00167     //if( m_Vis != rhs.m_Vis )
00168     //  return false;
00169 
00170     // See comments above
00171     //if( m_pStereotype != rhs.m_pStereotype )
00172     //  return false;
00173 
00174     // See comments above
00175     //if( m_bAbstract != rhs.m_bAbstract )
00176     //  return false;
00177 
00178     // See comments above
00179     //if( m_bStatic != rhs.m_bStatic )
00180     //  return false;
00181 
00182     return true;
00183 }
00184 
00185 void UMLObject::copyInto(UMLObject *rhs) const
00186 {
00187     // Data members with copy constructor
00188     rhs->m_Doc = m_Doc;
00189     rhs->m_pStereotype = m_pStereotype;
00190     rhs->m_bAbstract = m_bAbstract;
00191     rhs->m_bStatic = m_bStatic;
00192     rhs->m_BaseType = m_BaseType;
00193     rhs->m_Vis = m_Vis;
00194     rhs->m_pUMLPackage = m_pUMLPackage;
00195 
00196     // We don't want the same name existing twice.
00197     rhs->m_Name = Model_Utils::uniqObjectName(m_BaseType, m_pUMLPackage, m_Name);
00198 
00199     // Create a new ID.
00200     rhs->m_nId = UniqueID::gen();
00201 
00202     // Hope that the parent from QObject is okay.
00203     if (rhs->parent() != parent())
00204         kDebug() << "copyInto has a wrong parent" << endl;
00205 }
00206 
00207 
00208 bool UMLObject::getAbstract() const{
00209     return m_bAbstract;
00210 }
00211 
00212 void UMLObject::setAbstract(bool bAbstract) {
00213     m_bAbstract = bAbstract;
00214     emitModified();
00215 }
00216 
00217 void UMLObject::setInPaste(bool bInPaste /* =true */) {
00218     m_bInPaste = bInPaste;
00219 }
00220 
00222 bool UMLObject::getStatic() const
00223 {
00224     return m_bStatic;
00225 }
00227 void UMLObject::setStatic(bool bStatic)
00228 {
00229     m_bStatic = bStatic;
00230     emitModified();
00231 }
00232 
00233 void UMLObject::emitModified()
00234 {
00235     UMLDoc *umldoc = UMLApp::app()->getDocument();
00236     if (! umldoc->loading())
00237         emit modified();
00238 }
00239 
00240 void UMLObject::setDoc(const QString &d) {
00241     m_Doc = d;
00242     //emit modified();  No, this is done centrally at DocWindow::updateDocumentation()
00243 }
00244 
00245 Uml::Object_Type UMLObject::getBaseType() const {
00246     return m_BaseType;
00247 }
00248 
00249 void UMLObject::setBaseType(Uml::Object_Type ot) {
00250     m_BaseType = ot;
00251 }
00252 
00253 Uml::IDType UMLObject::getID() const {
00254     return m_nId;
00255 }
00256 
00257 QString UMLObject::getDoc() const {
00258     return m_Doc;
00259 }
00260 
00261 Uml::Visibility UMLObject::getVisibility() const {
00262     return m_Vis;
00263 }
00264 
00265 void UMLObject::setVisibility(Uml::Visibility s) {
00266     m_Vis = s;
00267     emitModified();
00268 }
00269 
00270 void UMLObject::setUMLStereotype(UMLStereotype *stereo) {
00271     if (stereo == m_pStereotype)
00272         return;
00273     if (stereo) {
00274         stereo->incrRefCount();
00275     }
00276     if (m_pStereotype) {
00277         m_pStereotype->decrRefCount();
00278         if (m_pStereotype->refCount() == 0) {
00279             UMLDoc *pDoc = UMLApp::app()->getDocument();
00280             pDoc->removeStereotype(m_pStereotype);
00281             delete m_pStereotype;
00282         }
00283     }
00284     m_pStereotype = stereo;
00285     // TODO: don't emit modified() if predefined folder
00286     emitModified();
00287 }
00288 
00289 void UMLObject::setStereotype(const QString &_name) {
00290     if (_name.isEmpty()) {
00291         setUMLStereotype(NULL);
00292         return;
00293     }
00294     UMLDoc *pDoc = UMLApp::app()->getDocument();
00295     UMLStereotype *s = pDoc->findOrCreateStereotype(_name);
00296     setUMLStereotype(s);
00297 }
00298 
00299 void UMLObject::setPackage(const QString &_name) {
00300     UMLObject *pkgObj = NULL;
00301     if (!_name.isEmpty()) {
00302         UMLDoc* umldoc = UMLApp::app()->getDocument();
00303         pkgObj = umldoc->findUMLObject(_name);
00304         if (pkgObj == NULL) {
00305             kDebug() << "UMLObject::setPackage: creating UMLPackage "
00306                 << _name << " for " << m_Name << endl;
00307             pkgObj = Import_Utils::createUMLObject(Uml::ot_Package, _name);
00308         } else {
00309             const Uml::Object_Type ot = pkgObj->getBaseType();
00310             if (ot != Uml::ot_Package && ot != Uml::ot_Folder && ot != Uml::ot_Component) {
00311                 kError() << "UMLObject::setPackage(" << m_Name << "): "
00312                     << "existing " << _name << " is not a container" << endl;
00313                 // This should not happen - if it does, there may be further problems.
00314                 // A container name should not overlap with another name in the same scope.
00315                 pkgObj = Import_Utils::createUMLObject(Uml::ot_Package, _name);
00316             }
00317         }
00318     }
00319     setUMLPackage( static_cast<UMLPackage *>(pkgObj) );
00320 }
00321 
00322 void UMLObject::setUMLPackage(UMLPackage* pPkg) {
00323     m_pUMLPackage = pPkg;
00324     emitModified();
00325 }
00326 
00327 const UMLStereotype * UMLObject::getUMLStereotype() {
00328     return m_pStereotype;
00329 }
00330 
00331 QString UMLObject::getStereotype(bool includeAdornments /* = false */) const {
00332     if (m_pStereotype == NULL)
00333         return "";
00334     QString name = m_pStereotype->getName();
00335     if (includeAdornments)
00336         name = QString::fromUtf8("«") + name + QString::fromUtf8("»");
00337     return name;
00338 }
00339 
00340 QString UMLObject::getPackage(QString separator, bool includeRoot) {
00341     if (separator.isEmpty())
00342         separator = UMLApp::app()->activeLanguageScopeSeparator();
00343     QString fqn = getFullyQualifiedName(separator, includeRoot);
00344     if (!fqn.contains(separator))
00345         return "";
00346     QString scope = fqn.left(fqn.length() - separator.length() - m_Name.length());
00347     return scope;
00348 }
00349 
00350 UMLPackageList UMLObject::getPackages(bool includeRoot) const {
00351     UMLPackageList pkgList;
00352     UMLPackage* pkg = m_pUMLPackage;
00353     while (pkg != NULL) {
00354         pkgList.prepend(pkg);
00355         pkg = pkg->getUMLPackage();
00356     }
00357     if (!includeRoot)
00358         pkgList.removeFirst();
00359     return pkgList;
00360 }
00361 
00362 UMLPackage* UMLObject::getUMLPackage() {
00363     return m_pUMLPackage;
00364 }
00365 
00366 QString UMLObject::getSecondaryId() const {
00367     return m_SecondaryId;
00368 }
00369 
00370 void UMLObject::setSecondaryId(const QString& id) {
00371     m_SecondaryId = id;
00372 }
00373 
00374 QString UMLObject::getSecondaryFallback() const {
00375     return m_SecondaryFallback;
00376 }
00377 
00378 void UMLObject::setSecondaryFallback(const QString& id) {
00379     m_SecondaryFallback = id;
00380 }
00381 
00382 void UMLObject::maybeSignalObjectCreated() {
00383     if (!m_bCreationWasSignalled &&
00384             m_BaseType != Uml::ot_Stereotype &&
00385             m_BaseType != Uml::ot_Association &&
00386             m_BaseType != Uml::ot_Role) {
00387         m_bCreationWasSignalled = true;
00388         UMLDoc* umldoc = UMLApp::app()->getDocument();
00389         umldoc->signalUMLObjectCreated(this);
00390     }
00391 }
00392 
00393 bool UMLObject::resolveRef() {
00394     if (m_pSecondary || (m_SecondaryId.isEmpty() && m_SecondaryFallback.isEmpty())) {
00395         maybeSignalObjectCreated();
00396         return true;
00397     }
00398 #ifdef VERBOSE_DEBUGGING
00399     kDebug() << "UMLObject::resolveRef(" << m_Name << "): m_SecondaryId is "
00400               << m_SecondaryId << endl;
00401 #endif
00402     UMLDoc *pDoc = UMLApp::app()->getDocument();
00403     // In the new, XMI standard compliant save format,
00404     // the type is the xmi.id of a UMLClassifier.
00405     if (! m_SecondaryId.isEmpty()) {
00406         m_pSecondary = pDoc->findObjectById(STR2ID(m_SecondaryId));
00407         if (m_pSecondary != NULL) {
00408             if (m_pSecondary->getBaseType() == Uml::ot_Stereotype) {
00409                 m_pStereotype = static_cast<UMLStereotype*>(m_pSecondary);
00410                 m_pStereotype->incrRefCount();
00411                 m_pSecondary = NULL;
00412             }
00413             m_SecondaryId = "";
00414             maybeSignalObjectCreated();
00415             return true;
00416         }
00417         if (m_SecondaryFallback.isEmpty()) {
00418             kDebug() << "UMLObject::resolveRef: object with xmi.id=" << m_SecondaryId
00419                 << " not found, setting to undef" << endl;
00420             UMLFolder *datatypes = pDoc->getDatatypeFolder();
00421             m_pSecondary = Object_Factory::createUMLObject(Uml::ot_Datatype, "undef", datatypes, false);
00422             return true;
00423         }
00424         m_SecondaryFallback = m_SecondaryId;
00425     }
00426     if (m_SecondaryFallback.isEmpty()) {
00427         kError() << "UMLObject::resolveRef(" << m_Name
00428             << "): cannot find type with id "
00429             << m_SecondaryId << endl;
00430         return false;
00431     }
00432 #ifdef VERBOSE_DEBUGGING
00433     kDebug() << "UMLObject::resolveRef(" << m_Name
00434               << "): could not resolve secondary ID " << m_SecondaryId
00435               << ", using secondary fallback " << m_SecondaryFallback
00436               << endl;
00437 #endif
00438     m_SecondaryId = m_SecondaryFallback;
00439     // Assume we're dealing with the older Umbrello format where
00440     // the type name was saved in the "type" attribute rather
00441     // than the xmi.id of the model object of the attribute type.
00442     m_pSecondary = pDoc->findUMLObject( m_SecondaryId, Uml::ot_UMLObject, this );
00443     if (m_pSecondary) {
00444         m_SecondaryId = "";
00445         maybeSignalObjectCreated();
00446         return true;
00447     }
00448     // Work around Object_Factory::createUMLObject()'s incapability
00449     // of on-the-fly scope creation:
00450     if (m_SecondaryId.contains("::")) {
00451         // TODO: Merge Import_Utils::createUMLObject() into Object_Factory::createUMLObject()
00452         m_pSecondary = Import_Utils::createUMLObject(Uml::ot_UMLObject, m_SecondaryId, NULL);
00453         if (m_pSecondary) {
00454             if (Import_Utils::newUMLObjectWasCreated()) {
00455                 maybeSignalObjectCreated();
00456                 kapp->processEvents();
00457                 kDebug() << "UMLObject::resolveRef: Import_Utils::createUMLObject() "
00458                           << "created a new type for " << m_SecondaryId << endl;
00459             } else {
00460                 kDebug() << "UMLObject::resolveRef: Import_Utils::createUMLObject() "
00461                           << "returned an existing type for " << m_SecondaryId << endl;
00462             }
00463             m_SecondaryId = "";
00464             return true;
00465         }
00466         kError() << "UMLObject::resolveRef: Import_Utils::createUMLObject() "
00467                   << "failed to create a new type for " << m_SecondaryId << endl;
00468         return false;
00469     }
00470     kDebug() << "UMLObject::resolveRef: Creating new type for " << m_SecondaryId << endl;
00471     // This is very C++ specific - we rely on  some '*' or
00472     // '&' to decide it's a ref type. Plus, we don't recognize
00473     // typedefs of ref types.
00474     bool isReferenceType = ( m_SecondaryId.contains('*') ||
00475                              m_SecondaryId.contains('&') );
00476     Uml::Object_Type ot = Uml::ot_Class;
00477     if (isReferenceType) {
00478         ot = Uml::ot_Datatype;
00479     } else {
00480         if (Model_Utils::isCommonDataType(m_SecondaryId))
00481             ot = Uml::ot_Datatype;
00482     }
00483     m_pSecondary = Object_Factory::createUMLObject(ot, m_SecondaryId, NULL);
00484     if (m_pSecondary == NULL)
00485         return false;
00486     m_SecondaryId = "";
00487     maybeSignalObjectCreated();
00488     //kapp->processEvents();
00489     return true;
00490 }
00491 
00492 QDomElement UMLObject::save( const QString &tag, QDomDocument & qDoc ) {
00493     /*
00494       Call as the first action of saveToXMI() in child class:
00495       This creates the QDomElement with which to work.
00496     */
00497     QDomElement qElement = qDoc.createElement(tag);
00498     qElement.setAttribute( "isSpecification", "false" );
00499     if (m_BaseType != Uml::ot_Association &&
00500             m_BaseType != Uml::ot_Role &&
00501             m_BaseType != Uml::ot_Attribute) {
00502         qElement.setAttribute( "isLeaf", "false" );
00503         qElement.setAttribute( "isRoot", "false" );
00504         if (m_bAbstract)
00505             qElement.setAttribute( "isAbstract", "true" );
00506         else
00507             qElement.setAttribute( "isAbstract", "false" );
00508     }
00509     qElement.setAttribute( "xmi.id", ID2STR(m_nId) );
00510     qElement.setAttribute( "name", m_Name );
00511     if (m_BaseType != Uml::ot_Operation &&
00512             m_BaseType != Uml::ot_Role &&
00513             m_BaseType != Uml::ot_Attribute) {
00514         Uml::IDType nmSpc;
00515         if (m_pUMLPackage)
00516             nmSpc = m_pUMLPackage->getID();
00517         else
00518             nmSpc = UMLApp::app()->getDocument()->getModelID();
00519         qElement.setAttribute( "namespace", ID2STR(nmSpc) );
00520     }
00521     if (! m_Doc.isEmpty())
00522         qElement.setAttribute( "comment", m_Doc );  //CHECK: uml13.dtd compliance
00523 #ifdef XMI_FLAT_PACKAGES
00524     if (m_pUMLPackage)             //FIXME: uml13.dtd compliance
00525         qElement.setAttribute( "package", m_pUMLPackage->getID() );
00526 #endif
00527     QString visibility = m_Vis.toString(false);
00528     qElement.setAttribute( "visibility", visibility);
00529     if (m_pStereotype != NULL)
00530         qElement.setAttribute( "stereotype", ID2STR(m_pStereotype->getID()) );
00531     if (m_bStatic)
00532         qElement.setAttribute( "ownerScope", "classifier" );
00533     /* else
00534         qElement.setAttribute( "ownerScope", "instance" );
00535      *** ownerScope defaults to instance if not set **********/
00536     return qElement;
00537 }
00538 
00539 bool UMLObject::load( QDomElement& ) {
00540     // This body is not usually executed because child classes
00541     // overwrite the load method.
00542     return true;
00543 }
00544 
00545 bool UMLObject::loadFromXMI( QDomElement & element) {
00546     UMLDoc* umldoc = UMLApp::app()->getDocument();
00547     if (umldoc == NULL) {
00548         kError() << "UMLObject::loadFromXMI: umldoc is NULL" << endl;
00549         return false;
00550     }
00551     // Read the name first so that if we encounter a problem, the error
00552     // message can say the name.
00553     m_Name = element.attribute( "name", "" );
00554     QString id = element.attribute( "xmi.id", "" );
00555     if (id.isEmpty() || id == "-1") {
00556         if (m_BaseType == Uml::ot_Role) {
00557             // Before version 1.4, Umbrello did not save the xmi.id
00558             // of UMLRole objects.
00559             m_nId = UniqueID::gen();
00560         } else {
00561             kError() << "UMLObject::loadFromXMI(" << m_Name
00562             << "): nonexistent or illegal xmi.id" << endl;
00563             return false;
00564         }
00565     } else {
00566         m_nId = STR2ID(id);
00567     }
00568 
00569     if (element.hasAttribute("documentation"))  // for bkwd compat.
00570         m_Doc = element.attribute( "documentation", "" );
00571     else
00572         m_Doc = element.attribute( "comment", "" );  //CHECK: need a UML:Comment?
00573 
00574     m_Vis = Uml::Visibility::Public;
00575     if (element.hasAttribute("scope")) {        // for bkwd compat.
00576         QString scope = element.attribute( "scope", "" );
00577         if (scope == "instance_level")         // nsuml compat.
00578             m_bStatic = false;
00579         else if (scope == "classifier_level")  // nsuml compat.
00580             m_bStatic = true;
00581         else {
00582             int nScope = scope.toInt();
00583             if (nScope >= Uml::Visibility::Public && nScope <= Uml::Visibility::Protected)
00584               m_Vis = (Uml::Visibility::Value)nScope;
00585             else
00586                 kError() << "UMLObject::loadFromXMI(" << m_Name
00587                 << "): illegal scope" << endl;  // soft error
00588         }
00589     } else {
00590         QString visibility = element.attribute( "visibility", "public" );
00591         if (visibility == "private"
00592                 || visibility == "private_vis")    // for compatibility with other programs
00593               m_Vis = Uml::Visibility::Private;
00594         else if (visibility == "protected"
00595                        || visibility == "protected_vis")  // for compatibility with other programs
00596           m_Vis = Uml::Visibility::Protected;
00597         else if (visibility == "implementation")
00598           m_Vis = Uml::Visibility::Implementation;
00599     }
00600 
00601     QString stereo = element.attribute( "stereotype", "" );
00602     if (!stereo.isEmpty()) {
00603         Uml::IDType stereoID = STR2ID(stereo);
00604         m_pStereotype = umldoc->findStereotypeById(stereoID);
00605         if (m_pStereotype) {
00606             m_pStereotype->incrRefCount();
00607         } else {
00608             kDebug() << "UMLObject::loadFromXMI(" << m_Name << "): "
00609                 << "UMLStereotype " << ID2STR(stereoID)
00610                 << " not found, creating now." << endl;
00611             setStereotype(stereo);
00612         }
00613     }
00614 
00615     if( element.hasAttribute("abstract") ) {     // for bkwd compat.
00616         QString abstract = element.attribute( "abstract", "0" );
00617         m_bAbstract = (bool)abstract.toInt();
00618     } else {
00619         QString isAbstract = element.attribute( "isAbstract", "false" );
00620         m_bAbstract = (isAbstract == "true");
00621     }
00622 
00623     if( element.hasAttribute("static") ) {       // for bkwd compat.
00624         QString staticScope = element.attribute( "static", "0" );
00625         m_bStatic = (bool)staticScope.toInt();
00626     } else {
00627         QString ownerScope = element.attribute( "ownerScope", "instance" );
00628         m_bStatic = (ownerScope == "classifier");
00629     }
00630 
00631     // If the node has child nodes, check whether attributes can be
00632     // extracted from them.
00633     if (element.hasChildNodes()) {
00634         QDomNode node = element.firstChild();
00635         if (node.isComment())
00636             node = node.nextSibling();
00637         QDomElement elem = node.toElement();
00638         while( !elem.isNull() ) {
00639             QString tag = elem.tagName();
00640             if (Uml::tagEq(tag, "name")) {
00641                 m_Name = elem.attribute("xmi.value", "");
00642                 if (m_Name.isEmpty())
00643                     m_Name = elem.text();
00644             } else if (Uml::tagEq(tag, "visibility")) {
00645                 QString vis = elem.attribute("xmi.value", "");
00646                 if (vis.isEmpty())
00647                     vis = elem.text();
00648                 if (vis == "private" || vis == "private_vis")
00649                       m_Vis = Uml::Visibility::Private;
00650                 else if (vis == "protected" || vis == "protected_vis")
00651                   m_Vis = Uml::Visibility::Protected;
00652                 else if (vis == "implementation")
00653                   m_Vis = Uml::Visibility::Implementation;
00654             } else if (Uml::tagEq(tag, "isAbstract")) {
00655                 QString isAbstract = elem.attribute("xmi.value", "");
00656                 if (isAbstract.isEmpty())
00657                     isAbstract = elem.text();
00658                 m_bAbstract = (isAbstract == "true");
00659             } else if (Uml::tagEq(tag, "ownerScope")) {
00660                 QString ownerScope = elem.attribute("xmi.value", "");
00661                 if (ownerScope.isEmpty())
00662                     ownerScope = elem.text();
00663                 m_bStatic = (ownerScope == "classifier");
00664             } else if (Uml::tagEq(tag, "stereotype")) {
00665                 QString stereo = elem.attribute("xmi.value", "");
00666                 if (stereo.isEmpty() && elem.hasChildNodes()) {
00667                     /* like so:
00668                      <UML:ModelElement.stereotype>
00669                        <UML:Stereotype xmi.idref = '07CD'/>
00670                      </UML:ModelElement.stereotype>
00671                      */
00672                     QDomNode stereoNode = elem.firstChild();
00673                     QDomElement stereoElem = stereoNode.toElement();
00674                     tag = stereoElem.tagName();
00675                     if (Uml::tagEq(tag, "Stereotype")) {
00676                         stereo = stereoElem.attribute("xmi.idref", "");
00677                     }
00678                 }
00679                 if (! stereo.isEmpty()) {
00680                     Uml::IDType stereoID = STR2ID(stereo);
00681                     m_pStereotype = umldoc->findStereotypeById(stereoID);
00682                     if (m_pStereotype)
00683                         m_pStereotype->incrRefCount();
00684                     else
00685                         m_SecondaryId = stereo;  // leave it to resolveRef()
00686                 }
00687             }
00688             node = node.nextSibling();
00689             if (node.isComment())
00690                 node = node.nextSibling();
00691             elem = node.toElement();
00692         }
00693     }
00694 
00695     // Operations, attributes, enum literals, templates, stereotypes,
00696     // and association role objects get added and signaled elsewhere.
00697     if (m_BaseType != Uml::ot_Operation && m_BaseType != Uml::ot_Attribute &&
00698             m_BaseType != Uml::ot_EnumLiteral && m_BaseType != Uml::ot_EntityAttribute &&
00699             m_BaseType != Uml::ot_Template && m_BaseType != Uml::ot_Stereotype &&
00700             m_BaseType != Uml::ot_Role) {
00701         if (m_bInPaste) {
00702             m_pUMLPackage = NULL;  // forget any old parent
00703             UMLListView *listView = UMLApp::app()->getListView();
00704             UMLListViewItem *parentItem = (UMLListViewItem*)listView->currentItem();
00705             if (parentItem) {
00706                 Uml::ListView_Type lvt = parentItem->getType();
00707                 if (Model_Utils::typeIsContainer(lvt) ||
00708                         lvt == Uml::lvt_Class ||
00709                         lvt == Uml::lvt_Interface) {
00710                     UMLObject *o = parentItem->getUMLObject();
00711                     m_pUMLPackage = static_cast<UMLPackage*>( o );
00712                 }
00713             }
00714         }
00715         if (m_pUMLPackage) {
00716             m_pUMLPackage->addObject(this);
00717         } else if (umldoc->rootFolderType(this) == Uml::N_MODELTYPES) {
00718             // m_pUMLPackage is not set on the root folders.
00719             kDebug() << "UMLObject::loadFromXMI(" << m_Name << "): m_pUMLPackage is not set"
00720                 << endl;
00721         }
00722     }
00723     return load(element);
00724 }
00725 
00726 kdbgstream& operator<< (kdbgstream& s, const UMLObject& a) {
00727     s << a.getName();
00728     return s;
00729 }
00730 
00731 #include "umlobject.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:08:01 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003