summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/classifiercodedocument.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitbd9e6617827818fd043452c08c606f07b78014a0 (patch)
tree425bb4c3168f9c02f10150f235d2cb998dcc6108 /umbrello/umbrello/classifiercodedocument.cpp
downloadtdesdk-bd9e6617827818fd043452c08c606f07b78014a0.tar.gz
tdesdk-bd9e6617827818fd043452c08c606f07b78014a0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdesdk@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'umbrello/umbrello/classifiercodedocument.cpp')
-rw-r--r--umbrello/umbrello/classifiercodedocument.cpp742
1 files changed, 742 insertions, 0 deletions
diff --git a/umbrello/umbrello/classifiercodedocument.cpp b/umbrello/umbrello/classifiercodedocument.cpp
new file mode 100644
index 00000000..a2d2f9fc
--- /dev/null
+++ b/umbrello/umbrello/classifiercodedocument.cpp
@@ -0,0 +1,742 @@
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * copyright (C) 2004-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Jun 19 2003
+ */
+
+// own header
+#include "classifiercodedocument.h"
+
+// qt/kde includes
+#include <kdebug.h>
+#include <qregexp.h>
+
+// local includes
+#include "association.h"
+#include "attribute.h"
+#include "operation.h"
+#include "classifierlistitem.h"
+#include "classifier.h"
+#include "codegenerator.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlrole.h"
+#include "umlattributelist.h"
+#include "umloperationlist.h"
+#include "codegenerators/codegenfactory.h"
+
+// Constructors/Destructors
+//
+
+ClassifierCodeDocument::ClassifierCodeDocument ( UMLClassifier * parent )
+{
+ init (parent);
+}
+
+ClassifierCodeDocument::~ClassifierCodeDocument ( )
+{
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ delete cf;
+ }
+ m_classfieldVector.clear();
+}
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+/** get a list of codeclassifier objects held by this classifiercodedocument that meet the passed criteria.
+ */
+CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType)
+{
+ CodeClassFieldList list;
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ if (cf->getClassFieldType() == cfType)
+ list.append(cf);
+ }
+ return list;
+}
+
+/** get a list of codeclassifier objects held by this classifiercodedocument that meet the passed criteria.
+ */
+CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType, bool isStatic)
+{
+ CodeClassFieldList list;
+ list.setAutoDelete(false);
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ if (cf->getClassFieldType() == cfType && cf->getStatic() == isStatic)
+ list.append(cf);
+ }
+ return list;
+}
+
+/** get a list of codeclassifier objects held by this classifiercodedocument that meet the passed criteria.
+ */
+CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType, Uml::Visibility visibility)
+{
+ CodeClassFieldList list;
+ list.setAutoDelete(false);
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ if (cf->getClassFieldType() == cfType && cf->getVisibility() == visibility)
+ list.append(cf);
+ }
+ return list;
+}
+
+/** get a list of codeclassifier objects held by this classifiercodedocument that meet the passed criteria.
+ */
+CodeClassFieldList ClassifierCodeDocument::getSpecificClassFields (CodeClassField::ClassFieldType cfType, bool isStatic, Uml::Visibility visibility)
+{
+ CodeClassFieldList list;
+ list.setAutoDelete(false);
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ if (cf->getClassFieldType() == cfType && cf->getVisibility() == visibility && cf->getStatic() == isStatic )
+ list.append(cf);
+ }
+ return list;
+}
+
+// do we have accessor methods for lists of objects?
+// (as opposed to lists of primitive types like 'int' or 'float', etc)
+bool ClassifierCodeDocument::hasObjectVectorClassFields() {
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ if(cf->getClassFieldType() != CodeClassField::Attribute)
+ {
+ UMLRole * role = dynamic_cast<UMLRole*>(cf->getParentObject());
+ QString multi = role->getMultiplicity();
+ if (
+ multi.contains(QRegExp("[23456789\\*]")) ||
+ multi.contains(QRegExp("1\\d"))
+ )
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ClassifierCodeDocument::hasClassFields() {
+ if(m_classfieldVector.count() > 0 )
+ return true;
+ return false;
+}
+
+/**
+ * Tell if one or more codeclassfields are derived from associations.
+ */
+bool ClassifierCodeDocument::hasAssociationClassFields() {
+ CodeClassFieldList list = getSpecificClassFields(CodeClassField::Attribute);
+ return (m_classfieldVector.count() - list.count()) > 0 ? true : false;
+}
+
+/**
+ * Tell if one or more codeclassfields are derived from attributes.
+ */
+bool ClassifierCodeDocument::hasAttributeClassFields() {
+ CodeClassFieldList list = getSpecificClassFields(CodeClassField::Attribute);
+ return list.count() > 0 ? true : false;
+}
+
+/**
+ * Add a CodeClassField object to the m_classfieldVector List
+ * @return boolean true if successful in adding
+ */
+// We DON'T add methods of the code classfield here because we need to allow
+// the codegenerator writer the liberty to organize their document as they desire.
+bool ClassifierCodeDocument::addCodeClassField ( CodeClassField * add_object ) {
+ UMLObject * umlobj = add_object->getParentObject();
+ if(!(m_classFieldMap.contains(umlobj)))
+ {
+ m_classfieldVector.append(add_object);
+ m_classFieldMap.insert(umlobj,add_object);
+
+ return true;
+ }
+ return false;
+}
+
+// this is a slot..should only be called from a signal
+void ClassifierCodeDocument::addAttributeClassField (UMLClassifierListItem *obj, bool syncToParentIfAdded) {
+ UMLAttribute *at = (UMLAttribute*)obj;
+ CodeClassField * cf = CodeGenFactory::newCodeClassField(this, at);
+ if(cf)
+ if (addCodeClassField(cf) && syncToParentIfAdded)
+ updateContent();
+}
+
+/**
+ * Remove a CodeClassField object from m_classfieldVector List
+ */
+bool ClassifierCodeDocument::removeCodeClassField ( CodeClassField * remove_object ) {
+ UMLObject * umlobj = remove_object->getParentObject();
+ if(m_classFieldMap.contains(umlobj))
+ {
+ if (m_classfieldVector.removeRef(remove_object))
+ {
+ // remove from our classfield map
+ m_classFieldMap.remove(umlobj);
+ delete remove_object;
+ return true;
+ }
+ }
+ return false;
+}
+
+void ClassifierCodeDocument::removeAttributeClassField(UMLClassifierListItem *obj)
+{
+ CodeClassField * remove_object = m_classFieldMap[obj];
+ if(remove_object)
+ removeCodeClassField(remove_object);
+}
+
+void ClassifierCodeDocument::removeAssociationClassField (UMLAssociation *assoc )
+{
+
+ // the object could be either (or both!) role a or b. We should check
+ // both parts of the association.
+ CodeClassField * remove_object = m_classFieldMap[assoc->getUMLRole(Uml::A)];
+ if(remove_object)
+ removeCodeClassField(remove_object);
+
+ // check role b
+ remove_object = m_classFieldMap[assoc->getUMLRole(Uml::B)];
+ if(remove_object)
+ removeCodeClassField(remove_object);
+
+}
+
+/**
+ * Get the list of CodeClassField objects held by m_classfieldVector
+ * @return CodeClassFieldList list of CodeClassField objects held by
+ * m_classfieldVector
+ */
+CodeClassFieldList * ClassifierCodeDocument::getCodeClassFieldList ( ) {
+ return &m_classfieldVector;
+}
+
+/**
+ * Get the value of m_parentclassifier
+ * @return the value of m_parentclassifier
+ */
+UMLClassifier * ClassifierCodeDocument::getParentClassifier ( ) {
+ return m_parentclassifier;
+}
+
+/**
+ * @return QPtrList<CodeOperation>
+ */
+QPtrList<CodeOperation> ClassifierCodeDocument::getCodeOperations ( ) {
+
+ QPtrList<CodeOperation> list;
+ list.setAutoDelete(false);
+
+ TextBlockList * tlist = getTextBlockList();
+ for (TextBlock *tb = tlist->first(); tb; tb=tlist->next())
+ {
+ CodeOperation * cop = dynamic_cast<CodeOperation*>(tb);
+ if(cop)
+ list.append(cop);
+ }
+ return list;
+}
+
+/**
+ * @param o The Operation to add
+ */
+void ClassifierCodeDocument::addOperation (UMLClassifierListItem * o) {
+ UMLOperation *op = dynamic_cast<UMLOperation*>(o);
+ if (op == NULL) {
+ kError() << "ClassifierCodeDocument::addOperation: arg is not a UMLOperation"
+ << endl;
+ }
+ QString tag = CodeOperation::findTag(op);
+ CodeOperation * codeOp = dynamic_cast<CodeOperation*>(findTextBlockByTag(tag, true));
+ bool createdNew = false;
+
+ // create the block, if it doesn't already exist
+ if(!codeOp)
+ {
+ codeOp = CodeGenFactory::newCodeOperation(this, op);
+ createdNew = true;
+ }
+
+ // now try to add it. This may fail because it (or a block with
+ // the same tag) is already in the document somewhere. IF we
+ // created this new, then we need to delete our object.
+ if(!addCodeOperation(codeOp)) // wont add if already present
+ if(createdNew)
+ delete codeOp;
+
+}
+
+/**
+ * @param op
+ */
+void ClassifierCodeDocument::removeOperation (UMLClassifierListItem * op ) {
+
+ QString tag = CodeOperation::findTag((UMLOperation*)op);
+ TextBlock *tb = findTextBlockByTag(tag, true);
+ if(tb)
+ {
+ if(removeTextBlock(tb)) // wont add if already present
+ delete tb; // delete unused operations
+ else
+ kError()<<"Cant remove CodeOperation from ClassCodeDocument!"<<endl;
+
+ }
+ else
+ kError()<<"Cant Find codeOperation for deleted operation!"<<endl;
+}
+
+// Other methods
+//
+
+void ClassifierCodeDocument::addCodeClassFieldMethods(CodeClassFieldList &list )
+{
+
+ for (CodeClassFieldListIt ccflit(list); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * field = ccflit.current();
+ CodeAccessorMethodList list = field->getMethodList();
+ CodeAccessorMethod * method;
+ for (CodeAccessorMethodListIt it(list); (method = it.current()) != NULL; ++it)
+ {
+ /*
+ QString tag = method->getTag();
+ if(tag.isEmpty())
+ {
+ tag = getUniqueTag();
+ method->setTag(tag);
+ }
+ */
+ addTextBlock(method); // wont add if already exists in document, will add a tag if missing;
+
+ }
+
+ }
+
+}
+
+// add declaration blocks for the passed classfields
+void ClassifierCodeDocument::declareClassFields (CodeClassFieldList & list ,
+ CodeGenObjectWithTextBlocks * parent )
+{
+
+ for (CodeClassFieldListIt ccflit(list); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * field = ccflit.current();
+ CodeClassFieldDeclarationBlock * declBlock = field->getDeclarationCodeBlock();
+
+ /*
+ // if it has a tag, check
+ if(!declBlock->getTag().isEmpty())
+ {
+ // In C++, because we may shift the declaration to a different parent
+ // block for a change in scope, we need to track down any pre-existing
+ // location, and remove FIRST before adding to new parent
+ CodeGenObjectWithTextBlocks * oldParent = findParentObjectForTaggedTextBlock (declBlock->getTag());
+ if(oldParent) {
+ if(oldParent != parent)
+ oldParent->removeTextBlock(declBlock);
+ }
+ }
+ */
+
+ parent->addTextBlock(declBlock); // wont add it IF its already present. Will give it a tag if missing
+
+ }
+}
+
+bool ClassifierCodeDocument::parentIsClass() {
+ return (m_parentclassifier->getBaseType() == Uml::ot_Class);
+}
+
+bool ClassifierCodeDocument::parentIsInterface() {
+ return (m_parentclassifier->getBaseType() == Uml::ot_Interface);
+}
+
+/**
+ * Init from a UMLClassifier object.
+ * @param classifier
+ * @param package
+ */
+void ClassifierCodeDocument::init (UMLClassifier * c )
+{
+
+ m_parentclassifier = c;
+ m_classfieldVector.setAutoDelete(false);
+
+ updateHeader();
+ syncNamesToParent();
+ // initCodeClassFields(); // cant call here?..newCodeClassField is pure virtual
+
+ // slots
+ if (parentIsClass()) {
+ connect(c,SIGNAL(attributeAdded(UMLClassifierListItem*)),this,SLOT(addAttributeClassField(UMLClassifierListItem*)));
+ connect(c,SIGNAL(attributeRemoved(UMLClassifierListItem*)),this,SLOT(removeAttributeClassField(UMLClassifierListItem*)));
+ }
+
+ connect(c,SIGNAL(sigAssociationEndAdded(UMLAssociation*)),this,SLOT(addAssociationClassField(UMLAssociation*)));
+ connect(c,SIGNAL(sigAssociationEndRemoved(UMLAssociation*)),this,SLOT(removeAssociationClassField(UMLAssociation*)));
+ connect(c,SIGNAL(operationAdded(UMLClassifierListItem*)),this,SLOT(addOperation(UMLClassifierListItem*)));
+ connect(c,SIGNAL(operationRemoved(UMLClassifierListItem*)),this,SLOT(removeOperation(UMLClassifierListItem*)));
+ connect(c,SIGNAL(modified()),this,SLOT(syncToParent()));
+
+}
+
+// IF the classifier object is modified, this will get called.
+// @todo we cannot make this virtual as long as the
+// ClassifierCodeDocument constructor calls it because that gives
+// a call-before-construction error.
+// Example of the problem: CPPSourceCodeDocument reimplementing syncNamesToParent()
+// CPPCodeGenerator::initFromParentDocument()
+// CodeDocument * codeDoc = new CPPSourceCodeDocument(c);
+// CPPSourceCodeDocument::CPPSourceCodeDocument(UMLClassifier * concept)
+// : ClassifierCodeDocument(concept)
+// ClassifierCodeDocument::ClassifierCodeDocument(concept)
+// init(concept);
+// syncNamesToParent();
+// dispatches to CPPSourceCodeDocument::syncNamesToParent()
+// but that object is not yet constructed.
+//
+void ClassifierCodeDocument::syncNamesToParent( ) {
+ QString fileName = CodeGenerator::cleanName(getParentClassifier()->getName());
+ if (!UMLApp::app()->activeLanguageIsCaseSensitive()) {
+ // @todo let the user decide about mixed case file names (codegen setup menu)
+ fileName = fileName.lower();
+ }
+ setFileName(fileName);
+ setPackage(m_parentclassifier->getUMLPackage());
+}
+
+void ClassifierCodeDocument::synchronize( ) {
+
+ updateHeader(); // doing this insures time/date stamp is at the time of this call
+ syncNamesToParent();
+ updateContent();
+ syncClassFields();
+ updateOperations();
+
+}
+
+void ClassifierCodeDocument::syncClassFields( )
+{
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ cf->synchronize();
+ }
+}
+
+void ClassifierCodeDocument::updateOperations( ) {
+
+ UMLOperationList opList(getParentClassifier()->getOpList());
+ for (UMLOperation *op = opList.first(); op; op = opList.next())
+ {
+ QString tag = CodeOperation::findTag(op);
+ CodeOperation * codeOp = dynamic_cast<CodeOperation*>(findTextBlockByTag(tag, true));
+ bool createdNew = false;
+
+ if(!codeOp)
+ {
+ codeOp = CodeGenFactory::newCodeOperation(this, op);
+ createdNew = true;
+ }
+
+ // now try to add it. This may fail because it (or a block with
+ // the same tag) is already in the document somewhere. IF we
+ // created this new, then we need to delete our object.
+ if(!addCodeOperation(codeOp)) // wont add if already present
+ if(createdNew)
+ delete codeOp;
+
+ // synchronize all non-new operations
+ if(!createdNew)
+ codeOp->syncToParent();
+ }
+
+}
+
+void ClassifierCodeDocument::syncToParent( ) {
+ synchronize();
+}
+
+/**
+ * add codeclassfields to this classifiercodedocument. IF a codeclassfield
+ * already exists, it is not added.
+ */
+void ClassifierCodeDocument::initCodeClassFields ( ) {
+
+ UMLClassifier * c = getParentClassifier();
+ // first, do the code classifields that arise from attributes
+ if (parentIsClass()) {
+ UMLAttributeList alist = c->getAttributeList();
+ for(UMLAttribute * at = alist.first(); at; at = alist.next())
+ {
+ CodeClassField * field = CodeGenFactory::newCodeClassField(this, at);
+ addCodeClassField(field);
+ }
+
+ }
+
+ // now, do the code classifields that arise from associations
+ UMLAssociationList ap = c->getSpecificAssocs(Uml::at_Association);
+ UMLAssociationList ag = c->getAggregations();
+ UMLAssociationList ac = c->getCompositions();
+ UMLAssociationList selfAssoc = c->getSpecificAssocs(Uml::at_Association_Self);
+
+ updateAssociationClassFields(ap);
+ updateAssociationClassFields(ag);
+ updateAssociationClassFields(ac);
+ updateAssociationClassFields(selfAssoc);
+
+}
+
+void ClassifierCodeDocument::updateAssociationClassFields ( UMLAssociationList &assocList )
+{
+ CodeClassFieldList list;
+ for(UMLAssociation * a=assocList.first(); a; a=assocList.next())
+ addAssociationClassField(a, false); // syncToParent later
+}
+
+void ClassifierCodeDocument::addAssociationClassField (UMLAssociation * a, bool syncToParentIfAdded)
+{
+
+ Uml::IDType cid = getParentClassifier()->getID(); // so we know who 'we' are
+ bool printRoleA = false, printRoleB = false, shouldSync = false;
+ // it may seem counter intuitive, but you want to insert the role of the
+ // *other* class into *this* class.
+ if (a->getObjectId(Uml::A) == cid)
+ printRoleB = true;
+
+ if (a->getObjectId(Uml::B) == cid)
+ printRoleA = true;
+
+ // grab RoleB decl
+ if (printRoleB)
+ {
+
+ UMLRole * role = a->getUMLRole(Uml::B);
+ if(!m_classFieldMap.contains((UMLObject*)role))
+ {
+ CodeClassField * classfield = CodeGenFactory::newCodeClassField(this, role);
+ if( addCodeClassField(classfield))
+ shouldSync = true;
+ }
+ }
+
+ // print RoleA decl
+ if (printRoleA)
+ {
+ UMLRole * role = a->getUMLRole(Uml::A);
+ if(!m_classFieldMap.contains((UMLObject*)role))
+ {
+ CodeClassField * classfield = CodeGenFactory::newCodeClassField(this, role);
+ if( addCodeClassField(classfield))
+ shouldSync = true;
+ }
+ }
+
+ if (shouldSync && syncToParentIfAdded)
+ syncToParent(); // needed for a slot add
+
+}
+
+/** set the class attributes of this object from
+ * the passed element node.
+ */
+void ClassifierCodeDocument::setAttributesFromNode ( QDomElement & elem )
+{
+
+ // NOTE: we DON'T set the parent here as we ONLY get to this point
+ // IF the parent codegenerator could find a matching parent classifier
+ // that already has a code document.
+
+ // We FIRST set code class field stuff..check re-linnking with
+ // accessor methods by looking for our particular child element
+ QDomNode node = elem.firstChild();
+ QDomElement childElem = node.toElement();
+ while( !childElem.isNull() ) {
+ QString tag = childElem.tagName();
+ if( tag == "classfields" ) {
+ // load classfields
+ loadClassFieldsFromXMI(childElem);
+ break;
+ }
+ node = childElem.nextSibling();
+ childElem= node.toElement();
+ }
+
+ // call super-class after. THis will populate the text blocks (incl
+ // the code accessor methods above) as is appropriate
+ CodeDocument::setAttributesFromNode(elem);
+
+}
+
+// look at all classfields currently in document.. match up
+// by parent object ID and Role ID (needed for self-association CF's)
+CodeClassField *
+ClassifierCodeDocument::findCodeClassFieldFromParentID (Uml::IDType id,
+ int role_id)
+{
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ if(role_id == -1) { // attribute-based
+ if (STR2ID(cf->getID()) == id)
+ return cf;
+ } else { // association(role)-based
+ const Uml::Role_Type r = (Uml::Role_Type)role_id;
+ UMLRole * role = dynamic_cast<UMLRole *>(cf->getParentObject());
+ if(role && STR2ID(cf->getID()) == id && role->getRole() == r)
+ return cf;
+ }
+ }
+
+ // shouldn't happen..
+ kError() << "Failed to find codeclassfield for parent uml id:"
+ << ID2STR(id) << " (role id:" << role_id
+ << ") Do you have a corrupt classifier code document?"
+ << endl;
+
+ return (CodeClassField*) NULL; // not found
+}
+
+void ClassifierCodeDocument::loadClassFieldsFromXMI( QDomElement & elem) {
+
+ QDomNode node = elem.firstChild();
+ QDomElement childElem = node.toElement();
+ while( !childElem.isNull() ) {
+ QString nodeName = childElem.tagName();
+ if( nodeName == "codeclassfield")
+ {
+ QString id = childElem.attribute("parent_id","-1");
+ int role_id = childElem.attribute("role_id","-1").toInt();
+ CodeClassField * cf = findCodeClassFieldFromParentID(STR2ID(id), role_id);
+ if(cf)
+ {
+ // Because we just may change the parent object here,
+ // we need to yank it from the map of umlobjects
+ m_classFieldMap.remove(cf->getParentObject());
+
+ // configure from XMI
+ cf->loadFromXMI(childElem);
+
+ // now add back in
+ m_classFieldMap.insert(cf->getParentObject(),cf);
+
+ } else
+ kError()<<" LoadFromXMI: can't load classfield parent_id:"<<id<<" do you have a corrupt savefile?"<<endl;
+ }
+ node = childElem.nextSibling();
+ childElem= node.toElement();
+ }
+}
+
+/**
+ * Save the XMI representation of this object
+ */
+void ClassifierCodeDocument::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+#if 0
+ // avoid the creation of primitive data type
+ QString strType;
+ if (getParentClassifier()->getBaseType() == Uml::ot_Datatype) {
+ strType = getParentClassifier()->getName();
+ // lets get the default code generator to check if it is a primitive data type
+ // there's a reason to create files for int/boolean and so ?
+ if (getParentGenerator()->isReservedKeyword(strType))
+ return;
+ }
+#endif
+ QDomElement docElement = doc.createElement( "classifiercodedocument" );
+
+ setAttributesOnNode(doc, docElement);
+
+ root.appendChild( docElement );
+}
+
+/**
+ * load params from the appropriate XMI element node.
+ */
+void ClassifierCodeDocument::loadFromXMI ( QDomElement & root ) {
+
+ // set attributes/fields
+ setAttributesFromNode(root);
+
+ // now sync our doc, needed?
+ // synchronize();
+}
+
+/** set attributes of the node that represents this class
+ * in the XMI document.
+ */
+void ClassifierCodeDocument::setAttributesOnNode ( QDomDocument & doc, QDomElement & docElement)
+{
+
+ // do super-class first
+ CodeDocument::setAttributesOnNode(doc, docElement);
+
+ // cache local attributes/fields
+ docElement.setAttribute("parent_class", ID2STR(getParentClassifier()->getID()));
+
+ // (code) class fields
+ // which we will store in its own separate child node block
+ QDomElement fieldsElement = doc.createElement( "classfields" );
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * field = ccflit.current();
+ field->saveToXMI(doc, fieldsElement);
+ }
+ docElement.appendChild( fieldsElement);
+
+}
+
+TextBlock * ClassifierCodeDocument::findCodeClassFieldTextBlockByTag (const QString &tag)
+{
+
+ for (CodeClassFieldListIt ccflit(m_classfieldVector); ccflit.current(); ++ccflit)
+ {
+ CodeClassField * cf = ccflit.current();
+ CodeClassFieldDeclarationBlock * decl = cf->getDeclarationCodeBlock();
+ if(decl && decl->getTag() == tag)
+ return decl;
+ // well, if not in the decl block, then in the methods perhaps?
+ CodeAccessorMethodList mlist = cf->getMethodList();
+ CodeAccessorMethod *m;
+ for (CodeAccessorMethodListIt it(mlist); (m = it.current()) != NULL; ++it)
+ if(m->getTag() == tag)
+ return m;
+ }
+
+ // if we get here, we failed.
+ return (TextBlock*) NULL;
+
+}
+
+
+#include "classifiercodedocument.moc"