diff options
-rw-r--r-- | examples/uml/duse-mt/src/app/example3.xmi | 40 | ||||
-rw-r--r-- | src/uml/qumlport.cpp | 56 | ||||
-rw-r--r-- | src/uml/qumlport.h | 6 | ||||
-rw-r--r-- | tests/auto/auto.pro | 2 | ||||
-rw-r--r-- | tests/auto/qtumlprovidedrequiredinterfaces/qtumlprovidedrequiredinterfaces.pro | 7 | ||||
-rw-r--r-- | tests/auto/qtumlprovidedrequiredinterfaces/test.xmi | 40 | ||||
-rw-r--r-- | tests/auto/qtumlprovidedrequiredinterfaces/tst_qtumlprovidedrequiredinterfaces.cpp | 92 |
7 files changed, 232 insertions, 11 deletions
diff --git a/examples/uml/duse-mt/src/app/example3.xmi b/examples/uml/duse-mt/src/app/example3.xmi index 1f75c494..901e7345 100644 --- a/examples/uml/duse-mt/src/app/example3.xmi +++ b/examples/uml/duse-mt/src/app/example3.xmi @@ -1,12 +1,40 @@ <?xml version="1.0" encoding="UTF-8"?> <xmi:XMI xmlns:xmi="http://www.omg.org/spec/XMI/20110701" xmlns:uml="http://www.omg.org/spec/UML/20110701"> <uml:Model xmi:id="_kk-nYE_cEeOrf6v5LQGc0Q" name="project2"> - <packagedElement xmi:type="uml:Node" xmi:id="_kk-nZE_cEeOrf6v5LQGc0Q" name="Node"/> - <packagedElement xmi:type="uml:Component" xmi:id="_kk-nZU_cEeOrf6v5LQGc0Q" name="WebServer"> - <ownedAttribute xmi:type="uml:Port" xmi:id="_kk-nZk_cEeOrf6v5LQGc0Q" name="monitorablePort" type="_kk-naU_cEeOrf6v5LQGc0Q"/> - <ownedAttribute xmi:type="uml:Port" xmi:id="_kk-nZ0_cEeOrf6v5LQGc0Q" name="controllablePort" type="_kk-naE_cEeOrf6v5LQGc0Q"/> + <packagedElement xmi:type="uml:Node" xmi:id="_g59JVE_rEeOrf6v5LQGc0Q" name="Node"/> + <packagedElement xmi:type="uml:Component" xmi:id="_g59JVU_rEeOrf6v5LQGc0Q" name="WebServer"> + <ownedAttribute xmi:type="uml:Port" xmi:id="_g59JVk_rEeOrf6v5LQGc0Q" name="monitorablePort" type="_g59JWk_rEeOrf6v5LQGc0Q"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_g59JV0_rEeOrf6v5LQGc0Q" name="controllablePort" type="_g59JWU_rEeOrf6v5LQGc0Q"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_g59JWE_rEeOrf6v5LQGc0Q" name="classTypedPort" type="_g59JW0_rEeOrf6v5LQGc0Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWU_rEeOrf6v5LQGc0Q" name="IMaxClientsControl" isAbstract="true"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWk_rEeOrf6v5LQGc0Q" name="IAvgResponseTimeMonitor" isAbstract="true"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWU_rEeOrf6v5LQGc0R" name="IBaseProvidedInterface" isAbstract="true"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWk_rEeOrf6v5LQGc0R" name="IBaseRequiredInterface" isAbstract="true"/> + <packagedElement xmi:type="uml:Class" xmi:id="_g59JW0_rEeOrf6v5LQGc0Q" name="MaxClientsControl"> + <generalization xmi:type="uml:Generalization" xmi:id="_g59JW0_rEeOrf6v5LQGc0S" general="_g59JW0_rEeOrf6v5LQGc0R"/> + <clientDependency href="_g59JXU_rEeOrf6v5LQGc0Q"/> + <clientDependency href="_g59JXE_rEeOrf6v5LQGc0Q"/> + <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_g59JXE_rEeOrf6v5LQGc0Q" name="MaxClientsControl-IMaxClientsControl-Realization" contract="_g59JWU_rEeOrf6v5LQGc0Q"> + <supplier href="_g59JWU_rEeOrf6v5LQGc0Q"/> + <client href="_g59JW0_rEeOrf6v5LQGc0Q"/> + </interfaceRealization> + </packagedElement> + <packagedElement xmi:type="uml:Dependency" xmi:id="_g59JXU_rEeOrf6v5LQGc0Q" name="MaxClientsControl-IAvgResponseTimeMonitor-Dependency"> + <supplier href="_g59JWk_rEeOrf6v5LQGc0Q"/> + <client href="_g59JW0_rEeOrf6v5LQGc0Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_g59JW0_rEeOrf6v5LQGc0R" name="BaseClass"> + <clientDependency href="_g59JXU_rEeOrf6v5LQGc0R"/> + <clientDependency href="_g59JXE_rEeOrf6v5LQGc0R"/> + <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_g59JXE_rEeOrf6v5LQGc0R" name="BaseClass-IBaseProvidedInterface-Realization" contract="_g59JWU_rEeOrf6v5LQGc0R"> + <supplier href="_g59JWU_rEeOrf6v5LQGc0R"/> + <client href="_g59JW0_rEeOrf6v5LQGc0R"/> + </interfaceRealization> + </packagedElement> + <packagedElement xmi:type="uml:Dependency" xmi:id="_g59JXU_rEeOrf6v5LQGc0R" name="BaseClass-IBaseRequiredInterface-Dependency"> + <supplier href="_g59JWk_rEeOrf6v5LQGc0R"/> + <client href="_g59JW0_rEeOrf6v5LQGc0R"/> </packagedElement> - <packagedElement xmi:type="uml:Interface" xmi:id="_kk-naE_cEeOrf6v5LQGc0Q" name="IMaxClientsControl" isAbstract="true"/> - <packagedElement xmi:type="uml:Interface" xmi:id="_kk-naU_cEeOrf6v5LQGc0Q" name="IAvgResponseTimeMonitor" isAbstract="true"/> </uml:Model> </xmi:XMI> diff --git a/src/uml/qumlport.cpp b/src/uml/qumlport.cpp index 98d5331d..6d2812b6 100644 --- a/src/uml/qumlport.cpp +++ b/src/uml/qumlport.cpp @@ -66,6 +66,9 @@ #include <QtUml/QUmlType> #include <QtUml/QUmlValueSpecification> +#include <QtUml/QUmlGeneralization> +#include <QtUml/QUmlInterfaceRealization> + QT_BEGIN_NAMESPACE /*! @@ -238,9 +241,20 @@ const QSet<QUmlInterface *> QUmlPort::provided() const { // This is a read-only derived association end - qWarning("QUmlPort::provided(): to be implemented (this is a derived association end)"); + QSet<QUmlInterface *> provided_; + if (!_isConjugated) { + if (QUmlInterface *interface = dynamic_cast<QUmlInterface *>(_type)) { + provided_.insert(interface); + } + else { + collectRealizedInterfaces(dynamic_cast<QUmlBehavioredClassifier *>(_type), provided_); + } + } + else { + collectUsedInterfaces(dynamic_cast<QUmlBehavioredClassifier *>(_type), provided_); + } - return QSet<QUmlInterface *>(); + return provided_; } void QUmlPort::addProvided(QUmlInterface *provided) @@ -310,9 +324,20 @@ const QSet<QUmlInterface *> QUmlPort::required() const { // This is a read-only derived association end - qWarning("QUmlPort::required(): to be implemented (this is a derived association end)"); + QSet<QUmlInterface *> required_; + if (_isConjugated) { + if (QUmlInterface *interface = dynamic_cast<QUmlInterface *>(_type)) { + required_.insert(interface); + } + else { + collectRealizedInterfaces(dynamic_cast<QUmlBehavioredClassifier *>(_type), required_); + } + } + else { + collectUsedInterfaces(dynamic_cast<QUmlBehavioredClassifier *>(_type), required_); + } - return QSet<QUmlInterface *>(); + return required_; } void QUmlPort::addRequired(QUmlInterface *required) @@ -339,5 +364,28 @@ void QUmlPort::removeRequired(QUmlInterface *required) } } +void QUmlPort::collectRealizedInterfaces(QUmlBehavioredClassifier *behavioredClassifier, QSet<QUmlInterface *> &provided_) const +{ + if (!behavioredClassifier) + return; + foreach (QUmlInterfaceRealization *realization, behavioredClassifier->interfaceRealizations()) + provided_.insert(realization->contract()); + foreach (QUmlGeneralization *generalization, behavioredClassifier->generalizations()) + collectRealizedInterfaces(dynamic_cast<QUmlBehavioredClassifier *>(generalization->general()), provided_); +} + +void QUmlPort::collectUsedInterfaces(QUmlBehavioredClassifier *behavioredClassifier, QSet<QUmlInterface *> &required_) const +{ + if (!behavioredClassifier) + return; + foreach (QUmlDependency *dependency, behavioredClassifier->clientDependencies()) + if (QString::fromLatin1(dependency->asQModelingObject()->metaObject()->className()) == QStringLiteral("QUmlDependencyObject")) + foreach (QUmlNamedElement *supplier, dependency->suppliers()) + if (QUmlInterface *interface = dynamic_cast<QUmlInterface *>(supplier)) + required_.insert(interface); + foreach (QUmlGeneralization *generalization, behavioredClassifier->generalizations()) + collectUsedInterfaces(dynamic_cast<QUmlBehavioredClassifier *>(generalization->general()), required_); +} + QT_END_NAMESPACE diff --git a/src/uml/qumlport.h b/src/uml/qumlport.h index 12cf7e44..edc1843a 100644 --- a/src/uml/qumlport.h +++ b/src/uml/qumlport.h @@ -54,6 +54,8 @@ QT_MODULE(QtUml) class QUmlInterface; class QUmlProtocolStateMachine; +class QUmlBehavioredClassifier; + class Q_UML_EXPORT QUmlPort : public QUmlProperty { public: @@ -86,6 +88,10 @@ protected: bool _isService; QUmlProtocolStateMachine *_protocol; QSet<QUmlPort *> _redefinedPorts; + +private: + void collectRealizedInterfaces(QUmlBehavioredClassifier *behavioredClassifier, QSet<QUmlInterface *> &provided_) const; + void collectUsedInterfaces(QUmlBehavioredClassifier *behavioredClassifier, QSet<QUmlInterface *> &required_) const; }; QT_END_NAMESPACE diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 78ad7d9b..d797a078 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,3 +1,3 @@ TEMPLATE=subdirs qtHaveModule(mof): SUBDIRS += qtmofcontainment -qtHaveModule(uml): SUBDIRS += qtumlcontainment +qtHaveModule(uml): SUBDIRS += qtumlcontainment qtumlprovidedrequiredinterfaces diff --git a/tests/auto/qtumlprovidedrequiredinterfaces/qtumlprovidedrequiredinterfaces.pro b/tests/auto/qtumlprovidedrequiredinterfaces/qtumlprovidedrequiredinterfaces.pro new file mode 100644 index 00000000..639fd27f --- /dev/null +++ b/tests/auto/qtumlprovidedrequiredinterfaces/qtumlprovidedrequiredinterfaces.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qtumlprovidedrequiredinterfaces + +QT = modeling uml testlib + +SOURCES += \ + tst_qtumlprovidedrequiredinterfaces.cpp \ diff --git a/tests/auto/qtumlprovidedrequiredinterfaces/test.xmi b/tests/auto/qtumlprovidedrequiredinterfaces/test.xmi new file mode 100644 index 00000000..901e7345 --- /dev/null +++ b/tests/auto/qtumlprovidedrequiredinterfaces/test.xmi @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmlns:xmi="http://www.omg.org/spec/XMI/20110701" xmlns:uml="http://www.omg.org/spec/UML/20110701"> +<uml:Model xmi:id="_kk-nYE_cEeOrf6v5LQGc0Q" name="project2"> + <packagedElement xmi:type="uml:Node" xmi:id="_g59JVE_rEeOrf6v5LQGc0Q" name="Node"/> + <packagedElement xmi:type="uml:Component" xmi:id="_g59JVU_rEeOrf6v5LQGc0Q" name="WebServer"> + <ownedAttribute xmi:type="uml:Port" xmi:id="_g59JVk_rEeOrf6v5LQGc0Q" name="monitorablePort" type="_g59JWk_rEeOrf6v5LQGc0Q"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_g59JV0_rEeOrf6v5LQGc0Q" name="controllablePort" type="_g59JWU_rEeOrf6v5LQGc0Q"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_g59JWE_rEeOrf6v5LQGc0Q" name="classTypedPort" type="_g59JW0_rEeOrf6v5LQGc0Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWU_rEeOrf6v5LQGc0Q" name="IMaxClientsControl" isAbstract="true"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWk_rEeOrf6v5LQGc0Q" name="IAvgResponseTimeMonitor" isAbstract="true"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWU_rEeOrf6v5LQGc0R" name="IBaseProvidedInterface" isAbstract="true"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_g59JWk_rEeOrf6v5LQGc0R" name="IBaseRequiredInterface" isAbstract="true"/> + <packagedElement xmi:type="uml:Class" xmi:id="_g59JW0_rEeOrf6v5LQGc0Q" name="MaxClientsControl"> + <generalization xmi:type="uml:Generalization" xmi:id="_g59JW0_rEeOrf6v5LQGc0S" general="_g59JW0_rEeOrf6v5LQGc0R"/> + <clientDependency href="_g59JXU_rEeOrf6v5LQGc0Q"/> + <clientDependency href="_g59JXE_rEeOrf6v5LQGc0Q"/> + <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_g59JXE_rEeOrf6v5LQGc0Q" name="MaxClientsControl-IMaxClientsControl-Realization" contract="_g59JWU_rEeOrf6v5LQGc0Q"> + <supplier href="_g59JWU_rEeOrf6v5LQGc0Q"/> + <client href="_g59JW0_rEeOrf6v5LQGc0Q"/> + </interfaceRealization> + </packagedElement> + <packagedElement xmi:type="uml:Dependency" xmi:id="_g59JXU_rEeOrf6v5LQGc0Q" name="MaxClientsControl-IAvgResponseTimeMonitor-Dependency"> + <supplier href="_g59JWk_rEeOrf6v5LQGc0Q"/> + <client href="_g59JW0_rEeOrf6v5LQGc0Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_g59JW0_rEeOrf6v5LQGc0R" name="BaseClass"> + <clientDependency href="_g59JXU_rEeOrf6v5LQGc0R"/> + <clientDependency href="_g59JXE_rEeOrf6v5LQGc0R"/> + <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_g59JXE_rEeOrf6v5LQGc0R" name="BaseClass-IBaseProvidedInterface-Realization" contract="_g59JWU_rEeOrf6v5LQGc0R"> + <supplier href="_g59JWU_rEeOrf6v5LQGc0R"/> + <client href="_g59JW0_rEeOrf6v5LQGc0R"/> + </interfaceRealization> + </packagedElement> + <packagedElement xmi:type="uml:Dependency" xmi:id="_g59JXU_rEeOrf6v5LQGc0R" name="BaseClass-IBaseRequiredInterface-Dependency"> + <supplier href="_g59JWk_rEeOrf6v5LQGc0R"/> + <client href="_g59JW0_rEeOrf6v5LQGc0R"/> + </packagedElement> +</uml:Model> +</xmi:XMI> diff --git a/tests/auto/qtumlprovidedrequiredinterfaces/tst_qtumlprovidedrequiredinterfaces.cpp b/tests/auto/qtumlprovidedrequiredinterfaces/tst_qtumlprovidedrequiredinterfaces.cpp new file mode 100644 index 00000000..a5ba7c9f --- /dev/null +++ b/tests/auto/qtumlprovidedrequiredinterfaces/tst_qtumlprovidedrequiredinterfaces.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Sandro S. Andrade <sandroandrade@kde.org> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtUml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtTest/QtTest> + +#include <QtModeling/QXmiReader> +#include <QtModeling/QModelingElement> + +#include <QtUml/QUmlPort> +#include <QtUml/QUmlInterface> + +class TestQtUmlProvidedRequiredInterfaces : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void qtumlprovidedrequiredinterfaces(); +}; + +void TestQtUmlProvidedRequiredInterfaces::qtumlprovidedrequiredinterfaces() +{ + QFile file("test.xmi"); + + if (!file.open(QFile::ReadOnly | QFile::Text)) { + qDebug() << "Cannot read file !"; + return; + } + + QXmiReader reader; + QList<QModelingElement *> rootElements = reader.readFile(&file); + + QUmlPort *port1 = qmodelingelementproperty_cast<QUmlPort *>(rootElements.first()->asQModelingObject()->findChild<QObject *>("monitorablePort")); + QCOMPARE(port1->provided().size(), 1); + QCOMPARE(port1->provided().toList().first()->name(), QStringLiteral("IAvgResponseTimeMonitor")); + QCOMPARE(port1->required().size(), 0); + + QUmlPort *port2 = qmodelingelementproperty_cast<QUmlPort *>(rootElements.first()->asQModelingObject()->findChild<QObject *>("controllablePort")); + QCOMPARE(port2->provided().size(), 1); + QCOMPARE(port2->provided().toList().first()->name(), QStringLiteral("IMaxClientsControl")); + QCOMPARE(port2->required().size(), 0); + + QUmlPort *port3 = qmodelingelementproperty_cast<QUmlPort *>(rootElements.first()->asQModelingObject()->findChild<QObject *>("classTypedPort")); + QCOMPARE(port3->provided().size(), 2); + QCOMPARE(port3->provided().contains(qmodelingelementproperty_cast<QUmlInterface *>(rootElements.first()->asQModelingObject()->findChild<QObject *>("IBaseProvidedInterface"))), true); + QCOMPARE(port3->provided().contains(qmodelingelementproperty_cast<QUmlInterface *>(rootElements.first()->asQModelingObject()->findChild<QObject *>("IMaxClientsControl"))), true); + QCOMPARE(port3->required().size(), 2); + QCOMPARE(port3->required().contains(qmodelingelementproperty_cast<QUmlInterface *>(rootElements.first()->asQModelingObject()->findChild<QObject *>("IAvgResponseTimeMonitor"))), true); + QCOMPARE(port3->required().contains(qmodelingelementproperty_cast<QUmlInterface *>(rootElements.first()->asQModelingObject()->findChild<QObject *>("IBaseRequiredInterface"))), true); + +// qDeleteAll(rootElements); +} + +QTEST_MAIN(TestQtUmlProvidedRequiredInterfaces) +#include "tst_qtumlprovidedrequiredinterfaces.moc" + |