예제 #1
0
bool UMLClipboard::pasteChildren(UMLListViewItem *parent, IDChangeLog *chgLog) {
    if (!parent) {
        kWarning() << "Paste Children Error, parent missing" << endl;
        return false;
    }
    UMLDoc *doc = UMLApp::app()->getDocument();
    UMLListView *listView = UMLApp::app()->getListView();
    UMLListViewItem *childItem = static_cast<UMLListViewItem*>(parent->firstChild());
    while (childItem) {
        Uml::IDType oldID = childItem->getID();
        Uml::IDType newID = chgLog->findNewID(oldID);
        UMLListViewItem *shouldNotExist = listView->findItem(newID);
        if (shouldNotExist) {
            kError() << "UMLClipboard::pasteChildren: new list view item " << ID2STR(newID)
            << " already exists (internal error)" << endl;
            childItem = static_cast<UMLListViewItem*>(childItem->nextSibling());
            continue;
        }
        UMLObject *newObj = doc->findObjectById(newID);
        if (newObj) {
            kDebug() << "UMLClipboard::pasteChildren: adjusting lvitem(" << ID2STR(oldID)
            << ") to new UMLObject(" << ID2STR(newID) << ")" << endl;
            childItem->setUMLObject(newObj);
            childItem->setText(newObj->getName());
        } else {
            kDebug() << "UMLClipboard::pasteChildren: no UMLObject found for lvitem "
            << ID2STR(newID) << endl;
        }
        childItem = static_cast<UMLListViewItem*>(childItem->nextSibling());
    }
    return true;
}
    UMLObject* CmdBaseObjectCommand::object()
    {
        UMLDoc *doc = UMLApp::app()->document();
        UMLObject *umlObject = doc->findObjectById(m_objectId);

        if (!umlObject)
            umlObject = m_object;

        return umlObject;
    }
예제 #3
0
/**
 * This method loads the generic parts of the XMI common to most model
 * classes.  It is not usually reimplemented by child classes.
 * Instead, it invokes the load() method which implements the loading
 * of the specifics of each child class.
 *
 * @param element   The QDomElement from which to load.
 */
