codegenobjectwithtextblocks.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "codegenobjectwithtextblocks.h"
00019
00020
00021 #include <kdebug.h>
00022
00023
00024 #include "umldoc.h"
00025 #include "codedocument.h"
00026 #include "codeoperation.h"
00027 #include "codegenerators/codegenfactory.h"
00028 #include "classifiercodedocument.h"
00029 #include "hierarchicalcodeblock.h"
00030 #include "uml.h"
00031
00032
00033
00034
00035 CodeGenObjectWithTextBlocks::CodeGenObjectWithTextBlocks ( CodeDocument *parent )
00036 : m_pCodeDoc(parent)
00037 {
00038 initFields();
00039 }
00040
00041 CodeGenObjectWithTextBlocks::~CodeGenObjectWithTextBlocks ( ) {
00042 resetTextBlocks();
00043
00044 TextBlock *tb;
00045 for (TextBlockListIt it(m_textblockVector); (tb = it.current()) != NULL; ++it)
00046 delete tb;
00047
00048 m_textBlockTagMap.clear();
00049 m_textblockVector.clear();
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00065 TextBlockList * CodeGenObjectWithTextBlocks::getTextBlockList ( ) {
00066 return &m_textblockVector;
00067 }
00068
00069
00070
00071
00075 bool CodeGenObjectWithTextBlocks::addTextBlock(TextBlock* add_object ) {
00076
00077 QString tag = add_object->getTag();
00078
00079
00080 if(tag.isEmpty())
00081 {
00082 tag = getUniqueTag();
00083 add_object->setTag(tag);
00084 }
00085 else
00086 {
00087
00088
00089
00090 CodeDocument * parentDoc = add_object->getParentDocument();
00091 if(parentDoc) {
00092
00093 CodeGenObjectWithTextBlocks * oldParent = parentDoc->findParentObjectForTaggedTextBlock (tag);
00094 if(oldParent && oldParent != this)
00095 oldParent->removeTextBlock(add_object);
00096 }
00097 }
00098
00099 if(m_textBlockTagMap.contains(tag))
00100 return false;
00101
00102
00103
00104 m_textBlockTagMap.insert(tag, add_object);
00105 m_textblockVector.append(add_object);
00106
00107 return true;
00108 }
00109
00113 bool CodeGenObjectWithTextBlocks::removeTextBlock ( TextBlock * remove_object ) {
00114
00115
00116 if(!m_textblockVector.removeRef(remove_object))
00117 {
00118
00119 TextBlock * tb;
00120 for(TextBlockListIt it(m_textblockVector); (tb = it.current()) != NULL; ++it)
00121 {
00122 HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(tb);
00123 if(hb && hb->removeTextBlock(remove_object))
00124 return true;
00125 }
00126 }
00127
00128
00129 QString tag = remove_object->getTag();
00130 if(!tag.isEmpty())
00131 m_textBlockTagMap.erase(tag);
00132
00133 return true;
00134 }
00135
00136 TextBlock * CodeGenObjectWithTextBlocks::findTextBlockByTag( const QString &tag )
00137 {
00138
00139 if(m_textBlockTagMap.contains(tag))
00140 return m_textBlockTagMap[tag];
00141
00142 return (TextBlock*) NULL;
00143 }
00144
00145
00146
00147
00148
00149 CodeGenObjectWithTextBlocks * CodeGenObjectWithTextBlocks::findParentObjectForTaggedTextBlock (const QString & tag) {
00150
00151
00152 if(tag.isEmpty())
00153 return (CodeGenObjectWithTextBlocks*) NULL;
00154
00155 if(!findTextBlockByTag(tag))
00156 {
00157
00158 for(TextBlock * tb = m_textblockVector.first(); tb ; tb = m_textblockVector.next())
00159 {
00160 HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(tb);
00161 if(hb) {
00162 CodeGenObjectWithTextBlocks* cgowtb = dynamic_cast<CodeGenObjectWithTextBlocks*>(hb);
00163 CodeGenObjectWithTextBlocks * obj = cgowtb->findParentObjectForTaggedTextBlock(tag);
00164 if(obj)
00165 return obj;
00166 }
00167 }
00168
00169 } else
00170 return this;
00171
00172
00173
00174 return (CodeGenObjectWithTextBlocks*) NULL;
00175
00176 }
00177
00184 HierarchicalCodeBlock * CodeGenObjectWithTextBlocks::getHierarchicalCodeBlock ( const QString &tag, const QString &comment, int indentLevel ) {
00185
00186
00187 HierarchicalCodeBlock * codeBlock = dynamic_cast<HierarchicalCodeBlock*>(findTextBlockByTag(tag));
00188 if (!codeBlock) {
00189 codeBlock = newHierarchicalCodeBlock();
00190 codeBlock->setTag(tag);
00191 codeBlock->setComment(CodeGenFactory::newCodeComment(m_pCodeDoc));
00192
00193 if(comment.isEmpty())
00194 codeBlock->getComment()->setWriteOutText(false);
00195
00196 if(!addTextBlock(codeBlock))
00197 {
00198 delete codeBlock;
00199 return (HierarchicalCodeBlock*) NULL;
00200 }
00201 }
00202
00203 codeBlock->setOverallIndentationLevel (indentLevel);
00204 codeBlock->getComment()->setText(comment);
00205
00206 return codeBlock;
00207 }
00208
00209
00216 CodeBlockWithComments * CodeGenObjectWithTextBlocks::getCodeBlockWithComments ( const QString &tag, const QString &comment, int indentLevel ) {
00217
00218
00219 CodeBlockWithComments * codeBlock = dynamic_cast<CodeBlockWithComments*>(findTextBlockByTag(tag));
00220 if (!codeBlock) {
00221 codeBlock = newCodeBlockWithComments();
00222 codeBlock->setTag(tag);
00223 codeBlock->setComment(CodeGenFactory::newCodeComment(m_pCodeDoc));
00224
00225 if(comment.isEmpty())
00226 codeBlock->getComment()->setWriteOutText(false);
00227 if(!addTextBlock(codeBlock))
00228 return (CodeBlockWithComments*) NULL;
00229 }
00230 codeBlock->setOverallIndentationLevel (indentLevel);
00231 codeBlock->getComment()->setText(comment);
00232
00233 return codeBlock;
00234
00235 }
00236
00237
00244 CodeComment * CodeGenObjectWithTextBlocks::addOrUpdateTaggedCodeComment ( const QString &tag, const QString &text, int indentationLevel)
00245 {
00246
00247 TextBlock * tBlock = findTextBlockByTag(tag);
00248 CodeComment * codeComment = dynamic_cast<CodeComment*>(tBlock);
00249 bool createdCodeComment = false;
00250
00251 if(!codeComment) {
00252 createdCodeComment = true;
00253 codeComment = CodeGenFactory::newCodeComment(m_pCodeDoc);
00254 codeComment->setTag(tag);
00255 if(!addTextBlock(codeComment))
00256 {
00257 delete codeComment;
00258 return (CodeComment*) NULL;
00259 }
00260 }
00261
00262 codeComment->setText(text);
00263 if(createdCodeComment)
00264 if(!text.isEmpty())
00265 codeComment->setWriteOutText(true);
00266 else
00267 codeComment->setWriteOutText(false);
00268
00269 codeComment->setIndentationLevel(indentationLevel);
00270
00271 return codeComment;
00272 }
00273
00274
00283 CodeBlockWithComments * CodeGenObjectWithTextBlocks::addOrUpdateTaggedCodeBlockWithComments (const QString &tag, const QString &text, const QString &ctext, int indentLevel, bool forceUserBlockUpdate )
00284 {
00285
00286 TextBlock * tBlock = findTextBlockByTag(tag);
00287 CodeBlockWithComments * codeBlock = dynamic_cast<CodeBlockWithComments*>(tBlock);
00288 bool createdCodeBlock = false;
00289
00290 if(!codeBlock) {
00291 createdCodeBlock = true;
00292 codeBlock = newCodeBlockWithComments();
00293 codeBlock->setTag(tag);
00294 if(!addTextBlock(codeBlock))
00295 {
00296 delete codeBlock;
00297 return (CodeBlockWithComments*) NULL;
00298 }
00299 }
00300
00301
00302 if(forceUserBlockUpdate || codeBlock->getContentType() == CodeBlock::AutoGenerated)
00303 {
00304
00305 codeBlock->setText(text);
00306 codeBlock->getComment()->setText(ctext);
00307
00308
00309 if (createdCodeBlock)
00310 {
00311 if(!ctext.isEmpty())
00312 codeBlock->getComment()->setWriteOutText(true);
00313 else
00314 codeBlock->getComment()->setWriteOutText(false);
00315
00316 if(!text.isEmpty())
00317 codeBlock->setWriteOutText(true);
00318 else
00319 codeBlock->setWriteOutText(false);
00320 }
00321
00322 codeBlock->setOverallIndentationLevel(indentLevel);
00323
00324 }
00325
00326 return codeBlock;
00327
00328 }
00329
00330 void CodeGenObjectWithTextBlocks::resetTextBlocks() {
00331 TextBlock *tb;
00332 for (TextBlockListIt it(m_textblockVector); (tb = it.current()) != NULL; ++it)
00333 delete tb;
00334 m_textBlockTagMap.clear();
00335 m_textblockVector.clear();
00336 }
00337
00338
00339 void CodeGenObjectWithTextBlocks::setAttributesFromObject (CodeGenObjectWithTextBlocks * obj)
00340 {
00341 TextBlockList * list = obj->getTextBlockList();
00342 for (TextBlock * tb = list->first(); tb; tb=list->next())
00343 {
00344
00345
00346 }
00347 }
00348
00349 void CodeGenObjectWithTextBlocks::setAttributesOnNode (QDomDocument & doc, QDomElement & root) {
00350
00351
00352 QDomElement tblockElement = doc.createElement( "textblocks" );
00353
00354
00355 TextBlockList * tbList = getTextBlockList();
00356 for (TextBlock * block = tbList->first(); block; block= tbList->next())
00357 block->saveToXMI(doc, tblockElement);
00358
00359 root.appendChild( tblockElement);
00360
00361 }
00362
00366 void CodeGenObjectWithTextBlocks::setAttributesFromNode ( QDomElement & root)
00367 {
00368
00369
00370 resetTextBlocks();
00371
00372
00373 loadChildTextBlocksFromNode(root);
00374
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 void CodeGenObjectWithTextBlocks::loadChildTextBlocksFromNode ( QDomElement & root)
00384 {
00385
00386 QDomNode tnode = root.firstChild();
00387 QDomElement telement = tnode.toElement();
00388 bool loadCheckForChildrenOK = false;
00389 while( !telement.isNull() ) {
00390 QString nodeName = telement.tagName();
00391
00392 if( nodeName == "textblocks" ) {
00393
00394 QDomNode node = telement.firstChild();
00395 QDomElement element = node.toElement();
00396
00397
00398 loadCheckForChildrenOK = element.isNull() ? true : false;
00399
00400 while( !element.isNull() ) {
00401 QString name = element.tagName();
00402
00403 if( name == "codecomment" ) {
00404 CodeComment * block = CodeGenFactory::newCodeComment(m_pCodeDoc);
00405 block->loadFromXMI(element);
00406 if(!addTextBlock(block))
00407 {
00408 kError()<<"loadFromXMI: unable to add codeComment to :"<<this<<endl;
00409 delete block;
00410 } else
00411 loadCheckForChildrenOK= true;
00412 } else
00413 if( name == "codeaccessormethod" ||
00414 name == "ccfdeclarationcodeblock"
00415 ) {
00416 QString acctag = element.attribute("tag","");
00417
00418 TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
00419 if(!tb || !addTextBlock(tb))
00420 {
00421 kError()<<"loadFromXMI : unable to add code accessor/decl method block (tag:"<<acctag<<") to:"<<this<<endl;
00422
00423
00424 } else
00425 loadCheckForChildrenOK= true;
00426
00427 } else
00428 if( name == "codeblock" ) {
00429 CodeBlock * block = newCodeBlock();
00430 block->loadFromXMI(element);
00431 if(!addTextBlock(block))
00432 {
00433 kError()<<"loadFromXMI : unable to add codeBlock to :"<<this<<endl;
00434 delete block;
00435 } else
00436 loadCheckForChildrenOK= true;
00437 } else
00438 if( name == "codeblockwithcomments" ) {
00439 CodeBlockWithComments * block = newCodeBlockWithComments();
00440 block->loadFromXMI(element);
00441 if(!addTextBlock(block))
00442 {
00443 kError()<<"loadFromXMI : unable to add codeBlockwithcomments to:"<<this<<endl;
00444 delete block;
00445 } else
00446 loadCheckForChildrenOK= true;
00447 } else
00448 if( name == "header" ) {
00449
00450 } else
00451 if( name == "hierarchicalcodeblock" ) {
00452 HierarchicalCodeBlock * block = new HierarchicalCodeBlock(m_pCodeDoc);
00453 block->loadFromXMI(element);
00454 if(!addTextBlock(block))
00455 {
00456 kError()<<"loadFromXMI : unable to add hierarchicalcodeBlock to:"<<this<<endl;
00457 delete block;
00458 } else
00459 loadCheckForChildrenOK= true;
00460 } else
00461 if( name == "codeoperation" ) {
00462
00463 QString id = element.attribute("parent_id","-1");
00464 UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
00465 UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
00466 if(op) {
00467 CodeOperation * block = CodeGenFactory::newCodeOperation(dynamic_cast<ClassifierCodeDocument*>(m_pCodeDoc), op);
00468 block->loadFromXMI(element);
00469 if(addTextBlock(block))
00470 loadCheckForChildrenOK= true;
00471 else
00472 {
00473 kError()<<"loadFromXMI : unable to add codeoperation to:"<<this<<endl;
00474 delete block;
00475 }
00476 } else
00477 kError()<<"loadFromXMI : unable to create codeoperation for obj id:"<<id<<endl;
00478 }
00479
00480
00481
00482
00483
00484
00485 node = element.nextSibling();
00486 element = node.toElement();
00487 }
00488 break;
00489 }
00490
00491 tnode = telement.nextSibling();
00492 telement = tnode.toElement();
00493 }
00494
00495 if(!loadCheckForChildrenOK)
00496 {
00497 CodeDocument * test = dynamic_cast<CodeDocument*>(this);
00498 if(test)
00499 {
00500 kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
00501 } else {
00502 HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
00503 if(hb)
00504 kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
00505 else
00506 kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
00507 }
00508 }
00509
00510 }
00511
00512 void CodeGenObjectWithTextBlocks::initFields ( ) {
00513
00514 m_textblockVector.setAutoDelete(false);
00515
00516 }
00517
This file is part of the documentation for umbrello Version 3.1.0.