00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "classifier.h"
00013
00014 #include <kdebug.h>
00015 #include <klocale.h>
00016 #include <kmessagebox.h>
00017
00018 #include "association.h"
00019 #include "umlassociationlist.h"
00020 #include "operation.h"
00021 #include "attribute.h"
00022 #include "template.h"
00023 #include "enumliteral.h"
00024 #include "entityattribute.h"
00025 #include "enum.h"
00026 #include "entity.h"
00027 #include "stereotype.h"
00028 #include "umldoc.h"
00029 #include "uml.h"
00030 #include "umllistview.h"
00031 #include "uniqueid.h"
00032 #include "object_factory.h"
00033 #include "model_utils.h"
00034 #include "clipboard/idchangelog.h"
00035 #include "dialogs/umloperationdialog.h"
00036 #include "dialogs/umlattributedialog.h"
00037 #include "dialogs/umltemplatedialog.h"
00038 #include "optionstate.h"
00039
00040 using namespace Uml;
00041
00042 UMLClassifier::UMLClassifier(const QString & name, Uml::IDType id)
00043 : UMLPackage(name, id)
00044 {
00045 init();
00046 }
00047
00048 UMLClassifier::~UMLClassifier() {
00049 }
00050
00051 void UMLClassifier::init() {
00052 m_BaseType = Uml::ot_Class;
00053 m_pClassAssoc = NULL;
00054 m_isRef = false;
00055 }
00056
00057 void UMLClassifier::setBaseType(Uml::Object_Type ot) {
00058 m_BaseType = ot;
00059 Uml::Icon_Type newIcon;
00060 switch (ot) {
00061 case ot_Interface:
00062 UMLObject::setStereotype("interface");
00063 UMLObject::m_bAbstract = true;
00064 newIcon = Uml::it_Interface;
00065 break;
00066 case ot_Class:
00067 UMLObject::setStereotype(QString::null);
00068 UMLObject::m_bAbstract = false;
00069 newIcon = Uml::it_Class;
00070 break;
00071 case ot_Datatype:
00072 UMLObject::setStereotype("datatype");
00073 UMLObject::m_bAbstract = false;
00074 newIcon = Uml::it_Datatype;
00075 break;
00076 default:
00077 kError() << "UMLClassifier::setBaseType: cannot set to type "
00078 << ot << endl;
00079 return;
00080 }
00081
00082
00083 UMLListView *listView = UMLApp::app()->getListView();
00084 listView->changeIconOf(this, newIcon);
00085 }
00086
00087 bool UMLClassifier::isInterface() const {
00088 return (m_BaseType == ot_Interface);
00089 }
00090
00091 bool UMLClassifier::isDatatype() const {
00092 return (m_BaseType == ot_Datatype);
00093 }
00094
00095 UMLOperation * UMLClassifier::checkOperationSignature(
00096 const QString& name,
00097 UMLAttributeList opParams,
00098 UMLOperation *exemptOp)
00099 {
00100 UMLOperationList list = findOperations(name);
00101 if( list.count() == 0 )
00102 return NULL;
00103 const int inputParmCount = opParams.count();
00104
00105
00106 for (UMLOperationListIt oit(list); oit.current(); ++oit)
00107 {
00108 UMLOperation* test = oit.current();
00109 if (test == exemptOp)
00110 continue;
00111 UMLAttributeList testParams = test->getParmList( );
00112 const int pCount = testParams.count();
00113 if( pCount != inputParmCount )
00114 continue;
00115 int i = 0;
00116 while (i < pCount) {
00117
00118
00119 if( testParams.at(i)->getTypeName() != opParams.at(i)->getTypeName() )
00120 break;
00121 i++;
00122 }
00123 if( i == pCount )
00124 {
00125 return test;
00126 }
00127 }
00128
00129 return NULL;
00130 }
00131
00132 UMLOperation* UMLClassifier::findOperation(const QString& name,
00133 Model_Utils::NameAndType_List params) {
00134 UMLOperationList list = findOperations(name);
00135 if (list.count() == 0)
00136 return NULL;
00137
00138 const int inputParmCount = params.count();
00139 UMLOperation* test = NULL;
00140 for (UMLOperationListIt oit(list); (test = oit.current()) != NULL; ++oit) {
00141 UMLAttributeList testParams = test->getParmList();
00142 const int pCount = testParams.count();
00143 if (inputParmCount == 0 && pCount == 0)
00144 break;
00145 if (inputParmCount != pCount)
00146 continue;
00147 int i = 0;
00148 for (; i < pCount; ++i) {
00149 Model_Utils::NameAndType_ListIt nt(params.at(i));
00150 UMLClassifier *c = dynamic_cast<UMLClassifier*>((*nt).m_type);
00151 UMLClassifier *testType = testParams.at(i)->getType();
00152 if (c == NULL) {
00153 if (testType->getName() != "class")
00154 break;
00155 } else if (c != testType)
00156 break;
00157 }
00158 if (i == pCount)
00159 break;
00160 }
00161 return test;
00162 }
00163
00164 UMLOperation* UMLClassifier::createOperation(const QString &name ,
00165 bool *isExistingOp ,
00166 Model_Utils::NameAndType_List *params )
00167 {
00168 bool nameNotSet = (name.isNull() || name.isEmpty());
00169 if (! nameNotSet) {
00170 Model_Utils::NameAndType_List parList;
00171 if (params)
00172 parList = *params;
00173 UMLOperation* existingOp = findOperation(name, parList);
00174 if (existingOp != NULL) {
00175 if (isExistingOp != NULL)
00176 *isExistingOp = true;
00177 return existingOp;
00178 }
00179 }
00180
00181 UMLOperation *op = new UMLOperation(this, name);
00182 if (params) {
00183 for (Model_Utils::NameAndType_ListIt it = params->begin(); it != params->end(); ++it ) {
00184 const Model_Utils::NameAndType &nt = *it;
00185 UMLAttribute *par = new UMLAttribute(op, nt.m_name, Uml::id_None, Uml::Visibility::Private,
00186 nt.m_type, nt.m_initialValue);
00187 par->setParmKind(nt.m_direction);
00188 op->addParm(par);
00189 }
00190 }
00191 if (nameNotSet || params == NULL) {
00192 if (nameNotSet)
00193 op->setName( uniqChildName(Uml::ot_Operation) );
00194 do {
00195 UMLOperationDialog operationDialogue(0, op);
00196 if( operationDialogue.exec() != QDialog::Accepted ) {
00197 delete op;
00198 return NULL;
00199 } else if (checkOperationSignature(op->getName(), op->getParmList())) {
00200 KMessageBox::information(0,
00201 i18n("An operation with the same name and signature already exists. You can not add it again."));
00202 } else {
00203 break;
00204 }
00205 } while(1);
00206 }
00207
00208
00209 if (! addOperation(op)) {
00210 delete op;
00211 return NULL;
00212 }
00213
00214 UMLDoc *umldoc = UMLApp::app()->getDocument();
00215 umldoc->signalUMLObjectCreated(op);
00216 return op;
00217 }
00218
00219 bool UMLClassifier::addOperation(UMLOperation* op, int position )
00220 {
00221 if (m_List.findRef(op) != -1) {
00222 kDebug() << "UMLClassifier::addOperation: findRef("
00223 << op->getName() << ") finds op (bad)"
00224 << endl;
00225 return false;
00226 }
00227 if (checkOperationSignature(op->getName(), op->getParmList()) ) {
00228 kDebug() << "UMLClassifier::addOperation: checkOperationSignature("
00229 << op->getName() << ") op is non-unique" << endl;
00230 return false;
00231 }
00232
00233 if( position >= 0 && position <= (int)m_List.count() ) {
00234 kDebug() << "UMLClassifier::addOperation(" << op->getName()
00235 << "): inserting at position " << position << endl;
00236 m_List.insert(position,op);
00237 UMLClassifierListItemList itemList = getFilteredList(Uml::ot_Operation);
00238 UMLClassifierListItem* currentAtt;
00239 QString buf;
00240 for (UMLClassifierListItemListIt it0(itemList); (currentAtt = it0.current()); ++it0)
00241 buf.append(' ' + currentAtt->getName());
00242 kDebug() << " UMLClassifier::addOperation list after change: " << buf << endl;
00243 } else
00244 m_List.append( op );
00245 emit operationAdded(op);
00246 UMLObject::emitModified();
00247 connect(op,SIGNAL(modified()),this,SIGNAL(modified()));
00248 return true;
00249 }
00250
00251 bool UMLClassifier::addOperation(UMLOperation* Op, IDChangeLog* Log) {
00252 if( addOperation( Op, -1 ) )
00253 return true;
00254 else if( Log ) {
00255 Log->removeChangeByNewID( Op -> getID() );
00256 }
00257 return false;
00258 }
00259
00260 int UMLClassifier::removeOperation(UMLOperation *op) {
00261 if (op == NULL) {
00262 kDebug() << "UMLClassifier::removeOperation called on NULL op"
00263 << endl;
00264 return -1;
00265 }
00266 if(!m_List.remove(op)) {
00267 kDebug() << "UMLClassifier::removeOperation: can't find op "
00268 << op->getName() << " in list" << endl;
00269 return -1;
00270 }
00271
00272
00273 disconnect(op,SIGNAL(modified()),this,SIGNAL(modified()));
00274 emit operationRemoved(op);
00275 UMLObject::emitModified();
00276 return m_List.count();
00277 }
00278
00279 UMLObject* UMLClassifier::createTemplate(const QString& currentName ) {
00280 QString name = currentName;
00281 bool goodName = !name.isEmpty();
00282 if (!goodName)
00283 name = uniqChildName(Uml::ot_Template);
00284 UMLTemplate* newTemplate = new UMLTemplate(this, name);
00285
00286 int button = QDialog::Accepted;
00287
00288 while (button==QDialog::Accepted && !goodName) {
00289 UMLTemplateDialog templateDialogue(0, newTemplate);
00290 button = templateDialogue.exec();
00291 name = newTemplate->getName();
00292
00293 if(name.length() == 0) {
00294 KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
00295 } else if ( findChildObject(name) != NULL ) {
00296 KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
00297 } else {
00298 goodName = true;
00299 }
00300 }
00301
00302 if (button != QDialog::Accepted) {
00303 return NULL;
00304 }
00305
00306 addTemplate(newTemplate);
00307
00308 UMLDoc *umldoc = UMLApp::app()->getDocument();
00309 umldoc->signalUMLObjectCreated(newTemplate);
00310 return newTemplate;
00311 }
00312
00313 int UMLClassifier::attributes() {
00314 UMLClassifierListItemList atts = getFilteredList(Uml::ot_Attribute);
00315 return atts.count();
00316 }
00317
00318 UMLAttributeList UMLClassifier::getAttributeList() {
00319 UMLAttributeList attributeList;
00320 for (UMLObjectListIt lit(m_List); lit.current(); ++lit) {
00321 UMLObject *listItem = lit.current();
00322 if (listItem->getBaseType() == Uml::ot_Attribute) {
00323 attributeList.append(static_cast<UMLAttribute*>(listItem));
00324 }
00325 }
00326 return attributeList;
00327 }
00328
00329 UMLOperationList UMLClassifier::findOperations(const QString &n) {
00330 const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
00331 UMLOperationList list;
00332 for (UMLObjectListIt lit(m_List); lit.current(); ++lit) {
00333 UMLObject* obj = lit.current();
00334 if (obj->getBaseType() != Uml::ot_Operation)
00335 continue;
00336 UMLOperation *op = static_cast<UMLOperation*>(obj);
00337 if (caseSensitive) {
00338 if (obj->getName() == n)
00339 list.append(op);
00340 } else if (obj->getName().lower() == n.lower()) {
00341 list.append(op);
00342 }
00343 }
00344 return list;
00345 }
00346
00347 UMLObject* UMLClassifier::findChildObjectById(Uml::IDType id, bool considerAncestors ) {
00348 UMLObject *o = UMLCanvasObject::findChildObjectById(id);
00349 if (o)
00350 return o;
00351 if (considerAncestors) {
00352 UMLClassifierList ancestors = findSuperClassConcepts();
00353 for (UMLClassifier *anc = ancestors.first(); anc; anc = ancestors.next()) {
00354 UMLObject *o = anc->findChildObjectById(id);
00355 if (o)
00356 return o;
00357 }
00358 }
00359 return NULL;
00360 }
00361
00362 UMLClassifierList UMLClassifier::findSubClassConcepts (ClassifierType type) {
00363 UMLClassifierList list = getSubClasses();
00364 UMLAssociationList rlist = getRealizations();
00365
00366 UMLClassifierList inheritingConcepts;
00367 Uml::IDType myID = getID();
00368 for (UMLClassifier *c = list.first(); c; c = list.next())
00369 {
00370 if (type == ALL || (!c->isInterface() && type == CLASS)
00371 || (c->isInterface() && type == INTERFACE))
00372 inheritingConcepts.append(c);
00373 }
00374
00375 for (UMLAssociation *a = rlist.first(); a; a = rlist.next())
00376 {
00377 if (a->getObjectId(A) != myID)
00378 {
00379 UMLObject* obj = a->getObject(A);
00380 UMLClassifier *concept = dynamic_cast<UMLClassifier*>(obj);
00381 if (concept && (type == ALL || (!concept->isInterface() && type == CLASS)
00382 || (concept->isInterface() && type == INTERFACE))
00383 && (inheritingConcepts.findRef(concept) == -1))
00384 inheritingConcepts.append(concept);
00385 }
00386 }
00387
00388 return inheritingConcepts;
00389 }
00390
00391 UMLClassifierList UMLClassifier::findSuperClassConcepts (ClassifierType type) {
00392 UMLClassifierList list = getSuperClasses();
00393 UMLAssociationList rlist = getRealizations();
00394
00395 UMLClassifierList parentConcepts;
00396 Uml::IDType myID = getID();
00397 for (UMLClassifier *concept = list.first(); concept; concept = list.next())
00398 {
00399 if (type == ALL || (!concept->isInterface() && type == CLASS)
00400 || (concept->isInterface() && type == INTERFACE))
00401 parentConcepts.append(concept);
00402 }
00403
00404 for (UMLAssociation *a = rlist.first(); a; a = rlist.next())
00405 {
00406 if (a->getObjectId(A) == myID)
00407 {
00408 UMLObject* obj = a->getObject(B);
00409 UMLClassifier *concept = dynamic_cast<UMLClassifier*>(obj);
00410 if (concept && (type == ALL || (!concept->isInterface() && type == CLASS)
00411 || (concept->isInterface() && type == INTERFACE))
00412 && (parentConcepts.findRef(concept) == -1))
00413 parentConcepts.append(concept);
00414 }
00415 }
00416
00417 return parentConcepts;
00418 }
00419
00420 bool UMLClassifier::operator==( UMLClassifier & rhs ) {
00421
00422
00423
00424
00425
00426
00427
00428
00429 return UMLCanvasObject::operator==(rhs);
00430 }
00431
00432
00433 void UMLClassifier::copyInto(UMLClassifier *rhs) const
00434 {
00435 UMLCanvasObject::copyInto(rhs);
00436 rhs->setBaseType(m_BaseType);
00437
00438 m_List.copyInto(&(rhs->m_List));
00439 }
00440
00441 UMLObject* UMLClassifier::clone() const {
00442 UMLClassifier *clone = new UMLClassifier();
00443 copyInto(clone);
00444 return clone;
00445 }
00446
00447 bool UMLClassifier::resolveRef() {
00448 bool success = UMLPackage::resolveRef();
00449
00450 for (UMLObjectListIt oit(m_List); oit.current(); ++oit) {
00451 UMLObject* obj = oit.current();
00452
00453
00454
00455
00456
00457 if (obj->resolveRef()) {
00458 UMLClassifierListItem *cli = static_cast<UMLClassifierListItem*>(obj);
00459 switch (cli->getBaseType()) {
00460 case Uml::ot_Attribute:
00461 emit attributeAdded(cli);
00462 break;
00463 case Uml::ot_Operation:
00464 emit operationAdded(cli);
00465 break;
00466 case Uml::ot_Template:
00467 emit templateAdded(cli);
00468 break;
00469 default:
00470 break;
00471 }
00472 }
00473 }
00474 return success;
00475 }
00476
00477 bool UMLClassifier::acceptAssociationType(Uml::Association_Type type)
00478 {
00479 switch(type)
00480 {
00481 case at_Generalization:
00482 case at_Aggregation:
00483 case at_Relationship:
00484 case at_Dependency:
00485 case at_Association:
00486 case at_Association_Self:
00487 case at_Containment:
00488 case at_Composition:
00489 case at_Realization:
00490 case at_UniAssociation:
00491 return true;
00492 default:
00493 return false;
00494 }
00495 return false;
00496 }
00497
00498 UMLAttribute* UMLClassifier::createAttribute(const QString &name ,
00499 UMLObject *type,
00500 Uml::Visibility vis,
00501 const QString &init) {
00502 Uml::IDType id = UniqueID::gen();
00503 QString currentName;
00504 if (name.isNull()) {
00505 currentName = uniqChildName(Uml::ot_Attribute);
00506 } else {
00507 currentName = name;
00508 }
00509 UMLAttribute* newAttribute = new UMLAttribute(this, currentName, id, vis, type, init);
00510
00511 int button = QDialog::Accepted;
00512 bool goodName = false;
00513
00514
00515
00516 while (button == QDialog::Accepted && !goodName && name.isNull()) {
00517 UMLAttributeDialog attributeDialogue(0, newAttribute);
00518 button = attributeDialogue.exec();
00519 QString name = newAttribute->getName();
00520
00521 if(name.length() == 0) {
00522 KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
00523 } else if ( findChildObject(name) != NULL ) {
00524 KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
00525 } else {
00526 goodName = true;
00527 }
00528 }
00529
00530 if (button != QDialog::Accepted) {
00531 delete newAttribute;
00532 return NULL;
00533 }
00534
00535 addAttribute(newAttribute);
00536
00537 UMLDoc *umldoc = UMLApp::app()->getDocument();
00538 umldoc->signalUMLObjectCreated(newAttribute);
00539 return newAttribute;
00540 }
00541
00542 UMLAttribute* UMLClassifier::addAttribute(const QString &name, Uml::IDType id ) {
00543 for (UMLObjectListIt lit(m_List); lit.current(); ++lit) {
00544 UMLObject *obj = lit.current();
00545 if (obj->getBaseType() == Uml::ot_Attribute && obj->getName() == name)
00546 return static_cast<UMLAttribute*>(obj);
00547 }
00548 Uml::Visibility scope = Settings::getOptionState().classState.defaultAttributeScope;
00549 UMLAttribute *a = new UMLAttribute(this, name, id, scope);
00550 m_List.append(a);
00551 emit attributeAdded(a);
00552 UMLObject::emitModified();
00553 connect(a,SIGNAL(modified()),this,SIGNAL(modified()));
00554 return a;
00555 }
00556
00557 UMLAttribute* UMLClassifier::addAttribute(const QString &name, UMLObject *type, Uml::Visibility scope) {
00558 UMLAttribute *a = new UMLAttribute(this);
00559 a->setName(name);
00560 a->setVisibility(scope);
00561 a->setID(UniqueID::gen());
00562 if (type)
00563 a->setType(type);
00564 m_List.append(a);
00565 emit attributeAdded(a);
00566 UMLObject::emitModified();
00567 connect(a,SIGNAL(modified()),this,SIGNAL(modified()));
00568 return a;
00569 }
00570
00571 bool UMLClassifier::addAttribute(UMLAttribute* att, IDChangeLog* Log ,
00572 int position ) {
00573 if (findChildObject(att->getName()) == NULL) {
00574 att->parent()->removeChild( att );
00575 this->insertChild( att );
00576 if (position >= 0 && position < (int)m_List.count())
00577 m_List.insert(position, att);
00578 else
00579 m_List.append(att);
00580 emit attributeAdded(att);
00581 UMLObject::emitModified();
00582 connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
00583 return true;
00584 } else if (Log) {
00585 Log->removeChangeByNewID(att->getID());
00586 delete att;
00587 }
00588 return false;
00589 }
00590
00591 int UMLClassifier::removeAttribute(UMLAttribute* a) {
00592 if (!m_List.remove(a)) {
00593 kDebug() << "can't find att given in list" << endl;
00594 return -1;
00595 }
00596 emit attributeRemoved(a);
00597 UMLObject::emitModified();
00598
00599
00600
00601 delete a;
00602 return m_List.count();
00603 }
00604
00605
00606 void UMLClassifier::setClassAssoc(UMLAssociation *assoc) {
00607 m_pClassAssoc = assoc;
00608 }
00609
00610 UMLAssociation *UMLClassifier::getClassAssoc() {
00611 return m_pClassAssoc;
00612 }
00613
00614 bool UMLClassifier::hasAbstractOps () {
00615 UMLOperationList opl( getOpList() );
00616 for(UMLOperation *op = opl.first(); op ; op = opl.next())
00617 if(op->getAbstract())
00618 return true;
00619 return false;
00620 }
00621
00622 int UMLClassifier::operations() {
00623 return getOpList().count();
00624 }
00625
00626 UMLOperationList UMLClassifier::getOpList(bool includeInherited) {
00627 UMLOperationList ops;
00628 for (UMLObjectListIt lit(m_List); lit.current(); ++lit) {
00629 UMLObject *li = lit.current();
00630 if (li->getBaseType() == ot_Operation)
00631 ops.append(static_cast<UMLOperation*>(li));
00632 }
00633 if (includeInherited) {
00634 UMLClassifierList parents = findSuperClassConcepts();
00635 UMLClassifier *c;
00636 for (UMLClassifierListIt pit(parents); (c = pit.current()) != NULL; ++pit) {
00637 if (c == this) {
00638 kError() << "UMLClassifier::getOpList: class " << c->getName()
00639 << " is parent of itself ?!?" << endl;
00640 continue;
00641 }
00642
00643 UMLOperationList pops = c->getOpList(true);
00644
00645 for (UMLOperation *po = pops.first(); po; po = pops.next()) {
00646 QString po_as_string(po->toString(Uml::st_SigNoVis));
00647 UMLOperation *o = NULL;
00648 for (o = ops.first(); o; o = ops.next())
00649 if (o->toString(Uml::st_SigNoVis) == po_as_string)
00650 break;
00651 if (!o)
00652 ops.append(po);
00653 }
00654 }
00655 }
00656 return ops;
00657 }
00658
00659 UMLClassifierListItemList UMLClassifier::getFilteredList(Object_Type ot) {
00660 UMLClassifierListItemList resultList;
00661 UMLObject *o;
00662 for (UMLObjectListIt lit(m_List); (o = lit.current()) != NULL; ++lit) {
00663 if (o->getBaseType() == Uml::ot_Association)
00664 continue;
00665 UMLClassifierListItem *listItem = static_cast<UMLClassifierListItem*>(o);
00666 if (ot == Uml::ot_UMLObject || listItem->getBaseType() == ot)
00667 resultList.append(listItem);
00668 }
00669 return resultList;
00670 }
00671
00672 UMLTemplate* UMLClassifier::addTemplate(const QString &name, Uml::IDType id) {
00673 UMLTemplate *t = findTemplate(name);
00674 if (t)
00675 return t;
00676 t = new UMLTemplate(this, name, id);
00677 m_List.append(t);
00678 emit templateAdded(t);
00679 UMLObject::emitModified();
00680 connect(t, SIGNAL(modified()), this, SIGNAL(modified()));
00681 return t;
00682 }
00683
00684 bool UMLClassifier::addTemplate(UMLTemplate* newTemplate, IDChangeLog* log ) {
00685 QString name = newTemplate->getName();
00686 if (findChildObject(name) == NULL) {
00687 newTemplate->parent()->removeChild(newTemplate);
00688 this->insertChild(newTemplate);
00689 m_List.append(newTemplate);
00690 emit templateAdded(newTemplate);
00691 UMLObject::emitModified();
00692 connect(newTemplate,SIGNAL(modified()),this,SIGNAL(modified()));
00693 return true;
00694 } else if (log) {
00695 log->removeChangeByNewID( newTemplate->getID() );
00696 delete newTemplate;
00697 }
00698 return false;
00699 }
00700
00701 bool UMLClassifier::addTemplate(UMLTemplate* Template, int position)
00702 {
00703 QString name = Template->getName();
00704 if (findChildObject(name) == NULL) {
00705 Template->parent()->removeChild(Template);
00706 this->insertChild(Template);
00707 if( position >= 0 && position <= (int)m_List.count() )
00708 m_List.insert(position,Template);
00709 else
00710 m_List.append(Template);
00711 emit templateAdded(Template);
00712 UMLObject::emitModified();
00713 connect(Template,SIGNAL(modified()),this,SIGNAL(modified()));
00714 return true;
00715 }
00716
00717 return false;
00718 }
00719
00720 int UMLClassifier::removeTemplate(UMLTemplate* umltemplate) {
00721 if ( !m_List.remove(umltemplate) ) {
00722 kWarning() << "can't find att given in list" << endl;
00723 return -1;
00724 }
00725 emit templateRemoved(umltemplate);
00726 UMLObject::emitModified();
00727 disconnect(umltemplate,SIGNAL(modified()),this,SIGNAL(modified()));
00728 return m_List.count();
00729 }
00730
00731
00732 UMLTemplate *UMLClassifier::findTemplate(const QString& name) {
00733 UMLTemplateList templParams = getTemplateList();
00734 for (UMLTemplate *t = templParams.first(); t; t = templParams.next()) {
00735 if (t->getName() == name)
00736 return t;
00737 }
00738 return NULL;
00739 }
00740
00741 int UMLClassifier::templates() {
00742 UMLClassifierListItemList tempList = getFilteredList(Uml::ot_Template);
00743 return tempList.count();
00744 }
00745
00746 UMLTemplateList UMLClassifier::getTemplateList() {
00747 UMLTemplateList templateList;
00748 for (UMLObjectListIt lit(m_List); lit.current(); ++lit) {
00749 UMLObject *listItem = lit.current();
00750 if (listItem->getBaseType() == Uml::ot_Template) {
00751 templateList.append(static_cast<UMLTemplate*>(listItem));
00752 }
00753 }
00754 return templateList;
00755 }
00756
00757 int UMLClassifier::takeItem(UMLClassifierListItem *item) {
00758 UMLObject* currentAtt;
00759 QString buf;
00760 for (UMLObjectListIt it0(m_List);
00761 (currentAtt = it0.current()); ++it0) {
00762 QString txt = currentAtt->getName();
00763 if (txt.isEmpty())
00764 txt = "Type-" + QString::number((int) currentAtt->getBaseType());
00765 buf.append(' ' + currentAtt->getName());
00766 }
00767 kDebug() << " UMLClassifier::takeItem (before): m_List is " << buf << endl;
00768 int index = m_List.findRef(item);
00769 if (index == -1)
00770 return -1;
00771 switch (item->getBaseType()) {
00772 case Uml::ot_Operation: {
00773 if (removeOperation(dynamic_cast<UMLOperation*>(item)) < 0)
00774 index = -1;
00775 break;
00776 }
00777 case Uml::ot_Attribute: {
00778 UMLAttribute *retval = dynamic_cast<UMLAttribute*>(m_List.take());
00779 if (retval) {
00780 emit attributeRemoved(retval);
00781 emit modified();
00782 } else {
00783 index = -1;
00784 }
00785 break;
00786 }
00787 case Uml::ot_Template: {
00788 UMLTemplate *t = dynamic_cast<UMLTemplate*>(m_List.take());
00789 if (t) {
00790 emit templateRemoved(t);
00791 emit modified();
00792 } else {
00793 index = -1;
00794 }
00795 break;
00796 }
00797 case Uml::ot_EnumLiteral: {
00798 UMLEnumLiteral *el = dynamic_cast<UMLEnumLiteral*>(m_List.take());
00799 if (el) {
00800 UMLEnum *e = static_cast<UMLEnum*>(this);
00801 e->signalEnumLiteralRemoved(el);
00802 emit modified();
00803 } else {
00804 index = -1;
00805 }
00806 break;
00807 }
00808 case Uml::ot_EntityAttribute: {
00809 UMLEntityAttribute* el = dynamic_cast<UMLEntityAttribute*>(m_List.take());
00810 if (el) {
00811 UMLEntity *e = static_cast<UMLEntity*>(this);
00812 e->signalEntityAttributeRemoved(el);
00813 emit modified();
00814 } else {
00815 index = -1;
00816 }
00817 break;
00818 }
00819 default:
00820 index = -1;
00821 break;
00822 }
00823 return index;
00824 }
00825
00826 void UMLClassifier::setOriginType(UMLClassifier *origType) {
00827 m_pSecondary = origType;
00828 }
00829
00830 UMLClassifier * UMLClassifier::originType() {
00831 return static_cast<UMLClassifier*>(m_pSecondary);
00832 }
00833
00834 void UMLClassifier::setIsReference(bool isRef) {
00835 m_isRef = isRef;
00836 }
00837
00838 bool UMLClassifier::isReference() {
00839 return m_isRef;
00840 }
00841
00842 UMLAssociationList UMLClassifier::getUniAssociationToBeImplemented() {
00843 UMLAssociationList associations = getSpecificAssocs(Uml::at_UniAssociation);
00844 UMLAssociationList uniAssocListToBeImplemented;
00845
00846 for(UMLAssociation *a = associations.first(); a; a = associations.next()) {
00847 if (a->getObjectId(Uml::B) == getID())
00848 continue;
00849
00850 QString roleNameB = a->getRoleName(Uml::B);
00851 if (!roleNameB.isEmpty()) {
00852 UMLAttributeList atl = getAttributeList();
00853 bool found = false;
00854
00855 for (UMLAttribute *at = atl.first(); at ; at = atl.next()) {
00856 if (at->getName() == roleNameB) {
00857 found = true;
00858 break;
00859 }
00860 }
00861 if (!found) {
00862 uniAssocListToBeImplemented.append(a);
00863 }
00864 }
00865 }
00866 return uniAssocListToBeImplemented;
00867 }
00868
00869 void UMLClassifier::saveToXMI(QDomDocument & qDoc, QDomElement & qElement) {
00870 QString tag;
00871 switch (m_BaseType) {
00872 case Uml::ot_Class:
00873 tag = "UML:Class";
00874 break;
00875 case Uml::ot_Interface:
00876 tag = "UML:Interface";
00877 break;
00878 case Uml::ot_Datatype:
00879 tag = "UML:DataType";
00880 break;
00881 default:
00882 kError() << "UMLClassifier::saveToXMI() internal error: basetype is "
00883 << m_BaseType << endl;
00884 return;
00885 }
00886 QDomElement classifierElement = UMLObject::save(tag, qDoc);
00887 if (m_BaseType == Uml::ot_Datatype && m_pSecondary != NULL)
00888 classifierElement.setAttribute( "elementReference",
00889 ID2STR(m_pSecondary->getID()) );
00890
00891
00892 UMLClassifierListItemList list = getFilteredList(Uml::ot_Template);
00893 if (list.count()) {
00894 QDomElement tmplElement = qDoc.createElement( "UML:ModelElement.templateParameter" );
00895 for (UMLClassifierListItem *tmpl = list.first(); tmpl; tmpl = list.next() ) {
00896 tmpl->saveToXMI(qDoc, tmplElement);
00897 }
00898 classifierElement.appendChild( tmplElement );
00899 }
00900
00901
00902 UMLAssociationList generalizations = getSpecificAssocs(Uml::at_Generalization);
00903 if (generalizations.count()) {
00904 QDomElement genElement = qDoc.createElement("UML:GeneralizableElement.generalization");
00905 for (UMLAssociation *a = generalizations.first(); a; a = generalizations.next()) {
00906
00907 if (m_nId != a->getObjectId(Uml::A))
00908 continue;
00909 QDomElement gElem = qDoc.createElement("UML:Generalization");
00910 gElem.setAttribute( "xmi.idref", ID2STR(a->getID()) );
00911 genElement.appendChild(gElem);
00912 }
00913 if (genElement.hasChildNodes())
00914 classifierElement.appendChild( genElement );
00915 }
00916
00917
00918 QDomElement featureElement = qDoc.createElement( "UML:Classifier.feature" );
00919 UMLClassifierListItemList attList = getFilteredList(Uml::ot_Attribute);
00920 for (UMLClassifierListItem *pAtt = attList.first(); pAtt; pAtt = attList.next() )
00921 pAtt -> saveToXMI( qDoc, featureElement );
00922
00923
00924 UMLOperationList opList = getOpList();
00925 for (UMLOperation *pOp = opList.first(); pOp; pOp = opList.next() )
00926 pOp -> saveToXMI( qDoc, featureElement );
00927 if (featureElement.hasChildNodes())
00928 classifierElement.appendChild( featureElement );
00929
00930
00931 if (m_objects.count()) {
00932 QDomElement ownedElement = qDoc.createElement( "UML:Namespace.ownedElement" );
00933 for (UMLObjectListIt oit(m_objects); oit.current(); ++oit) {
00934 UMLObject *obj = oit.current();
00935 obj->saveToXMI (qDoc, ownedElement);
00936 }
00937 classifierElement.appendChild( ownedElement );
00938 }
00939 qElement.appendChild( classifierElement );
00940 }
00941
00942 UMLClassifierListItem* UMLClassifier::makeChildObject(const QString& xmiTag) {
00943 UMLClassifierListItem* pObject = NULL;
00944 if (tagEq(xmiTag, "Operation")) {
00945 pObject = new UMLOperation(this);
00946 } else if (tagEq(xmiTag, "Attribute")) {
00947 if (getBaseType() != Uml::ot_Class)
00948 return NULL;
00949 pObject = new UMLAttribute(this);
00950 } else if (tagEq(xmiTag, "TemplateParameter")) {
00951 pObject = new UMLTemplate(this);
00952 }
00953 return pObject;
00954 }
00955
00956 bool UMLClassifier::load(QDomElement& element) {
00957 UMLClassifierListItem *child = NULL;
00958 m_SecondaryId = element.attribute( "elementReference", "" );
00959 if (!m_SecondaryId.isEmpty()) {
00960
00961 m_isRef = true;
00962 }
00963 bool totalSuccess = true;
00964 for (QDomNode node = element.firstChild(); !node.isNull();
00965 node = node.nextSibling()) {
00966 if (node.isComment())
00967 continue;
00968 element = node.toElement();
00969 QString tag = element.tagName();
00970 if (tagEq(tag, "ModelElement.templateParameter") ||
00971 tagEq(tag, "Classifier.feature") ||
00972 tagEq(tag, "Namespace.ownedElement") ||
00973 tagEq(tag, "Namespace.contents")) {
00974 load(element);
00975
00976
00977
00978 } else if ((child = makeChildObject(tag)) != NULL) {
00979 if (child->loadFromXMI(element)) {
00980 switch (child->getBaseType()) {
00981 case Uml::ot_Template:
00982 addTemplate( static_cast<UMLTemplate*>(child) );
00983 break;
00984 case Uml::ot_Operation:
00985 if (! addOperation(static_cast<UMLOperation*>(child)) ) {
00986 kError() << "UMLClassifier::load: error from addOperation(op)"
00987 << endl;
00988 delete child;
00989 totalSuccess = false;
00990 }
00991 break;
00992 case Uml::ot_Attribute:
00993 addAttribute( static_cast<UMLAttribute*>(child) );
00994 break;
00995 default:
00996 break;
00997 }
00998 } else {
00999 kWarning() << "UMLClassifier::load: failed to load " << tag << endl;
01000 delete child;
01001 totalSuccess = false;
01002 }
01003 } else if (!Model_Utils::isCommonXMIAttribute(tag)) {
01004 UMLDoc *umldoc = UMLApp::app()->getDocument();
01005 UMLObject *pObject = Object_Factory::makeObjectFromXMI(tag);
01006 if (pObject == NULL) {
01007
01008
01009 continue;
01010 }
01011 pObject->setUMLPackage(this);
01012 if (! pObject->loadFromXMI(element)) {
01013 removeObject(pObject);
01014 delete pObject;
01015 totalSuccess = false;
01016 }
01017 }
01018 }
01019 return totalSuccess;
01020 }
01021
01022
01023
01024 #include "classifier.moc"