bool UMLObject::loadFromXMI(QDomElement & element)
{
    UMLDoc* umldoc = UMLApp::app()->document();
    if (umldoc == 0) {
        uError() << "umldoc is NULL";
        return false;
    }
    // Read the name first so that if we encounter a problem, the error
    // message can say the name.
    m_name = element.attribute(QLatin1String("name"));
    QString id = Model_Utils::getXmiId(element);
    if (id.isEmpty() || id == QLatin1String("-1")) {
        // 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) {
            // Some older Umbrello versions had a problem with xmi.id's
            // of other objects being reused for the UMLRole, see e.g.
            // attachment 21179 at http://bugs.kde.org/147988 .
            // If the xmi.id is already being used then we generate a new one.
            UMLObject *o = umldoc->findObjectById(nId);
            if (o) {
                uError() << "loadFromXMI(UMLRole): id " << id
                         << " is already in use!!! Please fix your XMI file.";
            }
        }
        m_nId = nId;
    }

    if (element.hasAttribute(QLatin1String("documentation")))  // for bkwd compat.
        m_Doc = element.attribute(QLatin1String("documentation"));
    else
        m_Doc = element.attribute(QLatin1String("comment"));    //CHECK: need a UML:Comment?

    m_visibility = Uml::Visibility::Public;
    if (element.hasAttribute(QLatin1String("scope"))) {        // for bkwd compat.
        QString scope = element.attribute(QLatin1String("scope"));
        if (scope == QLatin1String("instance_level"))         // nsuml compat.
            m_bStatic = false;
        else if (scope == QLatin1String("classifier_level"))  // nsuml compat.
            m_bStatic = true;
        else {
            int nScope = scope.toInt();
            switch (nScope) {
            case 200:
                m_visibility = Uml::Visibility::Public;
                break;
            case 201:
                m_visibility = Uml::Visibility::Private;
                break;
            case 202:
                m_visibility = Uml::Visibility::Protected;
                break;
            default:
                uError() << m_name << ": illegal scope " << nScope;
            }
        }
    } else {
        QString visibility = element.attribute(QLatin1String("visibility"), QLatin1String("public"));
        if (visibility == QLatin1String("private")
                || visibility == QLatin1String("private_vis"))    // for compatibility with other programs
            m_visibility = Uml::Visibility::Private;
        else if (visibility == QLatin1String("protected")
                 || visibility == QLatin1String("protected_vis"))  // for compatibility with other programs
            m_visibility = Uml::Visibility::Protected;
        else if (visibility == QLatin1String("implementation"))
            m_visibility = Uml::Visibility::Implementation;
    }

    QString stereo = element.attribute(QLatin1String("stereotype"));
    if (!stereo.isEmpty()) {
        Uml::ID::Type stereoID = Uml::ID::fromString(stereo);
        m_pStereotype = umldoc->findStereotypeById(stereoID);
        if (m_pStereotype) {
            m_pStereotype->incrRefCount();
        } else {
            uDebug() << m_name << ": UMLStereotype " << Uml::ID::toString(stereoID)
                     << " not found, creating now.";
            setStereotypeCmd(stereo);
        }
    }

    if (element.hasAttribute(QLatin1String("abstract"))) {      // for bkwd compat.
        QString abstract = element.attribute(QLatin1String("abstract"), QLatin1String("0"));
        m_bAbstract = (bool)abstract.toInt();
    } else {
        QString isAbstract = element.attribute(QLatin1String("isAbstract"), QLatin1String("false"));
        m_bAbstract = (isAbstract == QLatin1String("true"));
    }

    if (element.hasAttribute(QLatin1String("static"))) {        // for bkwd compat.
        QString staticScope = element.attribute(QLatin1String("static"), QLatin1String("0"));
        m_bStatic = (bool)staticScope.toInt();
    } else {
        QString ownerScope = element.attribute(QLatin1String("ownerScope"), QLatin1String("instance"));
        m_bStatic = (ownerScope == QLatin1String("classifier"));
    }

    // If the node has child nodes, check whether attributes can be
    // extracted from them.
    if (element.hasChildNodes()) {
        QDomNode node = element.firstChild();
        if (node.isComment())
            node = node.nextSibling();
        QDomElement elem = node.toElement();
        while (!elem.isNull()) {
            QString tag = elem.tagName();
            if (UMLDoc::tagEq(tag, QLatin1String("name"))) {
                m_name = elem.attribute(QLatin1String("xmi.value"));
                if (m_name.isEmpty())
                    m_name = elem.text();
            } else if (UMLDoc::tagEq(tag, QLatin1String("visibility"))) {
                QString vis = elem.attribute(QLatin1String("xmi.value"));
                if (vis.isEmpty())
                    vis = elem.text();
                if (vis == QLatin1String("private") || vis == QLatin1String("private_vis"))
                    m_visibility = Uml::Visibility::Private;
                else if (vis == QLatin1String("protected") || vis == QLatin1String("protected_vis"))
                    m_visibility = Uml::Visibility::Protected;
                else if (vis == QLatin1String("implementation"))
                    m_visibility = Uml::Visibility::Implementation;
            } else if (UMLDoc::tagEq(tag, QLatin1String("isAbstract"))) {
                QString isAbstract = elem.attribute(QLatin1String("xmi.value"));
                if (isAbstract.isEmpty())
                    isAbstract = elem.text();
                m_bAbstract = (isAbstract == QLatin1String("true"));
            } else if (UMLDoc::tagEq(tag, QLatin1String("ownerScope"))) {
                QString ownerScope = elem.attribute(QLatin1String("xmi.value"));
                if (ownerScope.isEmpty())
                    ownerScope = elem.text();
                m_bStatic = (ownerScope == QLatin1String("classifier"));
            } else {
                loadStereotype(elem);
            }
            node = node.nextSibling();
            if (node.isComment())
                node = node.nextSibling();
            elem = node.toElement();
        }
    }

    // Operations, attributes, enum literals, templates, stereotypes,
    // and association role objects get added and signaled elsewhere.
    if (m_BaseType != ot_Operation && m_BaseType != ot_Attribute &&
        m_BaseType != ot_EnumLiteral && m_BaseType != ot_EntityAttribute &&
        m_BaseType != ot_Template && m_BaseType != ot_Stereotype &&
        m_BaseType != ot_Role && m_BaseType != ot_UniqueConstraint &&
        m_BaseType != ot_ForeignKeyConstraint && m_BaseType != ot_CheckConstraint) {
        if (m_pUMLPackage) {
            m_pUMLPackage->addObject(this);
        } else if (umldoc->rootFolderType(this) == Uml::ModelType::N_MODELTYPES) {
            // m_pUMLPackage is not set on the root folders.
            uDebug() << m_name << ": m_pUMLPackage is not set";
        }
    }
    return load(element);
}
예제 #4
0
/**
 * Resolve referenced objects (if any.)
 * Needs to be called after all UML objects are loaded from file.
 * This needs to be done after all model objects are loaded because
 * some of the xmi.id's might be forward references, i.e. they may
 * identify model objects which were not yet loaded at the point of
 * reference.
 * The default implementation attempts resolution of the m_SecondaryId.
 *
 * @return   True for success.
 */
