umbrello API Documentation

jswriter.cpp

00001 /***************************************************************************
00002     begin                : Sat Feb 08 2003
00003     copyright            : (C) 2003 by Alexander Blum
00004     email                : blum@kewbee.de
00005  ***************************************************************************/
00006 
00007 /***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License js published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 #include "jswriter.h"
00017 #include "../association.h"
00018 #include "../classifier.h"
00019 #include "../operation.h"
00020 #include "../umldoc.h"
00021 #include "../attribute.h"
00022 
00023 #include <kdebug.h>
00024 
00025 #include <qregexp.h>
00026 #include <qtextstream.h>
00027 
00028 JSWriter::JSWriter() {
00029 }
00030 
00031 JSWriter::~JSWriter() {}
00032 
00033 
00034 void JSWriter::writeClass(UMLClassifier *c)
00035 {
00036     if(!c)
00037     {
00038         kDebug()<<"Cannot write class of NULL concept!" << endl;
00039         return;
00040     }
00041 
00042     QString classname = cleanName(c->getName());
00043     QString fileName = c->getName().lower();
00044 
00045     //find an appropriate name for our file
00046     fileName = findFileName(c,".js");
00047     if (fileName.isEmpty())
00048     {
00049         emit codeGenerated(c, false);
00050         return;
00051     }
00052 
00053     QFile filejs;
00054     if(!openFile(filejs, fileName))
00055     {
00056         emit codeGenerated(c, false);
00057         return;
00058     }
00059     QTextStream js(&filejs);
00060 
00062     //Start generating the code!!
00064 
00065 
00066     //try to find a heading file (license, coments, etc)
00067     QString str;
00068     str = getHeadingFile(".js");
00069     if(!str.isEmpty())
00070     {
00071         str.replace(QRegExp("%filename%"),fileName);
00072         str.replace(QRegExp("%filepath%"),filejs.name());
00073         js << str << m_endl;
00074     }
00075 
00076 
00077     //write includes
00078     UMLPackageList includes;
00079     findObjectsRelated(c,includes);
00080     for (UMLPackage *conc = includes.first(); conc; conc = includes.next())
00081     {
00082         QString headerName = findFileName(conc, ".js");
00083         if ( !headerName.isEmpty() )
00084         {
00085             js << "#include \"" << headerName << "\"" << m_endl;
00086         }
00087     }
00088     js << m_endl;
00089 
00090     //Write class Documentation if there is somthing or if force option
00091     if(forceDoc() || !c->getDoc().isEmpty())
00092     {
00093         js << m_endl << "" << m_endl << m_endl;
00097     }
00098 
00099 
00100     //check if class is abstract and / or has abstract methods
00101     if(c->getAbstract() && !hasAbstractOps(c))
00102         js << "/******************************* Abstract Class ****************************" << m_endl << "  "
00103         << classname << " does not have any pure virtual methods, but its author" << m_endl
00104         << "  defined it as an abstract class, so you should not use it directly." << m_endl
00105         << "  Inherit from it instead and create only objects from the derived classes" << m_endl
00106         << "*****************************************************************************/" << m_endl << m_endl;
00107 
00108     js << classname << " = function ()" << m_endl;
00109     js << "{" << m_endl;
00110     js << m_indentation << "this._init ();" << m_endl;
00111     js << "}" << m_endl;
00112     js << m_endl;
00113 
00114     UMLClassifierList superclasses = c->getSuperClasses();
00115     for (UMLClassifier *obj = superclasses.first();
00116             obj; obj = superclasses.next()) {
00117         js << classname << ".prototype = new " << cleanName(obj->getName()) << " ();" << m_endl;
00118     }
00119 
00120     js << m_endl;
00121 
00122     if (! c->isInterface()) {
00123         UMLAttributeList atl = c->getAttributeList();
00124 
00125         js << "" << m_endl;
00130         js << classname << ".prototype._init = function ()" << m_endl;
00131         js << "{" << m_endl;
00132         for(UMLAttribute *at = atl.first(); at ; at = atl.next())
00133         {
00134             if (forceDoc() || !at->getDoc().isEmpty())
00135             {
00136                 js << m_indentation << "" << m_endl;
00139             }
00140             if(!at->getInitialValue().isEmpty())
00141             {
00142                 js << m_indentation << "this.m_" << cleanName(at->getName()) << " = " << at->getInitialValue() << ";" << m_endl;
00143             }
00144             else
00145             {
00146                 js << m_indentation << "this.m_" << cleanName(at->getName()) << " = \"\";" << m_endl;
00147             }
00148         }
00149     }
00150 
00151     //associations
00152     UMLAssociationList aggregations = c->getAggregations();
00153     if (forceSections() || !aggregations.isEmpty ())
00154     {
00155         js << m_endl << m_indentation << "/**Aggregations: */" << m_endl;
00156         writeAssociation(classname, aggregations , js );
00157 
00158     }
00159     UMLAssociationList compositions = c->getCompositions();
00160     if( forceSections() || !compositions.isEmpty())
00161     {
00162         js << m_endl << m_indentation << "/**Compositions: */" << m_endl;
00163         writeAssociation(classname, compositions , js );
00164 
00165     }
00166     js << m_endl;
00167     js << "}" << m_endl;
00168     js << m_endl;
00169 
00170     //operations
00171     UMLOperationList ops(c->getOpList());
00172     writeOperations(classname, &ops, js);
00173 
00174     js << m_endl;
00175 
00176     //finish file
00177 
00178     //close files and notfiy we are done
00179     filejs.close();
00180     emit codeGenerated(c, true);
00181 }
00182 
00184 //  Helper Methods
00185 
00186 void JSWriter::writeAssociation(QString& classname, UMLAssociationList& assocList , QTextStream &js)
00187 {
00188     for (UMLAssociation *a = assocList.first(); a; a = assocList.next()) {
00189         // association side
00190         Uml::Role_Type role = (a->getObject(Uml::A)->getName() == classname ? Uml::B : Uml::A);
00191 
00192         QString roleName(cleanName(a->getRoleName(role)));
00193 
00194         if (!roleName.isEmpty()) {
00195 
00196             // association doc
00197             if (forceDoc() || !a->getDoc().isEmpty())
00198             {
00199                 js << m_indentation << "" << m_endl;
00202             }
00203 
00204             // role doc
00205             if (forceDoc() || !a->getRoleDoc(role).isEmpty())
00206             {
00207                 js << m_indentation << "" << m_endl;
00210             }
00211 
00212             bool okCvt;
00213             int nMulti = a->getMulti(role).toInt(&okCvt,10);
00214             bool isNotMulti = a->getMulti(role).isEmpty() || (okCvt && nMulti == 1);
00215 
00216             QString typeName(cleanName(a->getObject(role)->getName()));
00217 
00218             if (isNotMulti)
00219                 js << m_indentation << "this.m_" << roleName << " = new " << typeName << "();" << m_endl;
00220             else
00221                 js << m_indentation << "this.m_" << roleName << " = new Array();" << m_endl;
00222 
00223             // role visibility
00224         }
00225     }
00226 }
00227 
00228 void JSWriter::writeOperations(QString classname, UMLOperationList *opList, QTextStream &js)
00229 {
00230     UMLOperation *op;
00231     UMLAttribute *at;
00232 
00233     for(op = opList->first(); op; op = opList->next())
00234     {
00235         UMLAttributeList atl = op->getParmList();
00236         //write method doc if we have doc || if at least one of the params has doc
00237         bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
00238         for (at = atl.first(); at; at = atl.next())
00239             writeDoc |= !at->getDoc().isEmpty();
00240 
00241         if( writeDoc )  //write method documentation
00242         {
00243             js << "" << m_endl;
00254         }//end if : write method documentation
00255 
00256         js << classname << ".prototype." << cleanName(op->getName()) << " = function " << "(";
00257 
00258         int i = atl.count();
00259         int j=0;
00260         for (at = atl.first(); at ;at = atl.next(),j++)
00261         {
00262             js << cleanName(at->getName())
00263             << (!(at->getInitialValue().isEmpty()) ? (QString(" = ")+at->getInitialValue()) : QString(""))
00264             << ((j < i-1)?", ":"");
00265         }
00266         js << ")" << m_endl << "{" << m_endl <<
00267         m_indentation << m_endl << "}" << m_endl;
00268         js << m_endl << m_endl;
00269     }//end for
00270 }
00271 
00275 Uml::Programming_Language JSWriter::getLanguage() {
00276     return Uml::pl_JavaScript;
00277 }
00278 
00279 const QStringList JSWriter::reservedKeywords() const {
00280 
00281     static QStringList keywords;
00282 
00283     if (keywords.isEmpty()) {
00284         keywords << "break"
00285         << "case"
00286         << "const"
00287         << "continue"
00288         << "default"
00289         << "else"
00290         << "false"
00291         << "for"
00292         << "function"
00293         << "if"
00294         << "in"
00295         << "new"
00296         << "return"
00297         << "switch"
00298         << "this"
00299         << "true"
00300         << "var"
00301         << "while"
00302         << "with";
00303     }
00304 
00305     return keywords;
00306 }
00307 
00308 #include "jswriter.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:57 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003