umbrello API Documentation

cppcodegenerator.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-2006                                               *
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 "cppcodegenerator.h"
00019 
00020 // qt/kde includes
00021 #include <qregexp.h>
00022 #include <kdebug.h>
00023 #include <kconfig.h>
00024 
00025 // app includes
00026 #include "cppcodedocumentation.h"
00027 #include "cppcodegenerationpolicy.h"
00028 #include "cppsourcecodedocument.h"
00029 #include "cppheadercodedocument.h"
00030 #include "codegen_utils.h"
00031 #include "codeviewerdialog.h"
00032 #include "../codedocumentlist.h"
00033 #include "../uml.h"
00034 
00035 const bool CPPCodeGenerator::DEFAULT_BUILD_MAKEFILE = false;
00036 
00037 // Constructors/Destructors
00038 //
00039 
00040 CPPCodeGenerator::CPPCodeGenerator () {
00041     initAttributes();
00042 }
00043 
00044 CPPCodeGenerator::~CPPCodeGenerator ( ) {
00045     // destroy all separately owned codedocuments (e.g. header docs)
00046     CodeDocument *doc;
00047     for (CodeDocumentListIt it(m_headercodedocumentVector);
00048                      (doc = it.current()) != NULL; ++it)
00049         delete doc;
00050     m_headercodedocumentVector.clear();
00051 }
00052 
00053 //
00054 // Methods
00055 //
00056 
00057 // Accessor methods
00058 //
00059 
00063 Uml::Programming_Language CPPCodeGenerator::getLanguage() {
00064     return Uml::pl_Cpp;
00065 }
00066 
00071 void CPPCodeGenerator::setCreateProjectMakefile ( bool buildIt) {
00072     m_createMakefile = buildIt;
00073     CodeDocument * antDoc = findCodeDocumentByID(CPPMakefileCodeDocument::DOCUMENT_ID_VALUE);
00074     if (antDoc)
00075         antDoc->setWriteOutCode(buildIt);
00076 }
00077 
00082 bool CPPCodeGenerator::getCreateProjectMakefile ( ) {
00083     return m_createMakefile;
00084 }
00085 
00086 bool CPPCodeGenerator::addHeaderCodeDocument ( CPPHeaderCodeDocument * doc )
00087 {
00088 
00089     QString tag = doc->getID();
00090 
00091     // assign a tag if one doesn't already exist
00092     if(tag.isEmpty())
00093     {
00094         tag = "cppheader"+ID2STR(doc->getParentClassifier()->getID());
00095         doc->setID(tag);
00096     }
00097 
00098     if(m_codeDocumentDictionary.find(tag))
00099         return false; // return false, we already have some object with this tag in the list
00100     else
00101         m_codeDocumentDictionary.insert(tag, doc);
00102 
00103     m_headercodedocumentVector.append(doc);
00104     return true;
00105 }
00106 
00110 bool CPPCodeGenerator::removeHeaderCodeDocument ( CPPHeaderCodeDocument * remove_object ) {
00111     QString tag = remove_object->getID();
00112     if(!(tag.isEmpty()))
00113         m_codeDocumentDictionary.remove(tag);
00114     else
00115         return false;
00116 
00117     m_headercodedocumentVector.remove(remove_object);
00118     return true;
00119 }
00120 
00121 // In the C++ version, we need to make both source and header files as well
00122 // as the makefile available.
00123 CodeViewerDialog * CPPCodeGenerator::getCodeViewerDialog ( QWidget* parent, CodeDocument *doc,
00124         Settings::CodeViewerState state)
00125 {
00126 
00127     ClassifierCodeDocument * cdoc = dynamic_cast<ClassifierCodeDocument*>(doc);
00128     if(!cdoc)
00129         // bah..not a classcode document?? then just use vanilla version
00130         return CodeGenerator::getCodeViewerDialog(parent,doc,state);
00131     else {
00132         // build with passed (source) code document
00133         CodeViewerDialog *dialog;
00134 
00135         // use classifier to find appropriate header document
00136         UMLClassifier * c = cdoc->getParentClassifier();
00137         CPPHeaderCodeDocument * hdoc = findHeaderCodeDocumentByClassifier(c);
00138         if(hdoc)
00139         {
00140             // if we have a header document..build with that
00141             dialog = new CodeViewerDialog(parent, hdoc, state);
00142             dialog->addCodeDocument(doc);
00143         } else
00144             // shouldn't happen, but lets try to gracefully deliver something.
00145             dialog = new CodeViewerDialog(parent, doc, state);
00146 
00147         // add in makefile if available and desired
00148         if(getCreateProjectMakefile())
00149             dialog->addCodeDocument(findCodeDocumentByID(CPPMakefileCodeDocument::DOCUMENT_ID_VALUE));
00150 
00151         return dialog;
00152     }
00153 }
00154 
00155 // Other methods
00156 //
00157 
00158 // Change the following dataTypes to the ones the user really
00159 // wants in their code. Not yet complete.
00160 QString CPPCodeGenerator::fixTypeName(const QString &string)
00161 {
00162     return cleanName(string);
00163 }
00164 
00165 // special method needed so that we write out the header code documents
00166 void CPPCodeGenerator::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
00167     QDomElement docElement = doc.createElement( "codegenerator" );
00168     docElement.setAttribute("language", "C++");
00169 
00170     CodeDocumentList * docList = getCodeDocumentList();
00171     for (CodeDocument * codeDoc = docList->first(); codeDoc; codeDoc= docList->next())
00172         codeDoc->saveToXMI(doc, docElement);
00173 
00174     for (CodeDocument * hcodeDoc = m_headercodedocumentVector.first(); hcodeDoc; hcodeDoc=m_headercodedocumentVector.next())
00175         hcodeDoc->saveToXMI(doc, docElement);
00176 
00177     root.appendChild( docElement );
00178 }
00179 
00184 void CPPCodeGenerator::syncCodeToDocument ( ) {
00185 
00186     CodeDocumentList * docList = getCodeDocumentList();
00187 
00188     for (CodeDocument * doc = docList->first(); doc; doc=docList->next())
00189         doc->synchronize();
00190 
00191     for (CodeDocument * hcodeDoc = m_headercodedocumentVector.first(); hcodeDoc; hcodeDoc=m_headercodedocumentVector.next())
00192         hcodeDoc->synchronize();
00193 
00194 }
00195 
00199 void CPPCodeGenerator::writeCodeToFile ( )
00200 {
00201     // write all source documents (incl. Makefile)
00202     writeListedCodeDocsToFile(getCodeDocumentList());
00203 
00204     // write all header documents
00205     writeListedCodeDocsToFile(&m_headercodedocumentVector);
00206 
00207 }
00208 
00209 // overridden because we need to be able to generate code for
00210 // both the header and source documents
00211 void CPPCodeGenerator::writeCodeToFile ( UMLClassifierList & concepts) {
00212     CodeDocumentList docs;
00213     docs.setAutoDelete(false);
00214 
00215     for (UMLClassifier *concept= concepts.first(); concept; concept= concepts.next())
00216     {
00217         CodeDocument * doc = findCodeDocumentByClassifier(concept);
00218         if(doc)
00219             docs.append(doc);
00220         CodeDocument * hdoc = findHeaderCodeDocumentByClassifier(concept);
00221         if(hdoc)
00222             docs.append(hdoc);
00223     }
00224 
00225     writeListedCodeDocsToFile(&docs);
00226 }
00227 
00228 
00234 CPPHeaderCodeDocument * CPPCodeGenerator::findHeaderCodeDocumentByClassifier (UMLClassifier * classifier )
00235 {
00236     CodeDocument * doc = findCodeDocumentByID("cppheader"+ID2STR(classifier->getID()));
00237     return dynamic_cast<CPPHeaderCodeDocument*>(doc);
00238 }
00239 
00244 // source document version.
00245 CodeDocument * CPPCodeGenerator::newClassifierCodeDocument (UMLClassifier * classifier)
00246 {
00247     ClassifierCodeDocument *doc = new CPPSourceCodeDocument(classifier);
00248     doc->initCodeClassFields();
00249     return doc;
00250 }
00251 
00252 CPPHeaderCodeDocument * CPPCodeGenerator::newHeaderClassifierCodeDocument (UMLClassifier * classifier)
00253 {
00254     CPPHeaderCodeDocument *doc = new CPPHeaderCodeDocument(classifier);
00255     doc->initCodeClassFields();
00256     return doc;
00257 }
00258 
00263 CPPMakefileCodeDocument * CPPCodeGenerator::newMakefileCodeDocument ( ) {
00264     return new CPPMakefileCodeDocument();
00265 }
00266 
00267 
00272 void CPPCodeGenerator::initFromParentDocument( ) {
00273 
00274     // Walk through the document converting classifiers into
00275     // classifier code documents as needed (e.g only if doesn't exist)
00276     UMLClassifierList concepts = UMLApp::app()->getDocument()->getClassesAndInterfaces();
00277     for (UMLClassifier *c = concepts.first(); c; c = concepts.next())
00278     {
00279 
00280         // Doesn't exist? Then build one.
00281         CodeDocument * codeDoc = findCodeDocumentByClassifier(c);
00282         if (!codeDoc)
00283         {
00284             codeDoc = newClassifierCodeDocument(c);
00285             codeDoc->synchronize();
00286             addCodeDocument(codeDoc); // this will also add a unique tag to the code document
00287         }
00288 
00289         CPPHeaderCodeDocument * hcodeDoc = findHeaderCodeDocumentByClassifier(c);
00290         if (!hcodeDoc)
00291         {
00292             hcodeDoc = newHeaderClassifierCodeDocument(c);
00293             hcodeDoc->synchronize();
00294             addHeaderCodeDocument(hcodeDoc); // this will also add a unique tag to the code document
00295         }
00296     }
00297 
00298 }
00299 
00300 // need to worry about adding both source, and header documents for each
00301 // classifier
00302 void CPPCodeGenerator::checkAddUMLObject (UMLObject * obj) {
00303     if (!obj)
00304         return;
00305 
00306     // if the obj being created is a native data type
00307     // there's no reason to create a .h/.cpp file
00308     if (isReservedKeyword(obj->getName()))
00309         return;
00310 
00311     UMLClassifier * c = dynamic_cast<UMLClassifier*>(obj);
00312     if(c) {
00313         CodeDocument * cDoc = newClassifierCodeDocument(c);
00314         CPPHeaderCodeDocument * hcodeDoc = newHeaderClassifierCodeDocument(c);
00315         addCodeDocument(cDoc);
00316         addHeaderCodeDocument(hcodeDoc); // this will also add a unique tag to the code document
00317     }
00318 }
00319 
00320 // need to worry about removing both source, and header documents for each
00321 // classifier
00322 void CPPCodeGenerator::checkRemoveUMLObject (UMLObject * obj)
00323 {
00324 
00325     if (!obj)
00326         return;
00327 
00328     UMLClassifier * c = dynamic_cast<UMLClassifier*>(obj);
00329     if(c) {
00330 
00331         // source
00332         ClassifierCodeDocument * cDoc = (ClassifierCodeDocument*) findCodeDocumentByClassifier(c);
00333         if (cDoc)
00334             removeCodeDocument(cDoc);
00335 
00336         // header
00337         CPPHeaderCodeDocument * hcodeDoc = findHeaderCodeDocumentByClassifier(c);
00338         if (hcodeDoc)
00339             removeHeaderCodeDocument(hcodeDoc);
00340     }
00341 
00342 }
00343 
00344 void CPPCodeGenerator::initAttributes ( )
00345 {
00346     m_createMakefile = false;
00347 
00348     UMLApp::app()->setPolicyExt ( new CPPCodeGenerationPolicy(UMLApp::app()->getConfig()) );
00349 
00350     // load Classifier documents from parent document
00351     //initFromParentDocument();
00352 }
00353 
00354 QStringList CPPCodeGenerator::defaultDatatypes() {
00355     return Codegen_Utils::cppDatatypes();
00356 }
00357 
00358 const QStringList CPPCodeGenerator::reservedKeywords() const {
00359     return Codegen_Utils::reservedCppKeywords();
00360 }
00361 
00362 void CPPCodeGenerator::createDefaultStereotypes (){
00363     Codegen_Utils::createCppStereotypes();
00364 }
00365 
00366 #include "cppcodegenerator.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:55 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003