bool UMLObject::resolveRef()
{
    if (m_pSecondary || (m_SecondaryId.isEmpty() && m_SecondaryFallback.isEmpty())) {
        maybeSignalObjectCreated();
        return true;
    }
#ifdef VERBOSE_DEBUGGING
    uDebug() << m_name << ": m_SecondaryId is " << m_SecondaryId;
#endif
    UMLDoc *pDoc = UMLApp::app()->document();
    // In the new, XMI standard compliant save format,
    // the type is the xmi.id of a UMLClassifier.
    if (! m_SecondaryId.isEmpty()) {
        m_pSecondary = pDoc->findObjectById(Uml::ID::fromString(m_SecondaryId));
        if (m_pSecondary != NULL) {
            if (m_pSecondary->baseType() == ot_Stereotype) {
                m_pStereotype = dynamic_cast<UMLStereotype*>(m_pSecondary.data());
                m_pStereotype->incrRefCount();
                m_pSecondary = NULL;
            }
            m_SecondaryId = QString();
            maybeSignalObjectCreated();
            return true;
        }
        if (m_SecondaryFallback.isEmpty()) {
            uDebug() << "object with xmi.id=" << m_SecondaryId << " not found, setting to undef";
            UMLFolder *datatypes = pDoc->datatypeFolder();
            m_pSecondary = Object_Factory::createUMLObject(ot_Datatype, QLatin1String("undef"), datatypes, false);
            return true;
        }
    }
    if (m_SecondaryFallback.isEmpty()) {
        uError() << m_name << ": cannot find type with id " << m_SecondaryId;
        return false;
    }
#ifdef VERBOSE_DEBUGGING
    uDebug() << m_name << ": could not resolve secondary ID " << m_SecondaryId
             << ", using secondary fallback " << m_SecondaryFallback;
#endif
    m_SecondaryId = m_SecondaryFallback;
    // Assume we're dealing with the older Umbrello format where
    // the type name was saved in the "type" attribute rather
    // than the xmi.id of the model object of the attribute type.
    m_pSecondary = pDoc->findUMLObject(m_SecondaryId, ot_UMLObject, this);
    if (m_pSecondary) {
        m_SecondaryId = QString();
        maybeSignalObjectCreated();
        return true;
    }
    // Work around Object_Factory::createUMLObject()'s incapability
    // of on-the-fly scope creation:
    if (m_SecondaryId.contains(QLatin1String("::"))) {
        // TODO: Merge Import_Utils::createUMLObject() into Object_Factory::createUMLObject()
        m_pSecondary = Import_Utils::createUMLObject(ot_UMLObject, m_SecondaryId, m_pUMLPackage);
        if (m_pSecondary) {
            if (Import_Utils::newUMLObjectWasCreated()) {
                maybeSignalObjectCreated();
                qApp->processEvents();
                uDebug() << "Import_Utils::createUMLObject() created a new type for "
                         << m_SecondaryId;
            } else {
                uDebug() << "Import_Utils::createUMLObject() returned an existing type for "
                         << m_SecondaryId;
            }
            m_SecondaryId = QString();
            return true;
        }
        uError() << "Import_Utils::createUMLObject() failed to create a new type for "
                 << m_SecondaryId;
        return false;
    }
    uDebug() << "Creating new type for " << m_SecondaryId;
    // This is very C++ specific - we rely on  some '*' or
    // '&' to decide it's a ref type. Plus, we don't recognize
    // typedefs of ref types.
    bool isReferenceType = (m_SecondaryId.contains(QLatin1Char('*')) ||
                            m_SecondaryId.contains(QLatin1Char('&')));
    ObjectType ot = ot_Class;
    if (isReferenceType) {
        ot = ot_Datatype;
    } else {
        if (Model_Utils::isCommonDataType(m_SecondaryId))
            ot = ot_Datatype;
    }
    m_pSecondary = Object_Factory::createUMLObject(ot, m_SecondaryId, NULL);
    if (m_pSecondary == NULL)
        return false;
    m_SecondaryId = QString();
    maybeSignalObjectCreated();
    //qApp->processEvents();
    return true;
}
예제 #5
0
/**
 * Creates the <UML:Generalization> or <UML:Association> XMI element
 * including its role objects.
 */
