00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "umlrole.h"
00014
00015
00016 #include <kdebug.h>
00017 #include <qregexp.h>
00018
00019
00020 #include "association.h"
00021 #include "umldoc.h"
00022 #include "uml.h"
00023
00024
00025
00026 UMLRole::UMLRole(UMLAssociation * parent, UMLObject * parentObj, Uml::Role_Type role)
00027 : UMLObject(const_cast<UMLAssociation*>(parent))
00028 {
00029 init(parent, parentObj, role);
00030 }
00031
00032 UMLRole::~UMLRole() { }
00033
00034 bool UMLRole::operator==(UMLRole &rhs) {
00035 if (this == &rhs) {
00036 return true;
00037 }
00038 return ( UMLObject::operator==( rhs ) &&
00039 m_Changeability == rhs.m_Changeability &&
00040 m_Multi == rhs.m_Multi &&
00041 m_Name == rhs.m_Name
00042 );
00043 }
00044
00045 UMLAssociation * UMLRole::getParentAssociation () {
00046 return m_pAssoc;
00047 }
00048
00049 UMLObject* UMLRole::getObject() {
00050 return m_pSecondary;
00051 }
00052
00053 Uml::Changeability_Type UMLRole::getChangeability() const {
00054 return m_Changeability;
00055 }
00056
00057 QString UMLRole::getMultiplicity() const {
00058 return m_Multi;
00059 }
00060
00061 void UMLRole::setObject (UMLObject *obj) {
00062
00063
00064
00065
00066
00067 if(obj && dynamic_cast<UMLRole*>(obj))
00068 {
00069 kError()<<"ERROR: UMLRole cant setObject() to another UMLRole!, ignoring"<<endl;
00070 return;
00071 }
00072
00073 m_pSecondary = obj;
00074 UMLObject::emitModified();
00075 }
00076
00077 void UMLRole::setChangeability (Uml::Changeability_Type value) {
00078 m_Changeability = value;
00079 UMLObject::emitModified();
00080 }
00081
00082 void UMLRole::setMultiplicity ( const QString &multi ) {
00083 m_Multi = multi;
00084 UMLObject::emitModified();
00085 }
00086
00087 Uml::Role_Type UMLRole::getRole() {
00088 return m_role;
00089 }
00090
00091 void UMLRole::init(UMLAssociation * parent, UMLObject * parentObj, Uml::Role_Type r) {
00092 m_BaseType = Uml::ot_Role;
00093 m_role = r;
00094 m_pAssoc = parent;
00095 m_pSecondary = parentObj;
00096 m_Multi = "";
00097 m_Name = "";
00098 m_Changeability = Uml::chg_Changeable;
00099
00100
00101 connect(this,SIGNAL(modified()),parent,SIGNAL(modified()));
00102 }
00103
00104 void UMLRole::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) {
00105 QDomElement roleElement = UMLObject::save("UML:AssociationEnd", qDoc);
00106 if (m_pSecondary)
00107 roleElement.setAttribute( "type", ID2STR(m_pSecondary->getID()) );
00108 else
00109 kError() << "UMLRole::saveToXMI(id " << ID2STR(m_nId)
00110 << "): m_pSecondary is NULL" << endl;
00111 if (!m_Multi.isEmpty())
00112 roleElement.setAttribute("multiplicity", m_Multi);
00113 if (m_role == Uml::A) {
00114
00115 switch (m_pAssoc->getAssocType()) {
00116 case Uml::at_Composition:
00117 roleElement.setAttribute("aggregation", "composite");
00118 break;
00119 case Uml::at_Aggregation:
00120 roleElement.setAttribute("aggregation", "aggregate");
00121 break;
00122 default:
00123 roleElement.setAttribute("aggregation", "none");
00124 break;
00125 }
00126 if (m_pAssoc->getAssocType() == Uml::at_UniAssociation) {
00127
00128
00129
00130 roleElement.setAttribute("isNavigable", "false");
00131 } else {
00132 roleElement.setAttribute("isNavigable", "true");
00133 }
00134 } else {
00135 roleElement.setAttribute("aggregation", "none");
00136 roleElement.setAttribute("isNavigable", "true");
00137
00138 if (m_pAssoc->getAssocType() == Uml::at_Relationship) {
00139 roleElement.setAttribute("relationship", "true");
00140 }
00141 }
00142
00143 roleElement.setAttribute("visibility", getVisibility().toString(false));
00144
00145 switch (m_Changeability) {
00146 case Uml::chg_Frozen:
00147 roleElement.setAttribute("changeability", "frozen");
00148 break;
00149 case Uml::chg_AddOnly:
00150 roleElement.setAttribute("changeability", "addOnly");
00151 break;
00152 case Uml::chg_Changeable:
00153 roleElement.setAttribute("changeability", "changeable");
00154 break;
00155 }
00156 qElement.appendChild( roleElement );
00157 }
00158
00159 bool UMLRole::load( QDomElement & element ) {
00160 UMLDoc * doc = UMLApp::app()->getDocument();
00161 QString type = element.attribute("type", "");
00162 if (!type.isEmpty()) {
00163 if (!m_SecondaryId.isEmpty())
00164 kWarning() << "UMLRole::load: overwriting old m_SecondaryId \""
00165 << m_SecondaryId << " with new value \""
00166 << type << "\"" << endl;
00167 m_SecondaryId = type;
00168 }
00169
00170 for (QDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling()) {
00171 if (node.isComment())
00172 continue;
00173 QDomElement tempElement = node.toElement();
00174 QString tag = tempElement.tagName();
00175 if (Uml::tagEq(tag, "name")) {
00176 m_Name = tempElement.text();
00177 } else if (Uml::tagEq(tag, "AssociationEnd.multiplicity")) {
00185 QDomNode n = tempElement.firstChild();
00186 if (node.isNull() || tempElement.isNull() || n.isNull() ||
00187 n.toElement().isNull()) {
00188 m_Multi = tempElement.text().stripWhiteSpace();
00189 continue;
00190 }
00191 tempElement = n.toElement();
00192 tag = tempElement.tagName();
00193 if (!Uml::tagEq(tag, "Multiplicity")) {
00194 m_Multi = tempElement.text().stripWhiteSpace();
00195 continue;
00196 }
00197 n = tempElement.firstChild();
00198 tempElement = n.toElement();
00199 tag = tempElement.tagName();
00200 if (!Uml::tagEq(tag, "Multiplicity.range")) {
00201 m_Multi = tempElement.text().stripWhiteSpace();
00202 continue;
00203 }
00204 n = tempElement.firstChild();
00205 tempElement = n.toElement();
00206 tag = tempElement.tagName();
00207 if (!Uml::tagEq(tag, "MultiplicityRange")) {
00208 m_Multi = tempElement.text().stripWhiteSpace();
00209 continue;
00210 }
00211 QString multiUpper;
00212 if (tempElement.hasAttribute("lower")) {
00213 m_Multi = tempElement.attribute("lower", "");
00214 multiUpper = tempElement.attribute("upper", "");
00215 if (!multiUpper.isEmpty()) {
00216 if (!m_Multi.isEmpty())
00217 m_Multi.append("..");
00218 m_Multi.append(multiUpper);
00219 }
00220 continue;
00221 }
00222 n = tempElement.firstChild();
00223 while (!n.isNull()) {
00224 tempElement = n.toElement();
00225 tag = tempElement.tagName();
00226 if (Uml::tagEq(tag, "MultiplicityRange.lower")) {
00227 m_Multi = tempElement.text();
00228 } else if (Uml::tagEq(tag, "MultiplicityRange.upper")) {
00229 multiUpper = tempElement.text();
00230 }
00231 n = n.nextSibling();
00232 }
00233 if (!multiUpper.isEmpty()) {
00234 if (!m_Multi.isEmpty())
00235 m_Multi.append("..");
00236 m_Multi.append(multiUpper);
00237 }
00238 } else if (m_SecondaryId.isEmpty() &&
00239 (Uml::tagEq(tag, "type") ||
00240 Uml::tagEq(tag, "participant"))) {
00241 m_SecondaryId = tempElement.attribute("xmi.id", "");
00242 if (m_SecondaryId.isEmpty())
00243 m_SecondaryId = tempElement.attribute("xmi.idref", "");
00244 if (m_SecondaryId.isEmpty()) {
00245 QDomNode inner = tempElement.firstChild();
00246 QDomElement innerElem = inner.toElement();
00247 m_SecondaryId = innerElem.attribute("xmi.id", "");
00248 if (m_SecondaryId.isEmpty())
00249 m_SecondaryId = innerElem.attribute("xmi.idref", "");
00250 }
00251 }
00252 }
00253 if (!m_Multi.isEmpty())
00254 kDebug() << "UMLRole::load(" << m_Name << "): m_Multi is " << m_Multi << endl;
00255 if (m_SecondaryId.isEmpty()) {
00256 kError() << "UMLRole::load: type not given or illegal" << endl;
00257 return false;
00258 }
00259 UMLObject * obj;
00260 obj = doc->findObjectById(STR2ID(m_SecondaryId));
00261 if (obj) {
00262 m_pSecondary = obj;
00263 m_SecondaryId = "";
00264 }
00265
00266
00267 blockSignals(true);
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 QString aggregation = element.attribute("aggregation", "none");
00284 if (aggregation == "composite")
00285 m_pAssoc->setAssocType(Uml::at_Composition);
00286 else if (aggregation == "shared"
00287 || aggregation == "aggregate")
00288 m_pAssoc->setAssocType(Uml::at_Aggregation);
00289
00290 if (!element.hasAttribute("isNavigable")) {
00291
00292
00293
00294
00295 m_pAssoc->setOldLoadMode(true);
00296 } else if (m_pAssoc->getOldLoadMode() == true) {
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 if (element.attribute("isNavigable") == "true")
00309 m_pAssoc->setAssocType(Uml::at_UniAssociation);
00310 } else if (element.attribute("isNavigable") == "false") {
00311 m_pAssoc->setAssocType(Uml::at_UniAssociation);
00312 }
00313
00314
00315 if (element.hasAttribute("relationship")) {
00316 if (element.attribute("relationship") == "true") {
00317 m_pAssoc->setAssocType(Uml::at_Relationship);
00318 }
00319 }
00320
00321 if (m_Multi.isEmpty())
00322 m_Multi = element.attribute("multiplicity", "");
00323
00324
00325 m_Changeability = Uml::chg_Changeable;
00326 QString changeability = element.attribute("changeability", "");
00327 if (changeability.isEmpty())
00328 element.attribute("changeable", "");
00329 if (changeability == "frozen")
00330 m_Changeability = Uml::chg_Frozen;
00331 else if (changeability == "addOnly")
00332 m_Changeability = Uml::chg_AddOnly;
00333
00334
00335 blockSignals(false);
00336 return true;
00337 }
00338
00339 #include "umlrole.moc"