codeclassfield.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "codeclassfield.h"
00019
00020 #include <qregexp.h>
00021 #include <kdebug.h>
00022
00023 #include "association.h"
00024 #include "classifiercodedocument.h"
00025 #include "codegenerator.h"
00026 #include "attribute.h"
00027 #include "umlobject.h"
00028 #include "umlrole.h"
00029 #include "uml.h"
00030 #include "codegenerators/codegenfactory.h"
00031
00032
00033
00034
00035 CodeClassField::CodeClassField ( ClassifierCodeDocument * doc , UMLRole * role)
00036 : CodeParameter ( doc , (UMLObject*) role)
00037 {
00038
00039 setParentUMLObject(role);
00040 initFields(true);
00041
00042 }
00043
00044 CodeClassField::CodeClassField ( ClassifierCodeDocument * doc , UMLAttribute * attrib)
00045 : CodeParameter ( doc , (UMLObject*) attrib )
00046 {
00047
00048 setParentUMLObject(attrib);
00049 initFields(true);
00050
00051 }
00052
00053 CodeClassField::~CodeClassField ( ) {
00054
00055
00056 CodeAccessorMethodList list = m_methodVector;
00057 for(CodeAccessorMethod * m = list.first(); m ; m=list.next())
00058 {
00059 getParentDocument()->removeTextBlock(m);
00060 m->forceRelease();
00061 }
00062 list.clear();
00063
00064
00065 if(m_declCodeBlock)
00066 {
00067 getParentDocument()->removeTextBlock(m_declCodeBlock);
00068 m_declCodeBlock->forceRelease();
00069 delete m_declCodeBlock;
00070 }
00071
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 void CodeClassField::setParentUMLObject (UMLObject * obj) {
00083 UMLRole *role = dynamic_cast<UMLRole*>(obj);
00084 if(role) {
00085 UMLAssociation * parentAssoc = role->getParentAssociation();
00086 Uml::Association_Type atype = parentAssoc->getAssocType();
00087 m_parentIsAttribute = false;
00088
00089 if ( atype == Uml::at_Association || atype == Uml::at_Association_Self)
00090 m_classFieldType = PlainAssociation;
00091 else if (atype == Uml::at_Aggregation)
00092 m_classFieldType = Aggregation;
00093 else if (atype == Uml::at_Composition)
00094 m_classFieldType = Composition;
00095 } else {
00096 m_classFieldType = Attribute;
00097 m_parentIsAttribute = true;
00098 }
00099 }
00100
00101
00102
00103
00104 QString CodeClassField::getTypeName ( ) {
00105
00106 if (parentIsAttribute())
00107 {
00108 UMLAttribute * at = (UMLAttribute*) getParentObject();
00109 return at->getTypeName();
00110 } else {
00111 UMLRole * role = (UMLRole*) getParentObject();
00112 if(fieldIsSingleValue()) {
00113 return getUMLObjectName(role->getObject());
00114 } else {
00115 return role->getName();
00116 }
00117 }
00118 }
00119
00120
00121
00122 QString CodeClassField::getListObjectType() {
00123 QString type = QString ("");
00124 if (!parentIsAttribute())
00125 {
00126 UMLRole * role = dynamic_cast<UMLRole*>(getParentObject());
00127 type = getUMLObjectName(role->getObject());
00128 }
00129 return type;
00130 }
00131
00136 bool CodeClassField::parentIsAttribute ( ) {
00137 return m_parentIsAttribute;
00138
00139 }
00140
00144 CodeClassField::ClassFieldType CodeClassField::getClassFieldType() {
00145 return m_classFieldType;
00146 }
00147
00152
00153
00154
00155
00156
00157
00158
00159 QString CodeClassField::getUMLObjectName(UMLObject *obj)
00160 {
00161 return (obj!=0)?obj->getName():QString("NULL");
00162 }
00163
00167 bool CodeClassField::addMethod ( CodeAccessorMethod * add_object ) {
00168
00169 CodeAccessorMethod::AccessorType type = add_object->getType();
00170
00171 if(findMethodByType(type))
00172 return false;
00173
00174
00175
00176
00177
00178
00179
00180
00181 m_methodVector.append(add_object);
00182 return true;
00183 }
00184
00188 bool CodeClassField::removeMethod ( CodeAccessorMethod * remove_object ) {
00189
00190 m_methodVector.removeRef(remove_object);
00191 getParentDocument()->removeTextBlock(remove_object);
00192 return true;
00193 }
00194
00200 CodeAccessorMethodList CodeClassField::getMethodList() {
00201 return m_methodVector;
00202 }
00203
00208 bool CodeClassField::getWriteOutMethods ()
00209 {
00210 return m_writeOutMethods;
00211 }
00212
00213 void CodeClassField::setWriteOutMethods ( bool val )
00214 {
00215 m_writeOutMethods = val;
00216 updateContent();
00217 }
00218
00223 CodeClassFieldDeclarationBlock * CodeClassField::getDeclarationCodeBlock( )
00224 {
00225 return m_declCodeBlock;
00226 }
00227
00228
00229
00230
00234 void CodeClassField::loadFromXMI ( QDomElement & root ) {
00235 setAttributesFromNode(root);
00236 }
00237
00241 void CodeClassField::setAttributesOnNode ( QDomDocument & doc, QDomElement & cfElem)
00242 {
00243
00244
00245 CodeParameter::setAttributesOnNode(doc,cfElem);
00246
00247
00248 cfElem.setAttribute("field_type",m_classFieldType);
00249 cfElem.setAttribute("listClassName",m_listClassName);
00250 cfElem.setAttribute("writeOutMethods",getWriteOutMethods()?"true":"false");
00251
00252
00253
00254 m_declCodeBlock->saveToXMI(doc, cfElem);
00255
00256
00257 CodeAccessorMethod *method;
00258 for (CodeAccessorMethodListIt it(m_methodVector); (method = it.current()) != NULL; ++it)
00259 {
00260 method->saveToXMI(doc,cfElem);
00261 }
00262
00263 }
00264
00268 void CodeClassField::setAttributesFromNode ( QDomElement & root) {
00269
00270
00271 getParentObject()->disconnect(this);
00272
00273
00274 CodeParameter::setAttributesFromNode(root);
00275
00276
00277
00278 initFields( );
00279
00280 setWriteOutMethods(root.attribute("writeOutMethods","true") == "true" ? true : false);
00281 m_listClassName = root.attribute("listClassName","");
00282 m_classFieldType = (ClassFieldType) root.attribute("field_type","0").toInt();
00283
00284
00285
00286 QDomNode node = root.firstChild();
00287 QDomElement element = node.toElement();
00288 while( !element.isNull() ) {
00289 QString tag = element.tagName();
00290 if( tag == "ccfdeclarationcodeblock" ) {
00291 m_declCodeBlock->loadFromXMI(element);
00292 } else
00293 if( tag == "codeaccessormethod" ) {
00294 int type = element.attribute("accessType","0").toInt();
00295 int role_id = element.attribute("role_id","-1").toInt();
00296 CodeAccessorMethod * method = findMethodByType((CodeAccessorMethod::AccessorType) type, role_id);
00297 if(method)
00298 method->loadFromXMI(element);
00299 else
00300 kError()<<"Cant load code accessor method for type:"<<type<<" which doesn't exist in this codeclassfield. Is XMI out-dated or corrupt?"<<endl;
00301
00302 } else
00303 if( tag == "header" ) {
00304
00305 } else
00306 kWarning()<<"ERROR: bad savefile? code classfield loadFromXMI got child element with unknown tag:"<<tag<<" ignoring node."<<endl;
00307
00308 node = element.nextSibling();
00309 element = node.toElement();
00310 }
00311
00312 }
00313
00317 void CodeClassField::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
00318 QDomElement docElement = doc.createElement( "codeclassfield" );
00319
00320 setAttributesOnNode(doc, docElement);
00321
00322 root.appendChild( docElement );
00323 }
00324
00325 int CodeClassField::minimumListOccurances( ) {
00326 if (!parentIsAttribute())
00327 {
00328 UMLRole * role = dynamic_cast<UMLRole*>(getParentObject());
00329 QString multi = role->getMultiplicity();
00330
00331 if(!multi.isEmpty())
00332 {
00333 QString lowerBoundString = multi.remove(QRegExp("\\.\\.\\d+$"));
00334 if(!lowerBoundString.isEmpty() &&lowerBoundString.contains(QRegExp("^\\d+$")))
00335 return lowerBoundString.toInt();
00336 }
00337
00338 }
00339 return 0;
00340 }
00341
00342 int CodeClassField::maximumListOccurances( ) {
00343 if (!parentIsAttribute())
00344 {
00345 UMLRole * role = dynamic_cast<UMLRole*>(getParentObject());
00346 QString multi = role->getMultiplicity();
00347
00348 if(!multi.isEmpty())
00349 {
00350 QString upperBoundString = multi.section(QRegExp("(\\.\\.)"),1);
00351 if(!upperBoundString.isEmpty() && upperBoundString.contains(QRegExp("^\\d+$")))
00352 return upperBoundString.toInt();
00353 else
00354 return -1;
00355 } else
00356 return -1;
00357
00358 }
00359 return 1;
00360 }
00361
00362 QString CodeClassField::cleanName ( const QString &name ) {
00363 return getParentDocument()->cleanName(name);
00364 }
00365
00366 QString CodeClassField::fixInitialStringDeclValue(QString value, const QString &type)
00367 {
00368
00369 if (!value.isEmpty() && type == "String") {
00370 if (!value.startsWith("\""))
00371 value.prepend("\"");
00372 if (!value.endsWith("\""))
00373 value.append("\"");
00374 }
00375 return value;
00376 }
00377
00378 void CodeClassField::synchronize ()
00379 {
00380 updateContent();
00381 CodeAccessorMethod *method;
00382 for (CodeAccessorMethodListIt it(m_methodVector); (method = it.current()) != NULL; ++it)
00383 method->syncToParent();
00384
00385 if(m_declCodeBlock)
00386 m_declCodeBlock->syncToParent();
00387 }
00388
00389 CodeAccessorMethod * CodeClassField::findMethodByType ( CodeAccessorMethod::AccessorType type, int role_id)
00390 {
00391
00392
00393
00394
00395
00396
00397
00398 if(role_id > 1 || role_id < 0)
00399 {
00400 for (CodeAccessorMethod * m = m_methodVector.first(); m ; m= m_methodVector.next())
00401 if( m->getType() == type)
00402 return m;
00403 } else {
00404
00405
00406 for (CodeAccessorMethod * m = m_methodVector.first(); m ; m= m_methodVector.next())
00407 {
00408 UMLRole * role = dynamic_cast<UMLRole*>(m->getParentObject());
00409 if(!role)
00410 kError()<<" FindMethodByType() cant create role for method type:"<<m->getType()<<endl;
00411 if( role && m->getType() == type && role->getRole() == role_id)
00412 return m;
00413 }
00414
00415 }
00416
00417 return (CodeAccessorMethod *) NULL;
00418 }
00419
00420 void CodeClassField::initAccessorMethods()
00421 {
00422
00423
00424
00425 if(!findMethodByType(CodeAccessorMethod::GET))
00426 {
00427 CodeAccessorMethod * method = CodeGenFactory::newCodeAccessorMethod (getParentDocument(), this, CodeAccessorMethod::GET);
00428 if(method)
00429 {
00430 method->setType(CodeAccessorMethod::GET);
00431 addMethod(method);
00432 }
00433 }
00434
00435 if(!findMethodByType(CodeAccessorMethod::SET))
00436 {
00437 CodeAccessorMethod * method = CodeGenFactory::newCodeAccessorMethod (getParentDocument(), this, CodeAccessorMethod::SET);
00438 if(method) {
00439 method->setType(CodeAccessorMethod::SET);
00440 addMethod(method);
00441 }
00442 }
00443
00444
00445
00446 if (!parentIsAttribute()) {
00447
00448 if(!findMethodByType(CodeAccessorMethod::ADD))
00449 {
00450 CodeAccessorMethod * method = CodeGenFactory::newCodeAccessorMethod (getParentDocument(), this, CodeAccessorMethod::ADD);
00451 if(method) {
00452 method->setType(CodeAccessorMethod::ADD);
00453 addMethod(method);
00454 }
00455 }
00456
00457 if(!findMethodByType(CodeAccessorMethod::REMOVE))
00458 {
00459 CodeAccessorMethod * method = CodeGenFactory::newCodeAccessorMethod (getParentDocument(), this, CodeAccessorMethod::REMOVE);
00460 if(method) {
00461 method->setType(CodeAccessorMethod::REMOVE);
00462 addMethod(method);
00463 }
00464 }
00465
00466 if(!findMethodByType(CodeAccessorMethod::LIST))
00467 {
00468 CodeAccessorMethod * method = CodeGenFactory::newCodeAccessorMethod (getParentDocument(), this, CodeAccessorMethod::LIST);
00469 if(method) {
00470 method->setType(CodeAccessorMethod::LIST);
00471 addMethod(method);
00472 }
00473 }
00474
00475 }
00476
00477
00478 }
00479
00480 void CodeClassField::updateContent()
00481 {
00482
00483
00484
00485
00486
00487 if (parentIsAttribute())
00488 {
00489 for ( CodeAccessorMethod *method = m_methodVector.first(); method;
00490 method = m_methodVector.next() )
00491 method->setWriteOutText( m_writeOutMethods );
00492 return;
00493 }
00494 UMLRole * role = dynamic_cast<UMLRole*>(getParentObject());
00495 Uml::Changeability_Type changeType = role->getChangeability();
00496 bool isSingleValue = fieldIsSingleValue();
00497 bool isEmptyRole = role->getName().isEmpty() ? true : false;
00498
00499 for (CodeAccessorMethod * method = m_methodVector.first(); method; method=m_methodVector.next())
00500 {
00501
00502 CodeAccessorMethod::AccessorType type = method->getType();
00503
00504
00505
00506
00507 if(!m_writeOutMethods || isEmptyRole)
00508 {
00509 method->setWriteOutText(false);
00510 continue;
00511 }
00512
00513
00514 if(method->getContentType() != CodeBlock::AutoGenerated)
00515 continue;
00516
00517
00518
00519 if(isSingleValue)
00520 {
00521 switch(type) {
00522 case CodeAccessorMethod::SET:
00523
00524 if (changeType != Uml::chg_Frozen)
00525 method->setWriteOutText(true);
00526 else
00527 method->setWriteOutText(false);
00528 break;
00529 case CodeAccessorMethod::GET:
00530 method->setWriteOutText(true);
00531 break;
00532 case CodeAccessorMethod::ADD:
00533 case CodeAccessorMethod::REMOVE:
00534 case CodeAccessorMethod::LIST:
00535 default:
00536 method->setWriteOutText(false);
00537 break;
00538 }
00539 }
00540 else
00541 {
00542 switch(type) {
00543
00544 case CodeAccessorMethod::GET:
00545 case CodeAccessorMethod::SET:
00546 method->setWriteOutText(false);
00547 break;
00548 case CodeAccessorMethod::ADD:
00549
00550 if (changeType != Uml::chg_Frozen)
00551 method->setWriteOutText(true);
00552 else
00553 method->setWriteOutText(false);
00554 break;
00555 case CodeAccessorMethod::REMOVE:
00556
00557 if (changeType == Uml::chg_Changeable)
00558 method->setWriteOutText(true);
00559 else
00560 method->setWriteOutText(false);
00561 break;
00562 case CodeAccessorMethod::LIST:
00563 default:
00564 method->setWriteOutText(true);
00565 break;
00566 }
00567 }
00568 }
00569 }
00570
00571
00572
00573
00574 bool CodeClassField::fieldIsSingleValue ( )
00575 {
00576
00577
00578 if(parentIsAttribute())
00579 return true;
00580
00581 UMLRole * role = dynamic_cast<UMLRole*>(getParentObject());
00582 if(!role)
00583 return true;
00584
00585 QString multi = role->getMultiplicity();
00586
00587 if(multi.isEmpty() || multi.contains(QRegExp("^(0|1)$"))
00588 || multi.contains(QRegExp("^0\\.\\.1$")))
00589 return true;
00590
00591 return false;
00592 }
00593
00594 void CodeClassField::initFields(bool inConstructor) {
00595
00596 m_writeOutMethods = false;
00597 m_listClassName = QString ("");
00598 m_declCodeBlock = NULL;
00599
00600 m_methodVector.setAutoDelete(false);
00601
00602
00603 if (!inConstructor)
00604 finishInitialization();
00605 }
00606
00607 void CodeClassField::finishInitialization() {
00608 m_declCodeBlock = CodeGenFactory::newDeclarationCodeBlock(getParentDocument(), this);
00609 initAccessorMethods();
00610 updateContent();
00611
00612 connect(getParentObject(),SIGNAL(modified()),this,SIGNAL(modified()));
00613
00614 }
00615
00616 #include "codeclassfield.moc"
This file is part of the documentation for umbrello Version 3.1.0.