bool UMLAssociation::load( QDomElement & element )
{
    if (id() == Uml::id_None)
        return false; // old style XMI file. No real info in this association.

    UMLDoc * doc = UMLApp::app()->document();
    UMLObject * obj[2] = { NULL, NULL };
    if (m_AssocType == Uml::AssociationType::Generalization ||
        m_AssocType == Uml::AssociationType::Realization    ||
        m_AssocType == Uml::AssociationType::Dependency     ||
        m_AssocType == Uml::AssociationType::Child2Category ||
        m_AssocType == Uml::AssociationType::Category2Parent
        ) {
        for (unsigned r = Uml::A; r <= Uml::B; ++r) {
            const QString fetch = (m_AssocType == Uml::AssociationType::Generalization ?
                                   r == Uml::A ? "child" : "parent"
                       : r == Uml::A ? "client" : "supplier");
            QString roleIdStr = element.attribute(fetch, "");
            if (roleIdStr.isEmpty()) {
                // Might be given as a child node instead - see below.
                continue;
            }

            // set umlobject of role if possible (else defer resolution)
            obj[r] = doc->findObjectById(STR2ID(roleIdStr));
            Uml::Role_Type role = (Uml::Role_Type)r;
            if (obj[r] == NULL) {
                m_pRole[role]->setSecondaryId(roleIdStr);  // defer to resolveRef()
            } else {
                m_pRole[role]->setObject(obj[r]);
                if (m_pUMLPackage == NULL) {
                    Uml::ModelType mt = Model_Utils::convert_OT_MT(obj[r]->baseType());
                    m_pUMLPackage = doc->rootFolder(mt);
                    uDebug() << "assoctype " << m_AssocType
                        << ": setting model type " << mt;
                }
            }
        }
        if (obj[A] == NULL || obj[B] == NULL) {
            for (QDomNode node = element.firstChild(); !node.isNull();
                    node = node.nextSibling()) {
                if (node.isComment())
                    continue;
                QDomElement tempElement = node.toElement();
                QString tag = tempElement.tagName();
                if (Model_Utils::isCommonXMIAttribute(tag))
                    continue;
                // Permitted tag names:
                //  roleA: "child" "subtype" "client"
                //  roleB: "parent" "supertype" "supplier"
                QString idStr = tempElement.attribute( "xmi.id", "" );
                if (idStr.isEmpty())
                    idStr = tempElement.attribute( "xmi.idref", "" );
                if (idStr.isEmpty()) {
                    QDomNode inner = node.firstChild();
                    QDomElement tmpElem = inner.toElement();
                    idStr = tmpElem.attribute( "xmi.id", "" );
                    if (idStr.isEmpty())
                        idStr = tmpElem.attribute( "xmi.idref", "" );
                }
                if (idStr.isEmpty()) {
                    uError() << "type " << m_AssocType
                        << ", id " << ID2STR(id()) << ": "
                        << "xmi id not given for " << tag;
                    continue;
                }
                // Since we know for sure that we're dealing with a non
                // umbrello file, use deferred resolution unconditionally.
                if (UMLDoc::tagEq(tag, "child") || UMLDoc::tagEq(tag, "subtype") || UMLDoc::tagEq(tag, "client")) {
                    getUMLRole(A)->setSecondaryId(idStr);
                } else {
                    getUMLRole(B)->setSecondaryId(idStr);
                }
            }
        }

        // it is a realization if either endpoint is an interface
        if (isRealization(obj[A], obj[B])) {
            m_AssocType = Uml::AssociationType::Realization;
        }
        return true;
    }

    for (QDomNode node = element.firstChild(); !node.isNull();
            node = node.nextSibling()) {
        // uml13.dtd compliant format (new style)
        if (node.isComment())
            continue;
        QDomElement tempElement = node.toElement();
        QString tag = tempElement.tagName();
        if (Model_Utils::isCommonXMIAttribute(tag))
            continue;
        if (!UMLDoc::tagEq(tag, "Association.connection") &&
                !UMLDoc::tagEq(tag, "Namespace.ownedElement") &&
                !UMLDoc::tagEq(tag, "Namespace.contents")) {
            uWarning() << "unknown child node " << tag;
            continue;
        }
        // Load role A.
        node = tempElement.firstChild();
        while (node.isComment())
            node = node.nextSibling();
        tempElement = node.toElement();
        if (tempElement.isNull()) {
            uWarning() << "UML:Association : element (A) is Null";
            return false;
        }
        tag = tempElement.tagName();
        if (!UMLDoc::tagEq(tag, "AssociationEndRole") &&
                !UMLDoc::tagEq(tag, "AssociationEnd")) {
            uWarning() << "unknown child (A) tag " << tag;
            return false;
        }
        if (! getUMLRole(A)->loadFromXMI(tempElement))
            return false;
        // Load role B.
        node = node.nextSibling();
        while (node.isComment())
            node = node.nextSibling();
        tempElement = node.toElement();
        if (tempElement.isNull()) {
            uWarning() << "UML:Association : element (B) is Null";
            return false;
        }
        tag = tempElement.tagName();
        if (!UMLDoc::tagEq(tag, "AssociationEndRole") &&
                !UMLDoc::tagEq(tag, "AssociationEnd")) {
            uWarning() << "unknown child (B) tag " << tag;
            return false;
        }
        if (! getUMLRole(B)->loadFromXMI(tempElement))
            return false;

        if (m_pUMLPackage == NULL) {
            Uml::ModelType mt = Model_Utils::convert_OT_MT(getObject(B)->baseType());
            m_pUMLPackage = doc->rootFolder(mt);
            uDebug() << "setting model type " << mt;
        }

        // setting the association type:
        //
        // In the old days, we could just record this on the association,
        // and be done with it. But thats not how the UML13.dtd does things.
        // As a result, we are checking roleA for information about the
        // parent association (!) which by this point in the parse, should
        // be set. However, the information that the roles are allowed to have
        // is not complete, so we need to finish the analysis here.

        // find self-associations
        if (m_AssocType == Uml::AssociationType::Association && getObjectId(A) == getObjectId(B))
            m_AssocType = Uml::AssociationType::Association_Self;

        // fall-back default type
        if (m_AssocType == Uml::AssociationType::Unknown) {
            m_AssocType = Uml::AssociationType::Association;
        }

        return true;
    }

    // From here on it's old-style stuff.
    QString assocTypeStr = element.attribute( "assoctype", "-1" );
    Uml::AssociationType assocType = Uml::AssociationType::Unknown;
    if (assocTypeStr[0] >= 'a' && assocTypeStr[0] <= 'z') {
        // In an earlier version, the natural assoctype names were saved.
        const QString assocTypeString[] = {
                    "generalization",   // Uml::AssociationType::Generalization
                    "aggregation",      // Uml::AssociationType::Aggregation
                    "dependency",       // Uml::AssociationType::Dependency
                    "association",      // Uml::AssociationType::Association
                    "associationself",  // Uml::AssociationType::Association_Self
                    "collmessage",      // Uml::AssociationType::Coll_Message
                    "seqmessage",       // Uml::AssociationType::Seq_Message
                    "collmessageself",  // Uml::AssociationType::Coll_Message_Self
                    "seqmessageself",   // Uml::AssociationType::Seq_Message_Self
                    "implementation",   // Uml::AssociationType::Implementation
                    "composition",      // Uml::AssociationType::Composition
                    "realization",      // Uml::AssociationType::Realization
                    "uniassociation",   // Uml::AssociationType::UniAssociation
                    "anchor",           // Uml::AssociationType::Anchor
                    "state",            // Uml::AssociationType::State
                    "activity",         // Uml::AssociationType::Activity
                    "exception",        // Uml::AssociationType::Exception
                    "category2parent"   // Uml::AssociationType::Category2Parent
                    "child2category"    // Uml::AssociationType::Child2Category
                    "relationship"      // Uml::AssociationType::Relationship
        };
        const int arraySize = sizeof(assocTypeString)/sizeof(QString);
        uDebug() << "AssociationType string array size = " << arraySize;

        int index;
        for (index = 0; index < arraySize; ++index)
            if (assocTypeStr == assocTypeString[index])
                break;
        if (index < arraySize)
            assocType = Uml::AssociationType::Value(index);
    } else {
        int assocTypeNum = assocTypeStr.toInt();
        if (assocTypeNum < (int)Uml::AssociationType::Generalization ||   // first enum
            assocTypeNum > (int)Uml::AssociationType::Relationship) {     // last enum
            uWarning() << "bad assoctype of UML:AssociationType " << ID2STR(id());
            return false;
        }
        assocType = Uml::AssociationType::Value(assocTypeNum);
    }
    setAssociationType( assocType );

    Uml::IDType roleAObjID = STR2ID(element.attribute( "rolea", "-1" ));
    Uml::IDType roleBObjID = STR2ID(element.attribute( "roleb", "-1" ));
    if (assocType == Uml::AssociationType::Aggregation ||
        assocType == Uml::AssociationType::Composition) {
        // Flip roles to compensate for changed diamond logic in AssociationLine.
        // For further explanations see AssociationWidget::loadFromXMI.
        Uml::IDType tmp = roleAObjID;
        roleAObjID = roleBObjID;
        roleBObjID = tmp;
    }

    UMLObject * objA = doc->findObjectById(roleAObjID);
    UMLObject * objB = doc->findObjectById(roleBObjID);

    if(objA)
        getUMLRole(A)->setObject(objA);
    else
        return false;

    if(objB)
        getUMLRole(B)->setObject(objB);
    else
        return false;

    setMulti(element.attribute( "multia", "" ), A);
    setMulti(element.attribute( "multib", "" ), B);

    setRoleName(element.attribute( "namea", "" ), A);
    setRoleName(element.attribute( "nameb", "" ), B);

    setRoleDoc(element.attribute( "doca", "" ), A);
    setRoleDoc(element.attribute( "docb", "" ), B);

    // Visibility defaults to Public if it cant set it here..
    QString visibilityA = element.attribute( "visibilitya", "0");
    QString visibilityB = element.attribute( "visibilityb", "0");
    int vis = visibilityA.toInt();
    if (vis >= 200)  // bkwd compat.
        vis -= 200;
    setVisibility((Uml::Visibility::Value)vis, A);
    vis = visibilityB.toInt();
    if (vis >= 200)  // bkwd compat.
        vis -= 200;
    setVisibility((Uml::Visibility::Value)vis, B);

    // Changeability defaults to Changeable if it cant set it here..
    QString changeabilityA = element.attribute( "changeabilitya", "0");
    QString changeabilityB = element.attribute( "changeabilityb", "0");
    if (changeabilityA.toInt() > 0)
        setChangeability(Uml::Changeability(Uml::Changeability::Value(changeabilityA.toInt())), A);
    if (changeabilityB.toInt() > 0)
        setChangeability(Uml::Changeability(Uml::Changeability::Value(changeabilityB.toInt())), B);

    return true;
}
예제 #6
0
파일: umlrole.cpp 프로젝트: KDE/umbrello
/**
 * Loads the <UML:AssociationEnd> XMI element.
 * Auxiliary to UMLObject::loadFromXMI.
 */
