umbrello API Documentation

classifiercodedocument.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   copyright (C) 2004-2007                                               *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 /*  This code generated by:
00013  *      Author : thomas
00014  *      Date   : Thu Jun 19 2003
00015  */
00016 
00017 // own header
00018 #include "classifiercodedocument.h"
00019 
00020 // qt/kde includes
00021 #include <kdebug.h>
00022 #include <qregexp.h>
00023 
00024 // local includes
00025 #include "association.h"
00026 #include "attribute.h"
00027 #include "operation.h"
00028 #include "classifierlistitem.h"
00029 #include "classifier.h"
00030 #include "codegenerator.h"
00031 #include "uml.h"
00032 #include "umldoc.h"
00033 #include "umlrole.h"
00034 #include "umlattributelist.h"
00035 #include "umloperationlist.h"
00036 #include "codegenerators/codegenfactory.h"
00037 
00038 // Constructors/Destructors
00039 //
00040 
00041 ClassifierCodeDocument::ClassifierCodeDocument ( UMLClassifier * parent )
00042 {
00043     init (parent);
00044 }
00045 
00046 ClassifierCodeDocument::~ClassifierCodeDocument ( )
00047 {
00048     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00049     {
00050         CodeClassField * cf = ccflit.current();
00051         delete cf;
00052     }
00053     m_classfieldVector.clear();
00054 }
00055 
00056 //
00057 // Methods
00058 //
00059 
00060 
00061 // Accessor methods
00062 //
00063 
00066 CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType)
00067 {
00068     CodeClassFieldList list;
00069     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00070     {
00071         CodeClassField * cf = ccflit.current();
00072         if (cf->getClassFieldType() == cfType)
00073             list.append(cf);
00074     }
00075     return list;
00076 }
00077 
00080 CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType, bool isStatic)
00081 {
00082     CodeClassFieldList list;
00083     list.setAutoDelete(false);
00084     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00085     {
00086         CodeClassField * cf = ccflit.current();
00087         if (cf->getClassFieldType() == cfType && cf->getStatic() == isStatic)
00088             list.append(cf);
00089     }
00090     return list;
00091 }
00092 
00095 CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType, Uml::Visibility visibility)
00096 {
00097     CodeClassFieldList list;
00098     list.setAutoDelete(false);
00099     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00100     {
00101         CodeClassField * cf = ccflit.current();
00102         if (cf->getClassFieldType() == cfType && cf->getVisibility() == visibility)
00103             list.append(cf);
00104     }
00105     return list;
00106 }
00107 
00110 CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType, bool isStatic, Uml::Visibility visibility)
00111 {
00112     CodeClassFieldList list;
00113     list.setAutoDelete(false);
00114     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00115     {
00116         CodeClassField * cf = ccflit.current();
00117         if (cf->getClassFieldType() == cfType && cf->getVisibility() == visibility && cf->getStatic() == isStatic )
00118             list.append(cf);
00119     }
00120     return list;
00121 }
00122 
00123 // do we have accessor methods for lists of objects?
00124 // (as opposed to lists of primitive types like 'int' or 'float', etc)
00125 bool ClassifierCodeDocument::hasObjectVectorClassFields() {
00126     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00127     {
00128         CodeClassField * cf = ccflit.current();
00129         if(cf->getClassFieldType() != CodeClassField::Attribute)
00130         {
00131             UMLRole * role = dynamic_cast<UMLRole*>(cf->getParentObject());
00132             QString multi = role->getMultiplicity();
00133             if (
00134                 multi.contains(QRegExp("[23456789\\*]")) ||
00135                 multi.contains(QRegExp("1\\d"))
00136             )
00137                 return true;
00138         }
00139     }
00140     return false;
00141 }
00142 
00143 bool ClassifierCodeDocument::hasClassFields() {
00144     if(m_classfieldVector.count() > 0 )
00145         return true;
00146     return false;
00147 }
00148 
00152 bool ClassifierCodeDocument::hasAssociationClassFields() {
00153     CodeClassFieldList list = getSpecificClassFields(CodeClassField::Attribute);
00154     return (m_classfieldVector.count() - list.count()) > 0 ? true : false;
00155 }
00156 
00160 bool ClassifierCodeDocument::hasAttributeClassFields() {
00161     CodeClassFieldList list = getSpecificClassFields(CodeClassField::Attribute);
00162     return list.count() > 0 ? true : false;
00163 }
00164 
00169 // We DON'T add methods of the code classfield here because we need to allow
00170 // the codegenerator writer the liberty to organize their document as they desire.
00171 bool ClassifierCodeDocument::addCodeClassField ( CodeClassField * add_object ) {
00172     UMLObject * umlobj = add_object->getParentObject();
00173     if(!(m_classFieldMap.contains(umlobj)))
00174     {
00175         m_classfieldVector.append(add_object);
00176         m_classFieldMap.insert(umlobj,add_object);
00177 
00178         return true;
00179     }
00180     return false;
00181 }
00182 
00183 // this is a slot..should only be called from a signal
00184 void ClassifierCodeDocument::addAttributeClassField (UMLClassifierListItem *obj, bool syncToParentIfAdded) {
00185     UMLAttribute *at = (UMLAttribute*)obj;
00186     CodeClassField * cf = CodeGenFactory::newCodeClassField(this, at);
00187     if(cf)
00188         if (addCodeClassField(cf) && syncToParentIfAdded)
00189             updateContent();
00190 }
00191 
00195 bool ClassifierCodeDocument::removeCodeClassField ( CodeClassField * remove_object ) {
00196     UMLObject * umlobj = remove_object->getParentObject();
00197     if(m_classFieldMap.contains(umlobj))
00198     {
00199         if (m_classfieldVector.removeRef(remove_object))
00200         {
00201             // remove from our classfield map
00202             m_classFieldMap.remove(umlobj);
00203             delete remove_object;
00204             return true;
00205         }
00206     }
00207     return false;
00208 }
00209 
00210 void ClassifierCodeDocument::removeAttributeClassField(UMLClassifierListItem *obj)
00211 {
00212     CodeClassField * remove_object = m_classFieldMap[obj];
00213     if(remove_object)
00214         removeCodeClassField(remove_object);
00215 }
00216 
00217 void ClassifierCodeDocument::removeAssociationClassField (UMLAssociation *assoc )
00218 {
00219 
00220     // the object could be either (or both!) role a or b. We should check
00221     // both parts of the association.
00222     CodeClassField * remove_object = m_classFieldMap[assoc->getUMLRole(Uml::A)];
00223     if(remove_object)
00224         removeCodeClassField(remove_object);
00225 
00226     // check role b
00227     remove_object = m_classFieldMap[assoc->getUMLRole(Uml::B)];
00228     if(remove_object)
00229         removeCodeClassField(remove_object);
00230 
00231 }
00232 
00238 CodeClassFieldList * ClassifierCodeDocument::getCodeClassFieldList ( ) {
00239     return &m_classfieldVector;
00240 }
00241 
00246 UMLClassifier * ClassifierCodeDocument::getParentClassifier ( ) {
00247     return m_parentclassifier;
00248 }
00249 
00253 QPtrList<CodeOperation> ClassifierCodeDocument::getCodeOperations ( ) {
00254 
00255     QPtrList<CodeOperation> list;
00256     list.setAutoDelete(false);
00257 
00258     TextBlockList * tlist = getTextBlockList();
00259     for (TextBlock *tb = tlist->first(); tb; tb=tlist->next())
00260     {
00261         CodeOperation * cop = dynamic_cast<CodeOperation*>(tb);
00262         if(cop)
00263             list.append(cop);
00264     }
00265     return list;
00266 }
00267 
00271 void ClassifierCodeDocument::addOperation (UMLClassifierListItem * o) {
00272     UMLOperation *op = dynamic_cast<UMLOperation*>(o);
00273     if (op == NULL) {
00274         kError() << "ClassifierCodeDocument::addOperation: arg is not a UMLOperation"
00275             << endl;
00276     }
00277     QString tag = CodeOperation::findTag(op);
00278     CodeOperation * codeOp = dynamic_cast<CodeOperation*>(findTextBlockByTag(tag, true));
00279     bool createdNew = false;
00280 
00281     // create the block, if it doesn't already exist
00282     if(!codeOp)
00283     {
00284         codeOp = CodeGenFactory::newCodeOperation(this, op);
00285         createdNew = true;
00286     }
00287 
00288     // now try to add it. This may fail because it (or a block with
00289     // the same tag) is already in the document somewhere. IF we
00290     // created this new, then we need to delete our object.
00291     if(!addCodeOperation(codeOp)) // wont add if already present
00292         if(createdNew)
00293             delete codeOp;
00294 
00295 }
00296 
00300 void ClassifierCodeDocument::removeOperation (UMLClassifierListItem * op ) {
00301 
00302     QString tag = CodeOperation::findTag((UMLOperation*)op);
00303     TextBlock *tb = findTextBlockByTag(tag, true);
00304     if(tb)
00305     {
00306         if(removeTextBlock(tb)) // wont add if already present
00307             delete tb; // delete unused operations
00308         else
00309             kError()<<"Cant remove CodeOperation from ClassCodeDocument!"<<endl;
00310 
00311     }
00312     else
00313         kError()<<"Cant Find codeOperation for deleted operation!"<<endl;
00314 }
00315 
00316 // Other methods
00317 //
00318 
00319 void ClassifierCodeDocument::addCodeClassFieldMethods(CodeClassFieldList &list )
00320 {
00321 
00322     for (CodeClassFieldListIt ccflit(list); ccflit.current(); ++ccflit)
00323     {
00324         CodeClassField * field = ccflit.current();
00325         CodeAccessorMethodList list = field->getMethodList();
00326         CodeAccessorMethod * method;
00327         for (CodeAccessorMethodListIt it(list); (method = it.current()) != NULL; ++it)
00328         {
00329             /*
00330                                 QString tag = method->getTag();
00331                                 if(tag.isEmpty())
00332                                 {
00333                                         tag = getUniqueTag();
00334                                         method->setTag(tag);
00335                                 }
00336             */
00337             addTextBlock(method); // wont add if already exists in document, will add a tag if missing;
00338 
00339         }
00340 
00341     }
00342 
00343 }
00344 
00345 // add declaration blocks for the passed classfields
00346 void ClassifierCodeDocument::declareClassFields (CodeClassFieldList & list ,
00347         CodeGenObjectWithTextBlocks * parent )
00348 {
00349 
00350     for (CodeClassFieldListIt ccflit(list); ccflit.current(); ++ccflit)
00351     {
00352         CodeClassField * field = ccflit.current();
00353         CodeClassFieldDeclarationBlock * declBlock = field->getDeclarationCodeBlock();
00354 
00355         /*
00356                         // if it has a tag, check
00357                         if(!declBlock->getTag().isEmpty())
00358                         {
00359                                 // In C++, because we may shift the declaration to a different parent
00360                                 // block for a change in scope, we need to track down any pre-existing
00361                                 // location, and remove FIRST before adding to new parent
00362                                 CodeGenObjectWithTextBlocks * oldParent = findParentObjectForTaggedTextBlock (declBlock->getTag());
00363                                 if(oldParent) {
00364                                         if(oldParent != parent)
00365                                                 oldParent->removeTextBlock(declBlock);
00366                                 }
00367                         }
00368         */
00369 
00370         parent->addTextBlock(declBlock); // wont add it IF its already present. Will give it a tag if missing
00371 
00372     }
00373 }
00374 
00375 bool ClassifierCodeDocument::parentIsClass() {
00376     return (m_parentclassifier->getBaseType() == Uml::ot_Class);
00377 }
00378 
00379 bool ClassifierCodeDocument::parentIsInterface() {
00380     return (m_parentclassifier->getBaseType() == Uml::ot_Interface);
00381 }
00382 
00388 void ClassifierCodeDocument::init (UMLClassifier * c )
00389 {
00390 
00391     m_parentclassifier = c;
00392     m_classfieldVector.setAutoDelete(false);
00393 
00394     updateHeader();
00395     syncNamesToParent();
00396     // initCodeClassFields(); // cant call here?..newCodeClassField is pure virtual
00397 
00398     // slots
00399     if (parentIsClass())  {
00400         connect(c,SIGNAL(attributeAdded(UMLClassifierListItem*)),this,SLOT(addAttributeClassField(UMLClassifierListItem*)));
00401         connect(c,SIGNAL(attributeRemoved(UMLClassifierListItem*)),this,SLOT(removeAttributeClassField(UMLClassifierListItem*)));
00402     }
00403 
00404     connect(c,SIGNAL(sigAssociationEndAdded(UMLAssociation*)),this,SLOT(addAssociationClassField(UMLAssociation*)));
00405     connect(c,SIGNAL(sigAssociationEndRemoved(UMLAssociation*)),this,SLOT(removeAssociationClassField(UMLAssociation*)));
00406     connect(c,SIGNAL(operationAdded(UMLClassifierListItem*)),this,SLOT(addOperation(UMLClassifierListItem*)));
00407     connect(c,SIGNAL(operationRemoved(UMLClassifierListItem*)),this,SLOT(removeOperation(UMLClassifierListItem*)));
00408     connect(c,SIGNAL(modified()),this,SLOT(syncToParent()));
00409 
00410 }
00411 
00412 // IF the classifier object is modified, this will get called.
00413 // @todo we cannot make this virtual as long as the
00414 //       ClassifierCodeDocument constructor calls it because that gives
00415 //       a call-before-construction error.
00416 // Example of the problem: CPPSourceCodeDocument reimplementing syncNamesToParent()
00417 //  CPPCodeGenerator::initFromParentDocument()
00418 //    CodeDocument * codeDoc = new CPPSourceCodeDocument(c);
00419 //      CPPSourceCodeDocument::CPPSourceCodeDocument(UMLClassifier * concept)
00420 //       : ClassifierCodeDocument(concept)
00421 //        ClassifierCodeDocument::ClassifierCodeDocument(concept)
00422 //         init(concept);
00423 //          syncNamesToParent();
00424 //            dispatches to CPPSourceCodeDocument::syncNamesToParent()
00425 //            but that object is not yet constructed.
00426 //
00427 void ClassifierCodeDocument::syncNamesToParent( ) {
00428     QString fileName = CodeGenerator::cleanName(getParentClassifier()->getName());
00429     if (!UMLApp::app()->activeLanguageIsCaseSensitive()) {
00430         // @todo let the user decide about mixed case file names (codegen setup menu)
00431         fileName = fileName.lower();
00432     }
00433     setFileName(fileName);
00434     setPackage(m_parentclassifier->getUMLPackage());
00435 }
00436 
00437 void ClassifierCodeDocument::synchronize( ) {
00438 
00439     updateHeader(); // doing this insures time/date stamp is at the time of this call
00440     syncNamesToParent();
00441     updateContent();
00442     syncClassFields();
00443     updateOperations();
00444 
00445 }
00446 
00447 void ClassifierCodeDocument::syncClassFields( )
00448 {
00449     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00450     {
00451         CodeClassField * cf = ccflit.current();
00452         cf->synchronize();
00453     }
00454 }
00455 
00456 void ClassifierCodeDocument::updateOperations( ) {
00457 
00458     UMLOperationList opList(getParentClassifier()->getOpList());
00459     for (UMLOperation *op = opList.first(); op; op = opList.next())
00460     {
00461         QString tag = CodeOperation::findTag(op);
00462         CodeOperation * codeOp = dynamic_cast<CodeOperation*>(findTextBlockByTag(tag, true));
00463         bool createdNew = false;
00464 
00465         if(!codeOp)
00466         {
00467             codeOp = CodeGenFactory::newCodeOperation(this, op);
00468             createdNew = true;
00469         }
00470 
00471         // now try to add it. This may fail because it (or a block with
00472         // the same tag) is already in the document somewhere. IF we
00473         // created this new, then we need to delete our object.
00474         if(!addCodeOperation(codeOp)) // wont add if already present
00475             if(createdNew)
00476                 delete codeOp;
00477 
00478         // synchronize all non-new operations
00479         if(!createdNew)
00480             codeOp->syncToParent();
00481     }
00482 
00483 }
00484 
00485 void ClassifierCodeDocument::syncToParent( ) {
00486     synchronize();
00487 }
00488 
00493 void ClassifierCodeDocument::initCodeClassFields ( ) {
00494 
00495     UMLClassifier * c = getParentClassifier();
00496     // first, do the code classifields that arise from attributes
00497     if (parentIsClass()) {
00498         UMLAttributeList alist = c->getAttributeList();
00499         for(UMLAttribute * at = alist.first(); at; at = alist.next())
00500         {
00501             CodeClassField * field = CodeGenFactory::newCodeClassField(this, at);
00502             addCodeClassField(field);
00503         }
00504 
00505     }
00506 
00507     // now, do the code classifields that arise from associations
00508     UMLAssociationList ap = c->getSpecificAssocs(Uml::at_Association);
00509     UMLAssociationList ag = c->getAggregations();
00510     UMLAssociationList ac = c->getCompositions();
00511     UMLAssociationList selfAssoc = c->getSpecificAssocs(Uml::at_Association_Self);
00512 
00513     updateAssociationClassFields(ap);
00514     updateAssociationClassFields(ag);
00515     updateAssociationClassFields(ac);
00516     updateAssociationClassFields(selfAssoc);
00517 
00518 }
00519 
00520 void ClassifierCodeDocument::updateAssociationClassFields ( UMLAssociationList &assocList )
00521 {
00522     CodeClassFieldList list;
00523     for(UMLAssociation * a=assocList.first(); a; a=assocList.next())
00524         addAssociationClassField(a, false); // syncToParent later
00525 }
00526 
00527 void ClassifierCodeDocument::addAssociationClassField (UMLAssociation * a, bool syncToParentIfAdded)
00528 {
00529 
00530     Uml::IDType cid = getParentClassifier()->getID(); // so we know who 'we' are
00531     bool printRoleA = false, printRoleB = false, shouldSync = false;
00532     // it may seem counter intuitive, but you want to insert the role of the
00533     // *other* class into *this* class.
00534     if (a->getObjectId(Uml::A) == cid)
00535         printRoleB = true;
00536 
00537     if (a->getObjectId(Uml::B) == cid)
00538         printRoleA = true;
00539 
00540     // grab RoleB decl
00541     if (printRoleB)
00542     {
00543 
00544         UMLRole * role = a->getUMLRole(Uml::B);
00545         if(!m_classFieldMap.contains((UMLObject*)role))
00546         {
00547             CodeClassField * classfield = CodeGenFactory::newCodeClassField(this, role);
00548             if( addCodeClassField(classfield))
00549                 shouldSync = true;
00550         }
00551     }
00552 
00553     // print RoleA decl
00554     if (printRoleA)
00555     {
00556         UMLRole * role = a->getUMLRole(Uml::A);
00557         if(!m_classFieldMap.contains((UMLObject*)role))
00558         {
00559             CodeClassField * classfield = CodeGenFactory::newCodeClassField(this, role);
00560             if( addCodeClassField(classfield))
00561                 shouldSync = true;
00562         }
00563     }
00564 
00565     if (shouldSync && syncToParentIfAdded)
00566         syncToParent(); // needed for a slot add
00567 
00568 }
00569 
00573 void ClassifierCodeDocument::setAttributesFromNode ( QDomElement & elem )
00574 {
00575 
00576     // NOTE: we DON'T set the parent here as we ONLY get to this point
00577     // IF the parent codegenerator could find a matching parent classifier
00578     // that already has a code document.
00579 
00580     // We FIRST set code class field stuff..check re-linnking with
00581     // accessor methods by looking for our particular child element
00582     QDomNode node = elem.firstChild();
00583     QDomElement childElem = node.toElement();
00584     while( !childElem.isNull() ) {
00585         QString tag = childElem.tagName();
00586         if( tag == "classfields" ) {
00587             // load classfields
00588             loadClassFieldsFromXMI(childElem);
00589             break;
00590         }
00591         node = childElem.nextSibling();
00592         childElem= node.toElement();
00593     }
00594 
00595     // call super-class after. THis will populate the text blocks (incl
00596     // the code accessor methods above) as is appropriate
00597     CodeDocument::setAttributesFromNode(elem);
00598 
00599 }
00600 
00601 // look at all classfields currently in document.. match up
00602 // by parent object ID and Role ID (needed for self-association CF's)
00603 CodeClassField *
00604 ClassifierCodeDocument::findCodeClassFieldFromParentID (Uml::IDType id,
00605         int role_id)
00606 {
00607     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00608     {
00609         CodeClassField * cf = ccflit.current();
00610         if(role_id == -1) { // attribute-based
00611             if (STR2ID(cf->getID()) == id)
00612                 return cf;
00613         } else { // association(role)-based
00614             const Uml::Role_Type r = (Uml::Role_Type)role_id;
00615             UMLRole * role = dynamic_cast<UMLRole *>(cf->getParentObject());
00616             if(role && STR2ID(cf->getID()) == id && role->getRole() == r)
00617                 return cf;
00618         }
00619     }
00620 
00621     // shouldn't happen..
00622     kError() << "Failed to find codeclassfield for parent uml id:"
00623     << ID2STR(id) << " (role id:" << role_id
00624     << ") Do you have a corrupt classifier code document?"
00625     << endl;
00626 
00627     return (CodeClassField*) NULL; // not found
00628 }
00629 
00630 void ClassifierCodeDocument::loadClassFieldsFromXMI( QDomElement & elem) {
00631 
00632     QDomNode node = elem.firstChild();
00633     QDomElement childElem = node.toElement();
00634     while( !childElem.isNull() ) {
00635         QString nodeName = childElem.tagName();
00636         if( nodeName == "codeclassfield")
00637         {
00638             QString id = childElem.attribute("parent_id","-1");
00639             int role_id = childElem.attribute("role_id","-1").toInt();
00640             CodeClassField * cf = findCodeClassFieldFromParentID(STR2ID(id), role_id);
00641             if(cf)
00642             {
00643                 // Because we just may change the parent object here,
00644                 // we need to yank it from the map of umlobjects
00645                 m_classFieldMap.remove(cf->getParentObject());
00646 
00647                 // configure from XMI
00648                 cf->loadFromXMI(childElem);
00649 
00650                 // now add back in
00651                 m_classFieldMap.insert(cf->getParentObject(),cf);
00652 
00653             } else
00654                 kError()<<" LoadFromXMI: can't load classfield parent_id:"<<id<<" do you have a corrupt savefile?"<<endl;
00655         }
00656         node = childElem.nextSibling();
00657         childElem= node.toElement();
00658     }
00659 }
00660 
00664 void ClassifierCodeDocument::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
00665 #if 0
00666     // avoid the creation of primitive data type
00667     QString strType;
00668     if (getParentClassifier()->getBaseType() == Uml::ot_Datatype) {
00669         strType = getParentClassifier()->getName();
00670         // lets get the default code generator to check if it is a primitive data type
00671         // there's a reason to create files for int/boolean and so ?
00672         if (getParentGenerator()->isReservedKeyword(strType))
00673            return;
00674     }
00675 #endif
00676     QDomElement docElement = doc.createElement( "classifiercodedocument" );
00677 
00678     setAttributesOnNode(doc, docElement);
00679 
00680     root.appendChild( docElement );
00681 }
00682 
00686 void ClassifierCodeDocument::loadFromXMI ( QDomElement & root ) {
00687 
00688     // set attributes/fields
00689     setAttributesFromNode(root);
00690 
00691     // now sync our doc, needed?
00692     // synchronize();
00693 }
00694 
00698 void ClassifierCodeDocument::setAttributesOnNode ( QDomDocument & doc, QDomElement & docElement)
00699 {
00700 
00701     // do super-class first
00702     CodeDocument::setAttributesOnNode(doc, docElement);
00703 
00704     // cache local attributes/fields
00705     docElement.setAttribute("parent_class", ID2STR(getParentClassifier()->getID()));
00706 
00707     // (code) class fields
00708     // which we will store in its own separate child node block
00709     QDomElement fieldsElement = doc.createElement( "classfields" );
00710     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00711     {
00712         CodeClassField * field = ccflit.current();
00713         field->saveToXMI(doc, fieldsElement);
00714     }
00715     docElement.appendChild( fieldsElement);
00716 
00717 }
00718 
00719 TextBlock * ClassifierCodeDocument::findCodeClassFieldTextBlockByTag (const QString &tag)
00720 {
00721 
00722     for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
00723     {
00724         CodeClassField * cf = ccflit.current();
00725         CodeClassFieldDeclarationBlock * decl = cf->getDeclarationCodeBlock();
00726         if(decl && decl->getTag() == tag)
00727             return decl;
00728         // well, if not in the decl block, then in the methods perhaps?
00729         CodeAccessorMethodList mlist = cf->getMethodList();
00730         CodeAccessorMethod *m;
00731         for (CodeAccessorMethodListIt it(mlist); (m = it.current()) != NULL; ++it)
00732             if(m->getTag() == tag)
00733                 return m;
00734     }
00735 
00736     // if we get here, we failed.
00737     return (TextBlock*) NULL;
00738 
00739 }
00740 
00741 
00742 #include "classifiercodedocument.moc"
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:54 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003