00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00028
00029 #include "rubyclassifiercodedocument.h"
00030
00031
00032 #include <qregexp.h>
00033 #include <kdebug.h>
00034
00035
00036 #include "rubycodegenerator.h"
00037 #include "rubycodecomment.h"
00038 #include "rubyclassdeclarationblock.h"
00039 #include "rubycodeclassfielddeclarationblock.h"
00040 #include "rubycodeoperation.h"
00041 #include "../classifier.h"
00042 #include "../uml.h"
00043
00044
00045
00046
00047 RubyClassifierCodeDocument::RubyClassifierCodeDocument ( UMLClassifier * concept )
00048 : ClassifierCodeDocument (concept) {
00049 init();
00050 }
00051
00052 RubyClassifierCodeDocument::~RubyClassifierCodeDocument ( ) { }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 RubyCodeGenerationPolicy * RubyClassifierCodeDocument::getRubyPolicy() {
00063 CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
00064 RubyCodeGenerationPolicy * policy = dynamic_cast<RubyCodeGenerationPolicy*>(pe);
00065 return policy;
00066 }
00067
00072
00073
00074
00075
00076
00077
00078
00079 QString RubyClassifierCodeDocument::getPath ( )
00080 {
00081
00082 QString path = getPackage();
00083
00084
00085 path.simplifyWhiteSpace();
00086
00087
00088 path.replace(QRegExp(" "), "_");
00089
00090 path.replace(QRegExp("\\."),"/");
00091 path.replace(QRegExp("::"), "/");
00092
00093 path.lower();
00094
00095 return path;
00096
00097 }
00098
00099
00100
00101
00102
00103 QString RubyClassifierCodeDocument::capitalizeFirstLetter(const QString &string)
00104 {
00105 CodeGenerator *g = UMLApp::app()->getGenerator();
00106 RubyCodeGenerator * gen = dynamic_cast<RubyCodeGenerator *>(g);
00107 return gen->capitalizeFirstLetter(string);
00108 }
00109
00110 QString RubyClassifierCodeDocument::getRubyClassName (const QString &name) {
00111 CodeGenerator *g = UMLApp::app()->getGenerator();
00112 return capitalizeFirstLetter(g->cleanName(name));
00113 }
00114
00115
00116 void RubyClassifierCodeDocument::init ( ) {
00117
00118 setFileExtension(".rb");
00119
00120
00121
00122
00123
00124 classDeclCodeBlock = 0;
00125 publicBlock = 0;
00126 protectedBlock = 0;
00127 privateBlock = 0;
00128 pubConstructorBlock = 0;
00129 protConstructorBlock = 0;
00130 privConstructorBlock = 0;
00131 pubOperationsBlock = 0;
00132 privOperationsBlock = 0;
00133 protOperationsBlock = 0;
00134
00135
00136 synchronize();
00137 }
00138
00142
00143
00144 bool RubyClassifierCodeDocument::addCodeOperation (CodeOperation * op )
00145 {
00146 Uml::Visibility scope = op->getParentOperation()->getVisibility();
00147 if(!op->getParentOperation()->isConstructorOperation())
00148 {
00149 switch (scope) {
00150 default:
00151 case Uml::Visibility::Public:
00152 return pubOperationsBlock->addTextBlock(op);
00153 break;
00154 case Uml::Visibility::Protected:
00155 return protOperationsBlock->addTextBlock(op);
00156 break;
00157 case Uml::Visibility::Private:
00158 return privOperationsBlock->addTextBlock(op);
00159 break;
00160 }
00161 } else {
00162 switch (scope) {
00163 default:
00164 case Uml::Visibility::Public:
00165 return pubConstructorBlock->addTextBlock(op);
00166 break;
00167 case Uml::Visibility::Protected:
00168 return protConstructorBlock->addTextBlock(op);
00169 break;
00170 case Uml::Visibility::Private:
00171 return privConstructorBlock->addTextBlock(op);
00172 break;
00173 }
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182 void RubyClassifierCodeDocument::loadChildTextBlocksFromNode ( QDomElement & root)
00183 {
00184
00185 QDomNode tnode = root.firstChild();
00186 QDomElement telement = tnode.toElement();
00187 bool loadCheckForChildrenOK = false;
00188 while( !telement.isNull() ) {
00189 QString nodeName = telement.tagName();
00190
00191 if( nodeName == "textblocks" ) {
00192
00193 QDomNode node = telement.firstChild();
00194 QDomElement element = node.toElement();
00195
00196
00197 loadCheckForChildrenOK = element.isNull() ? true : false;
00198
00199 while( !element.isNull() ) {
00200 QString name = element.tagName();
00201
00202 if( name == "codecomment" ) {
00203 CodeComment * block = new RubyCodeComment(this);
00204 block->loadFromXMI(element);
00205 if(!addTextBlock(block))
00206 {
00207 kError()<<"loadFromXMI : unable to add codeComment to :"<<this<<endl;
00208 block->deleteLater();
00209 } else
00210 loadCheckForChildrenOK= true;
00211 } else
00212 if( name == "codeaccessormethod" ||
00213 name == "ccfdeclarationcodeblock"
00214 ) {
00215 QString acctag = element.attribute("tag","");
00216
00217 TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
00218 if(!tb || !addTextBlock(tb))
00219 {
00220 kError()<<"loadFromXMI : unable to add codeclassfield child method to:"<<this<<endl;
00221
00222 } else
00223 loadCheckForChildrenOK= true;
00224
00225 } else
00226 if( name == "codeblock" ) {
00227 CodeBlock * block = newCodeBlock();
00228 block->loadFromXMI(element);
00229 if(!addTextBlock(block))
00230 {
00231 kError()<<"loadFromXMI : unable to add codeBlock to :"<<this<<endl;
00232 block->deleteLater();
00233 } else
00234 loadCheckForChildrenOK= true;
00235 } else
00236 if( name == "codeblockwithcomments" ) {
00237 CodeBlockWithComments * block = newCodeBlockWithComments();
00238 block->loadFromXMI(element);
00239 if(!addTextBlock(block))
00240 {
00241 kError()<<"loadFromXMI : unable to add codeBlockwithcomments to:"<<this<<endl;
00242 block->deleteLater();
00243 } else
00244 loadCheckForChildrenOK= true;
00245 } else
00246 if( name == "header" ) {
00247
00248 } else
00249 if( name == "hierarchicalcodeblock" ) {
00250 HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
00251 block->loadFromXMI(element);
00252 if(!addTextBlock(block))
00253 {
00254 kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
00255 block->deleteLater();
00256 } else
00257 loadCheckForChildrenOK= true;
00258 } else
00259 if( name == "codeoperation" ) {
00260
00261 QString id = element.attribute("parent_id","-1");
00262 UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
00263 UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
00264 if(op) {
00265 CodeOperation * block = new RubyCodeOperation(this, op);
00266 block->loadFromXMI(element);
00267 if(addTextBlock(block))
00268 loadCheckForChildrenOK= true;
00269 else
00270 {
00271 kError()<<"Unable to add codeoperation to:"<<this<<endl;
00272 block->deleteLater();
00273 }
00274 } else
00275 kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
00276 } else
00277 if( name == "rubyclassdeclarationblock" )
00278 {
00279 RubyClassDeclarationBlock * block = getClassDecl();
00280 block->loadFromXMI(element);
00281 if(!addTextBlock(block))
00282 {
00283 kError()<<"Unable to add ruby code declaration block to:"<<this<<endl;
00284
00285
00286 } else
00287 loadCheckForChildrenOK= true;
00288 }
00289
00290
00291
00292
00293
00294 node = element.nextSibling();
00295 element = node.toElement();
00296 }
00297 break;
00298 }
00299
00300 tnode = telement.nextSibling();
00301 telement = tnode.toElement();
00302 }
00303
00304 if(!loadCheckForChildrenOK)
00305 {
00306 CodeDocument * test = dynamic_cast<CodeDocument*>(this);
00307 if(test)
00308 {
00309 kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
00310 } else {
00311 HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
00312 if(hb)
00313 kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
00314 else
00315 kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
00316 }
00317 }
00318
00319
00320 }
00321
00322 QString RubyClassifierCodeDocument::scopeToRubyDecl(Uml::Visibility scope)
00323 {
00324 QString scopeString;
00325 switch(scope)
00326 {
00327 case Uml::Visibility::Public:
00328 scopeString = "public";
00329 break;
00330 case Uml::Visibility::Protected:
00331 scopeString = "protected";
00332 break;
00333 case Uml::Visibility::Private:
00334 default:
00335 scopeString = "private";
00336 break;
00337 }
00338 return scopeString;
00339 }
00340
00341 RubyClassDeclarationBlock * RubyClassifierCodeDocument::getClassDecl()
00342 {
00343 if(!classDeclCodeBlock)
00344 {
00345 classDeclCodeBlock = new RubyClassDeclarationBlock (this);
00346 classDeclCodeBlock->setTag("ClassDeclBlock");
00347 }
00348 return classDeclCodeBlock;
00349 }
00350
00351 void RubyClassifierCodeDocument::resetTextBlocks()
00352 {
00353
00354
00355 operationsBlock = 0;
00356 constructorBlock = 0;
00357 classDeclCodeBlock = 0;
00358
00359
00360 ClassifierCodeDocument::resetTextBlocks();
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370 void RubyClassifierCodeDocument::updateContent( )
00371 {
00372
00373 UMLClassifier * c = getParentClassifier();
00374 RubyCodeGenerator * gen = dynamic_cast<RubyCodeGenerator*>(UMLApp::app()->getGenerator());
00375
00376
00377
00378 CodeClassFieldList * cfList = getCodeClassFieldList();
00379 for(CodeClassField * field = cfList->first(); field; field = cfList->next())
00380 if(field->parentIsAttribute())
00381 field->setWriteOutMethods(gen->getAutoGenerateAttribAccessors());
00382 else
00383 field->setWriteOutMethods(gen->getAutoGenerateAssocAccessors());
00384
00385
00386
00387 CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public );
00388 CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public );
00389 CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected );
00390 CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected );
00391 CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private );
00392 CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private);
00393
00394
00395
00396 CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Public);
00397 CodeClassFieldList publicAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Public);
00398 CodeClassFieldList publicCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Public );
00399
00400 CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Protected);
00401 CodeClassFieldList protAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Protected);
00402 CodeClassFieldList protCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Protected);
00403
00404 CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Private);
00405 CodeClassFieldList privAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Private);
00406 CodeClassFieldList privCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Private);
00407
00408 bool isInterface = parentIsInterface();
00409 bool hasOperationMethods = c->getOpList().last() ? true : false;
00410 CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();
00411 QString endLine = pol->getNewLineEndingChars();
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 RubyClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
00423 addTextBlock(myClassDeclCodeBlock);
00424
00425
00426
00427 bool createdPublicBlock = publicBlock == 0 ? true : false;
00428 publicBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("publicBlock","Public Items",0);
00429 if (createdPublicBlock)
00430 publicBlock->setStartText("public");
00431
00432 bool createdProtBlock = protectedBlock == 0 ? true : false;
00433 protectedBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("protectedBlock","Protected Items",0);
00434 if(createdProtBlock)
00435 protectedBlock->setStartText("protected");
00436
00437 bool createdPrivBlock = privateBlock == 0 ? true : false;
00438 privateBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("privateBlock","Private Items",0);
00439 if(createdPrivBlock)
00440 privateBlock->setStartText("private");
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 HierarchicalCodeBlock * pubMethodsBlock = publicBlock->getHierarchicalCodeBlock("pubMethodsBlock", "", 1);
00491 CodeComment * pubMethodsComment = pubMethodsBlock->getComment();
00492 bool forceDoc = pol->getCodeVerboseDocumentComments();
00493
00494 if (!forceDoc && !hasClassFields() && !hasOperationMethods)
00495 pubMethodsComment->setWriteOutText(false);
00496 else
00497 pubMethodsComment->setWriteOutText(true);
00498
00499
00500 HierarchicalCodeBlock * protMethodsBlock = protectedBlock->getHierarchicalCodeBlock("protMethodsBlock", "", 1);
00501 CodeComment * protMethodsComment = protMethodsBlock->getComment();
00502
00503 if (!forceDoc && !hasClassFields() && !hasOperationMethods)
00504 protMethodsComment->setWriteOutText(false);
00505 else
00506 protMethodsComment->setWriteOutText(true);
00507
00508
00509 HierarchicalCodeBlock * privMethodsBlock = privateBlock->getHierarchicalCodeBlock("privMethodsBlock", "", 1);
00510 CodeComment * privMethodsComment = privMethodsBlock->getComment();
00511
00512 if (!forceDoc && !hasClassFields() && !hasOperationMethods)
00513 privMethodsComment->setWriteOutText(false);
00514 else
00515 privMethodsComment->setWriteOutText(true);
00516
00517
00518
00519
00520
00521 pubConstructorBlock = pubMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
00522
00523
00524 CodeComment * pubConstComment = pubConstructorBlock->getComment();
00525 if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
00526 pubConstComment->setWriteOutText(false);
00527 else
00528 pubConstComment->setWriteOutText(true);
00529
00530
00531 protConstructorBlock = protMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
00532
00533
00534 CodeComment * protConstComment = protConstructorBlock->getComment();
00535 if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
00536 protConstComment->setWriteOutText(false);
00537 else
00538 protConstComment->setWriteOutText(true);
00539
00540
00541 privConstructorBlock = privMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
00542
00543
00544 CodeComment * privConstComment = privConstructorBlock->getComment();
00545 if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
00546 privConstComment->setWriteOutText(false);
00547 else
00548 privConstComment->setWriteOutText(true);
00549
00550
00551
00552 HierarchicalCodeBlock * pubAccessorBlock = pubMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
00553
00554 CodeComment * pubAccessComment = pubAccessorBlock->getComment();
00555 if (!forceDoc && !hasClassFields())
00556 pubAccessComment->setWriteOutText(false);
00557 else
00558 pubAccessComment->setWriteOutText(true);
00559
00560
00561 HierarchicalCodeBlock * protAccessorBlock = protMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
00562
00563 CodeComment * protAccessComment = protAccessorBlock->getComment();
00564 if (!forceDoc && !hasClassFields())
00565 protAccessComment->setWriteOutText(false);
00566 else
00567 protAccessComment->setWriteOutText(true);
00568
00569
00570 HierarchicalCodeBlock * privAccessorBlock = privMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
00571
00572 CodeComment * privAccessComment = privAccessorBlock->getComment();
00573 if (!forceDoc && !hasClassFields())
00574 privAccessComment->setWriteOutText(false);
00575 else
00576 privAccessComment->setWriteOutText(true);
00577
00578
00579
00580 HierarchicalCodeBlock * pubStaticAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubStaticAccessorMethods", "", 1);
00581 HierarchicalCodeBlock * pubRegularAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubRegularAccessorMethods", "", 1);
00582 pubStaticAccessors->getComment()->setWriteOutText(false);
00583 pubRegularAccessors->getComment()->setWriteOutText(false);
00584
00585 HierarchicalCodeBlock * protStaticAccessors = protAccessorBlock->getHierarchicalCodeBlock("protStaticAccessorMethods", "", 1);
00586 HierarchicalCodeBlock * protRegularAccessors = protAccessorBlock->getHierarchicalCodeBlock("protRegularAccessorMethods", "", 1);
00587 protStaticAccessors->getComment()->setWriteOutText(false);
00588 protRegularAccessors->getComment()->setWriteOutText(false);
00589
00590 HierarchicalCodeBlock * privStaticAccessors = privAccessorBlock->getHierarchicalCodeBlock("privStaticAccessorMethods", "", 1);
00591 HierarchicalCodeBlock * privRegularAccessors = privAccessorBlock->getHierarchicalCodeBlock("privRegularAccessorMethods", "", 1);
00592 privStaticAccessors->getComment()->setWriteOutText(false);
00593 privRegularAccessors->getComment()->setWriteOutText(false);
00594
00595
00596
00597 pubStaticAccessors->addCodeClassFieldMethods(staticPublicAttribClassFields);
00598 pubRegularAccessors->addCodeClassFieldMethods(publicAttribClassFields);
00599 pubRegularAccessors->addCodeClassFieldMethods(publicPlainAssocClassFields);
00600 pubRegularAccessors->addCodeClassFieldMethods(publicAggregationClassFields);
00601 pubRegularAccessors->addCodeClassFieldMethods(publicCompositionClassFields);
00602
00603
00604 protStaticAccessors->addCodeClassFieldMethods(staticProtectedAttribClassFields);
00605 protRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
00606 protRegularAccessors->addCodeClassFieldMethods(protPlainAssocClassFields);
00607 protRegularAccessors->addCodeClassFieldMethods(protAggregationClassFields);
00608 protRegularAccessors->addCodeClassFieldMethods(protCompositionClassFields);
00609
00610
00611 privStaticAccessors->addCodeClassFieldMethods(staticPrivateAttribClassFields);
00612 privRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
00613 privRegularAccessors->addCodeClassFieldMethods(privPlainAssocClassFields);
00614 privRegularAccessors->addCodeClassFieldMethods(privAggregationClassFields);
00615 privRegularAccessors->addCodeClassFieldMethods(privCompositionClassFields);
00616
00617
00618
00619
00620
00621
00622
00623 pubOperationsBlock = pubMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
00624
00625 CodeComment * pubOcomment = pubOperationsBlock->getComment();
00626 if (!forceDoc && !hasOperationMethods )
00627 pubOcomment->setWriteOutText(false);
00628 else
00629 pubOcomment->setWriteOutText(true);
00630
00631
00632 protOperationsBlock = protMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
00633
00634 CodeComment * protOcomment = protOperationsBlock->getComment();
00635 if (!forceDoc && !hasOperationMethods )
00636 protOcomment->setWriteOutText(false);
00637 else
00638 protOcomment->setWriteOutText(true);
00639
00640
00641 privOperationsBlock = privMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
00642
00643 CodeComment * privOcomment = privOperationsBlock->getComment();
00644 if (!forceDoc && !hasOperationMethods )
00645 privOcomment->setWriteOutText(false);
00646 else
00647 privOcomment->setWriteOutText(true);
00648
00649 }
00650
00651
00652 #include "rubyclassifiercodedocument.moc"