bool UMLRole::load(QDomElement & element)
{
    UMLDoc * doc = UMLApp::app()->document();
    QString type = element.attribute(QLatin1String("type"));
    if (!type.isEmpty()) {
        if (!m_SecondaryId.isEmpty())
            uWarning() << "overwriting old m_SecondaryId \"" << m_SecondaryId
                << " with new value \"" << type << "\"";
        m_SecondaryId = type;
    }
    // Inspect child nodes - for multiplicity (and type if not set above.)
    for (QDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling()) {
        if (node.isComment())
            continue;
        QDomElement tempElement = node.toElement();
        QString tag = tempElement.tagName();
        if (UMLDoc::tagEq(tag, QLatin1String("name"))) {
            m_name = tempElement.text();
        } else if (UMLDoc::tagEq(tag, QLatin1String("AssociationEnd.multiplicity"))) {
            /*
             * There are different ways in which the multiplicity might be given:
             *  - direct value in the <AssociationEnd.multiplicity> tag,
             *  - attributes "lower" and "upper" of a subordinate <MultiplicityRange>,
             *  - direct value in subordinate <MultiplicityRange.lower> and
             *    <MultiplicityRange.upper> tags
             */
            QDomNode n = tempElement.firstChild();
            if (node.isNull() || tempElement.isNull() || n.isNull() ||
                    n.toElement().isNull()) {
                m_Multi = tempElement.text().trimmed();
                continue;
            }
            tempElement = n.toElement();
            tag = tempElement.tagName();
            if (!UMLDoc::tagEq(tag, QLatin1String("Multiplicity"))) {
                m_Multi = tempElement.text().trimmed();
                continue;
            }
            n = tempElement.firstChild();
            tempElement = n.toElement();
            tag = tempElement.tagName();
            if (!UMLDoc::tagEq(tag, QLatin1String("Multiplicity.range"))) {
                m_Multi = tempElement.text().trimmed();
                continue;
            }
            n = tempElement.firstChild();
            tempElement = n.toElement();
            tag = tempElement.tagName();
            if (!UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange"))) {
                m_Multi = tempElement.text().trimmed();
                continue;
            }
            QString multiUpper;
            if (tempElement.hasAttribute(QLatin1String("lower"))) {
                m_Multi = tempElement.attribute(QLatin1String("lower"));
                multiUpper = tempElement.attribute(QLatin1String("upper"));
                if (!multiUpper.isEmpty()) {
                    if (!m_Multi.isEmpty())
                        m_Multi.append(QLatin1String(".."));
                    m_Multi.append(multiUpper);
                }
                continue;
            }
            n = tempElement.firstChild();
            while (!n.isNull()) {
                tempElement = n.toElement();
                tag = tempElement.tagName();
                if (UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange.lower"))) {
                    m_Multi = tempElement.text();
                } else if (UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange.upper"))) {
                    multiUpper = tempElement.text();
                }
                n = n.nextSibling();
            }
            if (!multiUpper.isEmpty()) {
                if (!m_Multi.isEmpty())
                    m_Multi.append(QLatin1String(".."));
                m_Multi.append(multiUpper);
            }
        } else if (m_SecondaryId.isEmpty() &&
                   (UMLDoc::tagEq(tag, QLatin1String("type")) ||
                    UMLDoc::tagEq(tag, QLatin1String("participant")))) {
            m_SecondaryId = tempElement.attribute(QLatin1String("xmi.id"));
            if (m_SecondaryId.isEmpty())
                m_SecondaryId = tempElement.attribute(QLatin1String("xmi.idref"));
            if (m_SecondaryId.isEmpty()) {
                QDomNode inner = tempElement.firstChild();
                QDomElement innerElem = inner.toElement();
                m_SecondaryId = innerElem.attribute(QLatin1String("xmi.id"));
                if (m_SecondaryId.isEmpty())
                    m_SecondaryId = innerElem.attribute(QLatin1String("xmi.idref"));
            }
        }
    }
    if (!m_Multi.isEmpty())
        uDebug() << name() << ": m_Multi is " << m_Multi;
    if (m_SecondaryId.isEmpty()) {
        uError() << name() << ": type not given or illegal";
        return false;
    }
    UMLObject * obj;
    obj = doc->findObjectById(Uml::ID::fromString(m_SecondaryId));
    if (obj) {
        m_pSecondary = obj;
        m_SecondaryId = QString();
    }

    // block signals to prevent needless updating
    blockSignals(true);
    // Here comes the handling of the association type.
    // This is open for discussion - I'm pretty sure there are better ways..

    // Yeah, for one, setting the *parent* object parameters from here is sucky
    // as hell. Why are we using roleA to store what is essentially a parent (association)
    // parameter, eh? The UML13.dtd is pretty silly, but since that is what
    // is driving us to that point, we have to go with it. Some analysis of
    // the component roles/linked items needs to be done in order to get things
    // right. *sigh* -b.t.

    // Setting association type from the role (A)
    // Determination of the "aggregation" attribute used to be done only
    // when (m_role == Uml::RoleType::A) but some XMI writers (e.g. StarUML) place
    // the aggregation attribute at role B.
    // The role end with the aggregation unequal to "none" wins.
    QString aggregation = element.attribute(QLatin1String("aggregation"), QLatin1String("none"));
    if (aggregation == QLatin1String("composite"))
        m_pAssoc->setAssociationType(Uml::AssociationType::Composition);
    else if (aggregation == QLatin1String("shared")       // UML1.3
          || aggregation == QLatin1String("aggregate"))   // UML1.4
        m_pAssoc->setAssociationType(Uml::AssociationType::Aggregation);

    if (!element.hasAttribute(QLatin1String("isNavigable"))) {
        // Backward compatibility mode: In Umbrello version 1.3.x the
        // logic for saving the isNavigable flag was wrong.
        // May happen on loading role A.
        m_pAssoc->setOldLoadMode(true);
    } else if (m_pAssoc->getOldLoadMode() == true) {
        // Here is the original logic:
        // "Role B:
        //  If isNavigable is not given, we make no change to the
        //  association type.
        //  If isNavigable is given, and is "true", then we assume that
        //  the association's other end (role A) is not navigable, and
        //  therefore we change the association type to UniAssociation.
        //  The case that isNavigable is given as "false" is ignored.
        //  Combined with the association type logic for role A, this
        //  allows us to support at_Association and at_UniAssociation."
        if (element.attribute(QLatin1String("isNavigable")) == QLatin1String("true"))
            m_pAssoc->setAssociationType(Uml::AssociationType::UniAssociation);
    } else if (element.attribute(QLatin1String("isNavigable")) == QLatin1String("false")) {
        m_pAssoc->setAssociationType(Uml::AssociationType::UniAssociation);
    }

    //FIXME not standard XMI
    if (element.hasAttribute(QLatin1String("relationship"))) {
        if (element.attribute(QLatin1String("relationship")) == QLatin1String("true")) {
            m_pAssoc->setAssociationType(Uml::AssociationType::Relationship);
        }
    }

    if (m_Multi.isEmpty())
        m_Multi = element.attribute(QLatin1String("multiplicity"));

    // Changeability defaults to Changeable if it cant set it here..
    m_Changeability = Uml::Changeability::Changeable;
    QString changeability = element.attribute(QLatin1String("changeability"));
    if (changeability.isEmpty())
        element.attribute(QLatin1String("changeable"));  // for backward compatibility
    if (changeability == QLatin1String("frozen"))
        m_Changeability = Uml::Changeability::Frozen;
    else if (changeability == QLatin1String("addOnly"))
        m_Changeability = Uml::Changeability::AddOnly;

    // finished config, now unblock
    blockSignals(false);
    return true;
}
예제 #7
0
UMLWidget* makeWidgetFromXMI(const QString& tag,
                             const QString& idStr, UMLView *view)
{
    UMLWidget *widget = NULL;

        // Loading of widgets which do NOT represent any UMLObject,
        // just graphic stuff with no real model information
        //FIXME while boxes and texts are just diagram objects, activities and
        // states should be UMLObjects
    if (tag == "statewidget" || tag == "UML:StateWidget") {
        widget = new StateWidget(view, StateWidget::Normal, Uml::id_Reserved);
    } else if (tag == "notewidget" || tag == "UML:NoteWidget") {
        widget = new NoteWidget(view, NoteWidget::Normal, Uml::id_Reserved);
    } else if (tag == "boxwidget") {
        widget = new BoxWidget(view, Uml::id_Reserved);
    } else if (tag == "floatingtext" || tag == "UML:FloatingTextWidget") {
        widget = new FloatingTextWidget(view, Uml::tr_Floating, "", Uml::id_Reserved);
    } else if (tag == "activitywidget" || tag == "UML:ActivityWidget") {
        widget = new ActivityWidget(view, ActivityWidget::Initial, Uml::id_Reserved);
    } else if (tag == "messagewidget") {
        widget = new MessageWidget(view, Uml::sequence_message_asynchronous, Uml::id_Reserved);
    } else if (tag == "forkjoin") {
        widget = new ForkJoinWidget(view, false, Uml::id_Reserved);
    } else if (tag == "preconditionwidget") {
        widget = new PreconditionWidget(view, NULL, Uml::id_Reserved);
    } else if (tag == "combinedFragmentwidget") {
        widget = new CombinedFragmentWidget(view, CombinedFragmentWidget::Ref, Uml::id_Reserved);
    } else if (tag == "signalwidget") {
        widget = new SignalWidget(view, SignalWidget::Send,  Uml::id_Reserved);
    } else if (tag == "floatingdashlinewidget") {
        widget = new FloatingDashLineWidget(view, Uml::id_Reserved);
    } else if (tag == "objectnodewidget") {
        widget = new ObjectNodeWidget(view, ObjectNodeWidget::Normal, Uml::id_Reserved);
    } else if (tag == "regionwidget") {
        widget = new RegionWidget(view, Uml::id_Reserved);
    } else if (tag == "pinwidget") {
        widget = new PinWidget(view, NULL, Uml::id_Reserved);
    }
    else
    {
        // Loading of widgets which represent an UMLObject

        // Find the UMLObject and create the Widget to represent it
        Uml::IDType id = STR2ID(idStr);
        UMLDoc *umldoc = UMLApp::app()->document();
        UMLObject *o = umldoc->findObjectById(id);
        if (o == NULL) {
            uDebug() << "makeWidgetFromXMI: cannot find object with id "
                << ID2STR(id) << endl;
        }

        if (tag == "actorwidget" || tag == "UML:ActorWidget") {
            if (validateObjType(Uml::ot_Actor, o, id))
                widget = new ActorWidget(view, static_cast<UMLActor*>(o));
        } else if (tag == "usecasewidget" || tag ==  "UML:UseCaseWidget") {
            if (validateObjType(Uml::ot_UseCase, o, id))
                widget = new UseCaseWidget(view, static_cast<UMLUseCase*>(o));
        } else if (tag == "classwidget" || tag == "UML:ClassWidget") {
            if (validateObjType(Uml::ot_Class, o, id))
                widget = new ClassifierWidget(view, static_cast<UMLClassifier*>(o));
        } else if (tag == "packagewidget") {
            if (validateObjType(Uml::ot_Package, o, id))
                widget = new PackageWidget(view, static_cast<UMLPackage*>(o));
        } else if (tag == "componentwidget") {
            if (validateObjType(Uml::ot_Component, o, id))
                widget = new ComponentWidget(view, static_cast<UMLComponent*>(o));
        } else if (tag == "nodewidget") {
            if (validateObjType(Uml::ot_Node, o, id))
                widget = new NodeWidget(view, static_cast<UMLNode*>(o));
        } else if (tag == "artifactwidget") {
            if (validateObjType(Uml::ot_Artifact, o, id))
                widget = new ArtifactWidget(view, static_cast<UMLArtifact*>(o));
        } else if (tag == "interfacewidget") {
            if (validateObjType(Uml::ot_Interface, o, id))
                widget = new ClassifierWidget(view, static_cast<UMLClassifier*>(o));
        } else if (tag == "datatypewidget") {
            if (validateObjType(Uml::ot_Datatype, o, id))
                widget = new DatatypeWidget(view, static_cast<UMLClassifier*>(o));
        } else if (tag == "enumwidget") {
            if (validateObjType(Uml::ot_Enum, o, id))
                widget = new EnumWidget(view, static_cast<UMLEnum*>(o));
        } else if (tag == "entitywidget") {
            if (validateObjType(Uml::ot_Entity, o, id))
                widget = new EntityWidget(view, static_cast<UMLEntity*>(o));
        } else if (tag == "categorywidget") {
            if (validateObjType(Uml::ot_Category, o, id))
                widget = new CategoryWidget(view, static_cast<UMLCategory*>(o));
        } else if (tag == "objectwidget" || tag == "UML:ObjectWidget") {
            widget = new ObjectWidget(view, o );
        } else {
            uWarning() << "Trying to create an unknown widget:" << tag;
        }
    }
    return widget;

}