00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00027
00028 #include "javaclassifiercodedocument.h"
00029
00030
00031 #include <kdebug.h>
00032 #include <qregexp.h>
00033
00034
00035 #include "javacodegenerator.h"
00036 #include "javacodecomment.h"
00037 #include "javaclassdeclarationblock.h"
00038 #include "javacodeclassfielddeclarationblock.h"
00039 #include "../classifier.h"
00040 #include "../codegenerationpolicy.h"
00041 #include "../uml.h"
00042
00043
00044
00045
00046 JavaClassifierCodeDocument::JavaClassifierCodeDocument ( UMLClassifier * concept )
00047 : ClassifierCodeDocument (concept) {
00048 init();
00049 }
00050
00051 JavaClassifierCodeDocument::~JavaClassifierCodeDocument ( ) { }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 JavaCodeGenerationPolicy * JavaClassifierCodeDocument::getJavaPolicy() {
00062 CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
00063 JavaCodeGenerationPolicy * policy = dynamic_cast<JavaCodeGenerationPolicy*>(pe);
00064 return policy;
00065 }
00066
00071
00072
00073
00074
00075
00076
00077 bool JavaClassifierCodeDocument::forceDoc () {
00078 return UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
00079 }
00080
00081
00082 QString JavaClassifierCodeDocument::getPath ( )
00083 {
00084
00085 QString path = getPackage();
00086
00087
00088 path.simplifyWhiteSpace();
00089
00090
00091 path.replace(QRegExp(" "), "_");
00092
00093 path.replace(QRegExp("\\."),"/");
00094 path.replace(QRegExp("::"), "/");
00095
00096 path.lower();
00097
00098 return path;
00099
00100 }
00101
00102
00103
00104
00105
00106 QString JavaClassifierCodeDocument::capitalizeFirstLetter(const QString &string)
00107 {
00108 return JavaCodeGenerator::capitalizeFirstLetter(string);
00109 }
00110
00111 QString JavaClassifierCodeDocument::getJavaClassName (const QString &name) {
00112 return capitalizeFirstLetter(CodeGenerator::cleanName(name));
00113 }
00114
00115
00116 void JavaClassifierCodeDocument::init ( ) {
00117
00118 setFileExtension(".java");
00119
00120
00121
00122
00123
00124 classDeclCodeBlock = 0;
00125 operationsBlock = 0;
00126 constructorBlock = 0;
00127
00128
00129 synchronize();
00130 }
00131
00135
00136
00137 bool JavaClassifierCodeDocument::addCodeOperation (CodeOperation * op ) {
00138
00139 if(!op->getParentOperation()->isLifeOperation())
00140 return operationsBlock->addTextBlock(op);
00141 else
00142 return constructorBlock->addTextBlock(op);
00143 }
00144
00145
00146
00147
00148
00149
00150 void JavaClassifierCodeDocument::loadChildTextBlocksFromNode ( QDomElement & root)
00151 {
00152
00153 QDomNode tnode = root.firstChild();
00154 QDomElement telement = tnode.toElement();
00155 bool loadCheckForChildrenOK = false;
00156 while( !telement.isNull() ) {
00157 QString nodeName = telement.tagName();
00158
00159 if( nodeName == "textblocks" ) {
00160
00161 QDomNode node = telement.firstChild();
00162 QDomElement element = node.toElement();
00163
00164
00165 loadCheckForChildrenOK = element.isNull() ? true : false;
00166
00167 while( !element.isNull() ) {
00168 QString name = element.tagName();
00169
00170 if( name == "codecomment" ) {
00171 CodeComment * block = new JavaCodeComment(this);
00172 block->loadFromXMI(element);
00173 if(!addTextBlock(block))
00174 {
00175 kError()<<"loadFromXMI : unable to add codeComment to :"<<this<<endl;
00176 block->deleteLater();
00177 } else
00178 loadCheckForChildrenOK= true;
00179 } else
00180 if( name == "codeaccessormethod" ||
00181 name == "ccfdeclarationcodeblock"
00182 ) {
00183 QString acctag = element.attribute("tag","");
00184
00185 TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
00186 if(!tb || !addTextBlock(tb))
00187 {
00188 kError()<<"loadFromXMI : unable to add codeclassfield child method to:"<<this<<endl;
00189
00190 } else
00191 loadCheckForChildrenOK= true;
00192
00193 } else
00194 if( name == "codeblock" ) {
00195 CodeBlock * block = newCodeBlock();
00196 block->loadFromXMI(element);
00197 if(!addTextBlock(block))
00198 {
00199 kError()<<"loadFromXMI : unable to add codeBlock to :"<<this<<endl;
00200 block->deleteLater();
00201 } else
00202 loadCheckForChildrenOK= true;
00203 } else
00204 if( name == "codeblockwithcomments" ) {
00205 CodeBlockWithComments * block = newCodeBlockWithComments();
00206 block->loadFromXMI(element);
00207 if(!addTextBlock(block))
00208 {
00209 kError()<<"loadFromXMI : unable to add codeBlockwithcomments to:"<<this<<endl;
00210 block->deleteLater();
00211 } else
00212 loadCheckForChildrenOK= true;
00213 } else
00214 if( name == "header" ) {
00215
00216 } else
00217 if( name == "hierarchicalcodeblock" ) {
00218 HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
00219 block->loadFromXMI(element);
00220 if(!addTextBlock(block))
00221 {
00222 kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
00223 block->deleteLater();
00224 } else
00225 loadCheckForChildrenOK= true;
00226 } else
00227 if( name == "codeoperation" ) {
00228
00229 QString id = element.attribute("parent_id","-1");
00230 UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
00231 UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
00232 if(op) {
00233 CodeOperation * block = new JavaCodeOperation(this, op);
00234 block->loadFromXMI(element);
00235 if(addTextBlock(block))
00236 loadCheckForChildrenOK= true;
00237 else
00238 {
00239 kError()<<"Unable to add codeoperation to:"<<this<<endl;
00240 block->deleteLater();
00241 }
00242 } else
00243 kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
00244 } else
00245 if( name == "javaclassdeclarationblock" )
00246 {
00247 JavaClassDeclarationBlock * block = getClassDecl();
00248 block->loadFromXMI(element);
00249 if(!addTextBlock(block))
00250 {
00251 kError()<<"Unable to add java code declaration block to:"<<this<<endl;
00252
00253
00254 } else
00255 loadCheckForChildrenOK= true;
00256 }
00257
00258
00259
00260
00261
00262 node = element.nextSibling();
00263 element = node.toElement();
00264 }
00265 break;
00266 }
00267
00268 tnode = telement.nextSibling();
00269 telement = tnode.toElement();
00270 }
00271
00272 if(!loadCheckForChildrenOK)
00273 {
00274 CodeDocument * test = dynamic_cast<CodeDocument*>(this);
00275 if(test)
00276 {
00277 kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
00278 } else {
00279 HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
00280 if(hb)
00281 kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
00282 else
00283 kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
00284 }
00285 }
00286
00287
00288 }
00289
00290 QString JavaClassifierCodeDocument::scopeToJavaDecl(Uml::Visibility scope)
00291 {
00292 QString scopeString;
00293 switch(scope)
00294 {
00295 case Uml::Visibility::Public:
00296 scopeString = "public";
00297 break;
00298 case Uml::Visibility::Protected:
00299 scopeString = "protected";
00300 break;
00301 case Uml::Visibility::Private:
00302 case Uml::Visibility::Implementation:
00303 default:
00304 scopeString = "private";
00305 break;
00306 }
00307 return scopeString;
00308 }
00309
00310 JavaClassDeclarationBlock * JavaClassifierCodeDocument::getClassDecl()
00311 {
00312 if(!classDeclCodeBlock)
00313 {
00314 classDeclCodeBlock = new JavaClassDeclarationBlock (this);
00315 classDeclCodeBlock->setTag("ClassDeclBlock");
00316 }
00317 return classDeclCodeBlock;
00318 }
00319
00320 void JavaClassifierCodeDocument::resetTextBlocks()
00321 {
00322
00323
00324 operationsBlock = 0;
00325 constructorBlock = 0;
00326 classDeclCodeBlock = 0;
00327
00328
00329 ClassifierCodeDocument::resetTextBlocks();
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 void JavaClassifierCodeDocument::updateContent( )
00340 {
00341
00342 UMLClassifier * c = getParentClassifier();
00343 CodeGenerationPolicy * commonPolicy = UMLApp::app()->getCommonPolicy();
00344 CodeGenPolicyExt * pe = UMLApp::app()->getPolicyExt();
00345 JavaCodeGenerationPolicy * policy = dynamic_cast<JavaCodeGenerationPolicy*>(pe);
00346
00347
00348
00349 CodeClassFieldList * cfList = getCodeClassFieldList();
00350 for(CodeClassField * field = cfList->first(); field; field = cfList->next())
00351 if(field->parentIsAttribute())
00352 field->setWriteOutMethods(policy->getAutoGenerateAttribAccessors());
00353 else
00354 field->setWriteOutMethods(policy->getAutoGenerateAssocAccessors());
00355
00356
00357
00358 CodeClassFieldList staticAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true);
00359 CodeClassFieldList attribClassFields = getSpecificClassFields (CodeClassField::Attribute, false);
00360
00361
00362 CodeClassFieldList plainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation );
00363 CodeClassFieldList aggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation );
00364 CodeClassFieldList compositionClassFields = getSpecificClassFields ( CodeClassField::Composition );
00365
00366 bool isInterface = parentIsInterface();
00367 bool hasOperationMethods = c->getOpList().last() ? true : false;
00368 QString endLine = commonPolicy->getNewLineEndingChars();
00369
00370
00371
00372
00373
00374
00375
00376
00377 QString pkgs = getPackage();
00378 pkgs.replace(QRegExp("::"), ".");
00379 QString packageText = getPackage().isEmpty() ? "" : "package "+pkgs+';'+endLine;
00380 CodeBlockWithComments * pblock = addOrUpdateTaggedCodeBlockWithComments("packages", packageText, "", 0, false);
00381 if(packageText.isEmpty() && pblock->getContentType() == CodeBlock::AutoGenerated)
00382 pblock->setWriteOutText(false);
00383 else
00384 pblock->setWriteOutText(true);
00385
00386
00387
00388
00389
00390
00391 QString importStatement = "";
00392 if ( hasObjectVectorClassFields() )
00393 importStatement.append("import java.util.*;");
00394
00395
00396 UMLPackageList imports;
00397 QMap<UMLPackage*, QString> packageMap;
00398
00399 CodeGenerator::findObjectsRelated(c,imports);
00400 for(UMLPackage *con = imports.first(); con ; con = imports.next())
00401
00402
00403
00404 if (!packageMap.contains(con) && con->getBaseType() != Uml::ot_Datatype)
00405 {
00406 packageMap.insert(con, con->getPackage());
00407
00408
00409
00410 if (con->getPackage() != c->getPackage() ||
00411 (c->getPackage().isEmpty() && con->getPackage().isEmpty()))
00412 {
00413 importStatement.append(endLine+"import ");
00414 if(!con->getPackage().isEmpty())
00415 importStatement.append(con->getPackage()+'.');
00416 importStatement.append(CodeGenerator::cleanName(con->getName())+';');
00417 }
00418 }
00419
00420 CodeBlockWithComments * iblock = addOrUpdateTaggedCodeBlockWithComments("imports", importStatement, "", 0, false);
00421 if(importStatement.isEmpty() && iblock->getContentType() == CodeBlock::AutoGenerated)
00422 iblock->setWriteOutText(false);
00423 else
00424 iblock->setWriteOutText(true);
00425
00426
00427
00428
00429
00430 JavaClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
00431 addTextBlock(myClassDeclCodeBlock);
00432
00433
00434
00435
00436
00437
00438
00439
00440
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 HierarchicalCodeBlock * fieldDeclBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("fieldsDecl", "Fields", 1);
00486
00487
00488 CodeComment * fcomment = fieldDeclBlock->getComment();
00489 if (isInterface || (!forceDoc() && !hasClassFields()) )
00490 fcomment->setWriteOutText(false);
00491 else
00492 fcomment->setWriteOutText(true);
00493
00494
00495 declareClassFields(staticAttribClassFields, fieldDeclBlock);
00496 declareClassFields(attribClassFields, fieldDeclBlock);
00497 declareClassFields(plainAssocClassFields, fieldDeclBlock);
00498 declareClassFields(aggregationClassFields, fieldDeclBlock);
00499 declareClassFields(compositionClassFields, fieldDeclBlock);
00500
00501
00502
00503
00504
00505
00506 HierarchicalCodeBlock * methodsBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("methodsBlock", "Methods", 1);
00507
00508
00509 CodeComment * methodsComment = methodsBlock->getComment();
00510
00511 if (!forceDoc() && !hasClassFields() && !hasOperationMethods)
00512 methodsComment->setWriteOutText(false);
00513 else
00514 methodsComment->setWriteOutText(true);
00515
00516
00517
00518
00519
00520 HierarchicalCodeBlock * constBlock = methodsBlock->getHierarchicalCodeBlock("constructorMethods", "Constructors", 1);
00521 constructorBlock = constBlock;
00522
00523
00524
00525 CodeComment * constComment = constBlock->getComment();
00526 CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();
00527 if (!forceDoc() && (isInterface || !pol->getAutoGenerateConstructors()))
00528 constComment->setWriteOutText(false);
00529 else
00530 constComment->setWriteOutText(true);
00531
00532
00533 QString JavaClassName = getJavaClassName(c->getName());
00534 QString emptyConstStatement = "public "+JavaClassName+" ( ) { }";
00535 CodeBlockWithComments * emptyConstBlock =
00536 constBlock->addOrUpdateTaggedCodeBlockWithComments("emptyconstructor", emptyConstStatement, "Empty Constructor", 1, false);
00537 // Now, as an additional condition we only show the empty constructor block
00538 // IF it was desired to be shown
00539 if(parentIsClass() && pol->getAutoGenerateConstructors())
00540 emptyConstBlock->setWriteOutText(true);
00541 else
00542 emptyConstBlock->setWriteOutText(false);
00543
00544 // METHODS subsection : ACCESSOR METHODS
00545 //
00546
00547 // get/create the accessor codeblock
00548 HierarchicalCodeBlock * accessorBlock = methodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
00549
00550 // set conditions for showing section comment
00551 CodeComment * accessComment = accessorBlock->getComment();
00552 if (!forceDoc() && !hasClassFields())
00553 accessComment->setWriteOutText(false);
00554 else
00555 accessComment->setWriteOutText(true);
00556
00557 // now, 2 sub-sub sections in accessor block
00558 // add/update accessor methods for attributes
00559 HierarchicalCodeBlock * staticAccessors = accessorBlock->getHierarchicalCodeBlock("staticAccessorMethods", "", 1);
00560 staticAccessors->getComment()->setWriteOutText(false); // never write block comment
00561 staticAccessors->addCodeClassFieldMethods(staticAttribClassFields);
00562 staticAccessors->addCodeClassFieldMethods(attribClassFields);
00563
00564 // add/update accessor methods for associations
00565 HierarchicalCodeBlock * regularAccessors = accessorBlock->getHierarchicalCodeBlock("regularAccessorMethods", "", 1);
00566 regularAccessors->getComment()->setWriteOutText(false); // never write block comment
00567 regularAccessors->addCodeClassFieldMethods(plainAssocClassFields);
00568 regularAccessors->addCodeClassFieldMethods(aggregationClassFields);
00569 regularAccessors->addCodeClassFieldMethods(compositionClassFields);
00570
00571 // METHODS subsection : Operation methods (which arent constructors)
00572 //
00573
00574 // get/create the operations codeblock
00575 operationsBlock = methodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
00576
00577 // set conditions for showing section comment
00578 CodeComment * ocomment = operationsBlock->getComment();
00579 if (!forceDoc() && !hasOperationMethods )
00580 ocomment->setWriteOutText(false);
00581 else
00582 ocomment->setWriteOutText(true);
00583
00584 }
00585
00586
00587 #include "javaclassifiercodedocument.moc"