summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/codegenerators
diff options
context:
space:
mode:
Diffstat (limited to 'umbrello/umbrello/codegenerators')
-rw-r--r--umbrello/umbrello/codegenerators/Makefile.am38
-rw-r--r--umbrello/umbrello/codegenerators/adawriter.cpp686
-rw-r--r--umbrello/umbrello/codegenerators/adawriter.h105
-rw-r--r--umbrello/umbrello/codegenerators/aswriter.cpp775
-rw-r--r--umbrello/umbrello/codegenerators/aswriter.h80
-rw-r--r--umbrello/umbrello/codegenerators/classifierinfo.cpp140
-rw-r--r--umbrello/umbrello/codegenerators/classifierinfo.h126
-rw-r--r--umbrello/umbrello/codegenerators/codegen_utils.cpp413
-rw-r--r--umbrello/umbrello/codegenerators/codegen_utils.h42
-rw-r--r--umbrello/umbrello/codegenerators/codegenfactory.cpp360
-rw-r--r--umbrello/umbrello/codegenerators/codegenfactory.h119
-rw-r--r--umbrello/umbrello/codegenerators/codegenpolicyext.h52
-rw-r--r--umbrello/umbrello/codegenerators/cppcodeclassfield.cpp108
-rw-r--r--umbrello/umbrello/codegenerators/cppcodeclassfield.h62
-rw-r--r--umbrello/umbrello/codegenerators/cppcodecomment.cpp98
-rw-r--r--umbrello/umbrello/codegenerators/cppcodecomment.h83
-rw-r--r--umbrello/umbrello/codegenerators/cppcodedocumentation.cpp141
-rw-r--r--umbrello/umbrello/codegenerators/cppcodedocumentation.h95
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerationform.cpp305
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerationform.h150
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerationformbase.ui481
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerationpolicy.cpp390
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerationpolicy.h227
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.cpp94
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.h48
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerator.cpp366
-rw-r--r--umbrello/umbrello/codegenerators/cppcodegenerator.h167
-rw-r--r--umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.cpp160
-rw-r--r--umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.h67
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.cpp170
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.h57
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.cpp78
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.h51
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodedocument.cpp813
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodedocument.h107
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp175
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodeoperation.h59
-rw-r--r--umbrello/umbrello/codegenerators/cppmakecodedocument.cpp78
-rw-r--r--umbrello/umbrello/codegenerators/cppmakecodedocument.h67
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.cpp169
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.h57
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.cpp74
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.h51
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodedocument.cpp168
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodedocument.h73
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp193
-rw-r--r--umbrello/umbrello/codegenerators/cppsourcecodeoperation.h51
-rw-r--r--umbrello/umbrello/codegenerators/cppwriter.cpp1283
-rw-r--r--umbrello/umbrello/codegenerators/cppwriter.h293
-rw-r--r--umbrello/umbrello/codegenerators/csharpwriter.cpp725
-rw-r--r--umbrello/umbrello/codegenerators/csharpwriter.h163
-rw-r--r--umbrello/umbrello/codegenerators/dwriter.cpp970
-rw-r--r--umbrello/umbrello/codegenerators/dwriter.h276
-rw-r--r--umbrello/umbrello/codegenerators/idlwriter.cpp482
-rw-r--r--umbrello/umbrello/codegenerators/idlwriter.h74
-rw-r--r--umbrello/umbrello/codegenerators/javaantcodedocument.cpp312
-rw-r--r--umbrello/umbrello/codegenerators/javaantcodedocument.h100
-rw-r--r--umbrello/umbrello/codegenerators/javaclassdeclarationblock.cpp169
-rw-r--r--umbrello/umbrello/codegenerators/javaclassdeclarationblock.h66
-rw-r--r--umbrello/umbrello/codegenerators/javaclassifiercodedocument.cpp583
-rw-r--r--umbrello/umbrello/codegenerators/javaclassifiercodedocument.h110
-rw-r--r--umbrello/umbrello/codegenerators/javacodeaccessormethod.cpp223
-rw-r--r--umbrello/umbrello/codegenerators/javacodeaccessormethod.h65
-rw-r--r--umbrello/umbrello/codegenerators/javacodeclassfield.cpp111
-rw-r--r--umbrello/umbrello/codegenerators/javacodeclassfield.h59
-rw-r--r--umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.cpp118
-rw-r--r--umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.h51
-rw-r--r--umbrello/umbrello/codegenerators/javacodecomment.cpp84
-rw-r--r--umbrello/umbrello/codegenerators/javacodecomment.h77
-rw-r--r--umbrello/umbrello/codegenerators/javacodedocumentation.cpp143
-rw-r--r--umbrello/umbrello/codegenerators/javacodedocumentation.h95
-rw-r--r--umbrello/umbrello/codegenerators/javacodegenerationformbase.ui277
-rw-r--r--umbrello/umbrello/codegenerators/javacodegenerationpolicy.cpp188
-rw-r--r--umbrello/umbrello/codegenerators/javacodegenerationpolicy.h116
-rw-r--r--umbrello/umbrello/codegenerators/javacodegenerationpolicypage.cpp84
-rw-r--r--umbrello/umbrello/codegenerators/javacodegenerationpolicypage.h48
-rw-r--r--umbrello/umbrello/codegenerators/javacodegenerator.cpp339
-rw-r--r--umbrello/umbrello/codegenerators/javacodegenerator.h150
-rw-r--r--umbrello/umbrello/codegenerators/javacodeoperation.cpp132
-rw-r--r--umbrello/umbrello/codegenerators/javacodeoperation.h52
-rw-r--r--umbrello/umbrello/codegenerators/javawriter.cpp936
-rw-r--r--umbrello/umbrello/codegenerators/javawriter.h236
-rw-r--r--umbrello/umbrello/codegenerators/jswriter.cpp308
-rw-r--r--umbrello/umbrello/codegenerators/jswriter.h78
-rw-r--r--umbrello/umbrello/codegenerators/pascalwriter.cpp542
-rw-r--r--umbrello/umbrello/codegenerators/pascalwriter.h86
-rw-r--r--umbrello/umbrello/codegenerators/perlwriter.cpp716
-rw-r--r--umbrello/umbrello/codegenerators/perlwriter.h101
-rw-r--r--umbrello/umbrello/codegenerators/php5writer.cpp3418
-rw-r--r--umbrello/umbrello/codegenerators/php5writer.h95
-rw-r--r--umbrello/umbrello/codegenerators/phpwriter.cpp3339
-rw-r--r--umbrello/umbrello/codegenerators/phpwriter.h90
-rw-r--r--umbrello/umbrello/codegenerators/pythonwriter.cpp438
-rw-r--r--umbrello/umbrello/codegenerators/pythonwriter.h86
-rw-r--r--umbrello/umbrello/codegenerators/rubyclassdeclarationblock.cpp147
-rw-r--r--umbrello/umbrello/codegenerators/rubyclassdeclarationblock.h74
-rw-r--r--umbrello/umbrello/codegenerators/rubyclassifiercodedocument.cpp646
-rw-r--r--umbrello/umbrello/codegenerators/rubyclassifiercodedocument.h126
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeaccessormethod.cpp233
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeaccessormethod.h73
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeclassfield.cpp113
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeclassfield.h61
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.cpp112
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.h55
-rw-r--r--umbrello/umbrello/codegenerators/rubycodecomment.cpp85
-rw-r--r--umbrello/umbrello/codegenerators/rubycodecomment.h69
-rw-r--r--umbrello/umbrello/codegenerators/rubycodedocumentation.cpp145
-rw-r--r--umbrello/umbrello/codegenerators/rubycodedocumentation.h97
-rw-r--r--umbrello/umbrello/codegenerators/rubycodegenerationformbase.ui248
-rw-r--r--umbrello/umbrello/codegenerators/rubycodegenerationpolicy.cpp170
-rw-r--r--umbrello/umbrello/codegenerators/rubycodegenerationpolicy.h117
-rw-r--r--umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.cpp75
-rw-r--r--umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.h51
-rw-r--r--umbrello/umbrello/codegenerators/rubycodegenerator.cpp186
-rw-r--r--umbrello/umbrello/codegenerators/rubycodegenerator.h129
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeoperation.cpp226
-rw-r--r--umbrello/umbrello/codegenerators/rubycodeoperation.h54
-rw-r--r--umbrello/umbrello/codegenerators/rubywriter.cpp448
-rw-r--r--umbrello/umbrello/codegenerators/rubywriter.h113
-rw-r--r--umbrello/umbrello/codegenerators/simplecodegenerator.cpp292
-rw-r--r--umbrello/umbrello/codegenerators/simplecodegenerator.h120
-rw-r--r--umbrello/umbrello/codegenerators/sqlwriter.cpp394
-rw-r--r--umbrello/umbrello/codegenerators/sqlwriter.h77
-rw-r--r--umbrello/umbrello/codegenerators/tclwriter.cpp951
-rw-r--r--umbrello/umbrello/codegenerators/tclwriter.h174
-rw-r--r--umbrello/umbrello/codegenerators/xmlcodecomment.cpp67
-rw-r--r--umbrello/umbrello/codegenerators/xmlcodecomment.h68
-rw-r--r--umbrello/umbrello/codegenerators/xmlelementcodeblock.cpp166
-rw-r--r--umbrello/umbrello/codegenerators/xmlelementcodeblock.h88
-rw-r--r--umbrello/umbrello/codegenerators/xmlschemawriter.cpp809
-rw-r--r--umbrello/umbrello/codegenerators/xmlschemawriter.h249
131 files changed, 34264 insertions, 0 deletions
diff --git a/umbrello/umbrello/codegenerators/Makefile.am b/umbrello/umbrello/codegenerators/Makefile.am
new file mode 100644
index 00000000..bc622fe0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/Makefile.am
@@ -0,0 +1,38 @@
+noinst_LTLIBRARIES = libcodegenerator.la
+
+INCLUDES = -I../dialogs -I$(top_srcdir)/umbrello/umbrello/dialogs $(all_includes)
+
+libcodegenerator_la_LDFLAGS = $(all_libraries)
+libcodegenerator_la_METASOURCES = AUTO
+libcodegenerator_la_SOURCES = codegenfactory.cpp classifierinfo.cpp \
+ javacodegenerator.cpp javaantcodedocument.cpp javacodeclassfield.cpp \
+ javaclassifiercodedocument.cpp javacodecomment.cpp javacodedocumentation.cpp \
+ javacodeoperation.cpp javacodeaccessormethod.cpp \
+ javaclassdeclarationblock.cpp javacodeclassfielddeclarationblock.cpp \
+ javacodegenerationpolicy.cpp javacodegenerationpolicypage.cpp \
+ javacodegenerationformbase.ui \
+ cppcodegenerator.cpp cppcodedocumentation.cpp cppcodeclassfield.cpp \
+ cppcodecomment.cpp cppmakecodedocument.cpp \
+ cppsourcecodedocument.cpp cppsourcecodeoperation.cpp cppsourcecodeaccessormethod.cpp \
+ cppsourcecodeclassfielddeclarationblock.cpp \
+ cppheadercodedocument.cpp cppheaderclassdeclarationblock.cpp \
+ cppheadercodeoperation.cpp cppheadercodeaccessormethod.cpp \
+ cppheadercodeclassfielddeclarationblock.cpp \
+ cppcodegenerationpolicy.cpp cppcodegenerationpolicypage.cpp \
+ cppcodegenerationformbase.ui cppcodegenerationform.cpp \
+ rubycodegenerator.cpp rubycodeclassfield.cpp \
+ rubyclassifiercodedocument.cpp rubycodecomment.cpp rubycodedocumentation.cpp \
+ rubycodeoperation.cpp rubycodeaccessormethod.cpp \
+ rubyclassdeclarationblock.cpp rubycodeclassfielddeclarationblock.cpp \
+ rubycodegenerationpolicy.cpp rubycodegenerationpolicypage.cpp \
+ rubycodegenerationformbase.ui \
+ simplecodegenerator.cpp \
+ adawriter.cpp aswriter.cpp cppwriter.cpp csharpwriter.cpp dwriter.cpp javawriter.cpp jswriter.cpp \
+ idlwriter.cpp pascalwriter.cpp perlwriter.cpp php5writer.cpp phpwriter.cpp \
+ pythonwriter.cpp rubywriter.cpp sqlwriter.cpp tclwriter.cpp xmlschemawriter.cpp \
+ xmlelementcodeblock.cpp xmlcodecomment.cpp \
+ codegen_utils.cpp
+libcodegenerator_la_COMPILE_FIRST = ../dialogs/codegenerationpolicybase.h
+
+KDE_OPTIONS = nofinal
+
diff --git a/umbrello/umbrello/codegenerators/adawriter.cpp b/umbrello/umbrello/codegenerators/adawriter.cpp
new file mode 100644
index 00000000..e1c79839
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/adawriter.cpp
@@ -0,0 +1,686 @@
+/***************************************************************************
+ * adawriter.cpp - description *
+ * ------------------- *
+ * Based on javawriter.cpp by Luis De la Parra Blum *
+ * copyright : (C) 2002 by Oliver Kellogg *
+ * (C) 2003-2007 Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "adawriter.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include "../umldoc.h"
+#include "../uml.h"
+#include "../classifier.h"
+#include "../enum.h"
+#include "../classifierlistitem.h"
+#include "../umlclassifierlistitemlist.h"
+#include "../umltemplatelist.h"
+#include "../folder.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../operation.h"
+#include "../template.h"
+#include "../umlnamespace.h"
+
+const QString AdaWriter::defaultPackageSuffix = "_Holder";
+
+AdaWriter::AdaWriter() {
+}
+
+AdaWriter::~AdaWriter() {}
+
+/**
+ * returns "Ada"
+ */
+Uml::Programming_Language AdaWriter::getLanguage() {
+ return Uml::pl_Ada;
+}
+
+
+bool AdaWriter::isOOClass(UMLClassifier *c) {
+ Uml::Object_Type ot = c->getBaseType();
+ if (ot == Uml::ot_Interface)
+ return true;
+ if (ot == Uml::ot_Enum)
+ return false;
+ if (ot != Uml::ot_Class) {
+ kDebug() << "AdaWriter::isOOClass: unknown object type " << ot << endl;
+ return false;
+ }
+ QString stype = c->getStereotype();
+ if (stype == "CORBAConstant" || stype == "CORBATypedef" ||
+ stype == "CORBAStruct" || stype == "CORBAUnion")
+ return false;
+ // CORBAValue, CORBAInterface, and all empty/unknown stereotypes are
+ // assumed to be OO classes.
+ return true;
+}
+
+QString AdaWriter::className(UMLClassifier *c, bool inOwnScope) {
+ // If the class has an enclosing package then it is assumed that
+ // the class name is the type name; if the class does not have an
+ // enclosing package then the class name acts as the Ada package
+ // name.
+ QString retval;
+ QString className = cleanName(c->getName());
+ UMLPackage *umlPkg = c->getUMLPackage();
+ if (umlPkg == UMLApp::app()->getDocument()->getRootFolder(Uml::mt_Logical)) {
+ if (! inOwnScope)
+ retval = className + '.';
+ retval.append("Object");
+ } else {
+ if (! inOwnScope)
+ retval = umlPkg->getFullyQualifiedName(".") + '.';
+ retval.append(className);
+ }
+ return retval;
+}
+
+QString AdaWriter::packageName(UMLPackage *p) {
+ // If the class has an enclosing package then it is assumed that
+ // the class name is the type name; if the class does not have an
+ // enclosing package then the class name acts as the Ada package
+ // name.
+ UMLPackage *umlPkg = p->getUMLPackage();
+ QString className = cleanName(p->getName());
+ QString retval;
+
+ if (umlPkg == UMLApp::app()->getDocument()->getRootFolder(Uml::mt_Logical))
+ umlPkg = NULL;
+
+ UMLClassifier *c = dynamic_cast<UMLClassifier*>(p);
+ if (umlPkg == NULL) {
+ retval = className;
+ if (c == NULL || !isOOClass(c))
+ retval.append(defaultPackageSuffix);
+ } else {
+ retval = umlPkg->getFullyQualifiedName(".");
+ }
+ return retval;
+}
+
+void AdaWriter::computeAssocTypeAndRole(UMLClassifier *c,
+ UMLAssociation *a,
+ QString& typeName, QString& roleName) {
+ UMLClassifier* assocEnd = dynamic_cast<UMLClassifier*>(a->getObject(Uml::B));
+ if (assocEnd == NULL)
+ return;
+ const Uml::Association_Type assocType = a->getAssocType();
+ if (assocType != Uml::at_Aggregation && assocType != Uml::at_Composition)
+ return;
+ const QString multi = a->getMulti(Uml::B);
+ bool hasNonUnityMultiplicity = (!multi.isEmpty() && multi != "1");
+ hasNonUnityMultiplicity &= !multi.contains(QRegExp("^1 *\\.\\. *1$"));
+ roleName = cleanName(a->getRoleName(Uml::B));
+ if (roleName.isEmpty())
+ roleName = cleanName(a->getName());
+ if (roleName.isEmpty()) {
+ QString artificialName = cleanName(assocEnd->getName());
+ if (hasNonUnityMultiplicity) {
+ roleName = artificialName;
+ roleName.append("_Vector");
+ } else {
+ roleName = "M_";
+ roleName.append(artificialName);
+ }
+ }
+ typeName = className(assocEnd, (assocEnd == c));
+ if (hasNonUnityMultiplicity)
+ typeName.append("_Array_Ptr");
+ else if (assocType == Uml::at_Aggregation)
+ typeName.append("_Ptr");
+}
+
+void AdaWriter::writeClass(UMLClassifier *c) {
+ if (!c) {
+ kDebug() << "Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ const bool isClass = !c->isInterface();
+ QString classname = cleanName(c->getName());
+ QString fileName = packageName(c).lower();
+ fileName.replace('.', '-');
+
+ //find an appropriate name for our file
+ fileName = overwritableName(c, fileName, ".ads");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile file;
+ if (!openFile(file, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // Start generating the code.
+
+ QTextStream ada(&file);
+ //try to find a heading file(license, comments, etc)
+ QString str;
+ str = getHeadingFile(".ads");
+ if (!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"), fileName);
+ str.replace(QRegExp("%filepath%"), file.name());
+ ada << str << endl;
+ }
+
+ // Import referenced classes.
+ UMLPackageList imports;
+ findObjectsRelated(c, imports);
+ if (imports.count()) {
+ for (UMLPackage *con = imports.first(); con; con = imports.next()) {
+ if (con->getBaseType() != Uml::ot_Datatype)
+ ada << "with " << packageName(con) << "; " << m_endl;
+ }
+ ada << m_endl;
+ }
+
+ // Generate generic formals.
+ UMLTemplateList template_params = c->getTemplateList();
+ if (template_params.count()) {
+ ada << getIndent() << "generic" << m_endl;
+ m_indentLevel++;
+ for (UMLTemplate *t = template_params.first(); t; t = template_params.next()) {
+ QString formalName = t->getName();
+ QString typeName = t->getTypeName();
+ if (typeName == "class") {
+ ada << getIndent() << "type " << formalName << " is tagged private;"
+ << m_endl;
+ } else {
+ // Check whether it's a data type.
+ UMLClassifier *typeObj = t->getType();
+ if (typeObj == NULL) {
+ kError() << "AdaWriter::writeClass(template_param "
+ << typeName << "): typeObj is NULL" << endl;
+ ada << getIndent() << "type " << formalName << " is new " << typeName
+ << " with private; -- CHECK: codegen error"
+ << m_endl;
+ } else if (typeObj->getBaseType() == Uml::ot_Datatype) {
+ ada << getIndent() << formalName << " : " << typeName << ";"
+ << m_endl;
+ } else {
+ ada << getIndent() << "type " << typeName << " is new "
+ << formalName << " with private;" << m_endl;
+ }
+ }
+ }
+ m_indentLevel--;
+ }
+
+ // Here comes the package proper.
+ QString pkg = packageName(c);
+ ada << getIndent() << "package " << pkg << " is" << m_endl << m_endl;
+ m_indentLevel++;
+ if (c->getBaseType() == Uml::ot_Enum) {
+ UMLEnum *ue = static_cast<UMLEnum*>(c);
+ UMLClassifierListItemList litList = ue->getFilteredList(Uml::ot_EnumLiteral);
+ uint i = 0;
+ ada << getIndent() << "type " << classname << " is (" << m_endl;
+ m_indentLevel++;
+ for (UMLClassifierListItem *lit = litList.first(); lit; lit = litList.next()) {
+ QString enumLiteral = cleanName(lit->getName());
+ ada << getIndent() << enumLiteral;
+ if (++i < litList.count())
+ ada << "," << m_endl;
+ }
+ m_indentLevel--;
+ ada << ");" << m_endl << m_endl;
+ m_indentLevel--;
+ ada << getIndent() << "end " << pkg << ";" << m_endl << m_endl;
+ return;
+ }
+ if (! isOOClass(c)) {
+ QString stype = c->getStereotype();
+ if (stype == "CORBAConstant") {
+ ada << getIndent() << "-- " << stype << " is Not Yet Implemented" << m_endl << m_endl;
+ } else if(stype == "CORBAStruct") {
+ if (isClass) {
+ UMLAttributeList atl = c->getAttributeList();
+ UMLAttribute *at;
+ ada << getIndent() << "type " << classname << " is record" << m_endl;
+ m_indentLevel++;
+ for (at = atl.first(); at; at = atl.next()) {
+ QString name = cleanName(at->getName());
+ QString typeName = at->getTypeName();
+ ada << getIndent() << name << " : " << typeName;
+ QString initialVal = at->getInitialValue();
+ if (initialVal.latin1() && ! initialVal.isEmpty())
+ ada << " := " << initialVal;
+ ada << ";" << m_endl;
+ }
+ m_indentLevel--;
+ ada << getIndent() << "end record;" << m_endl << m_endl;
+ }
+ } else if(stype == "CORBAUnion") {
+ ada << getIndent() << "-- " << stype << " is Not Yet Implemented" << m_endl << m_endl;
+ } else if(stype == "CORBATypedef") {
+ ada << getIndent() << "-- " << stype << " is Not Yet Implemented" << m_endl << m_endl;
+ } else {
+ ada << getIndent() << "-- " << stype << ": Unknown stereotype" << m_endl << m_endl;
+ }
+ m_indentLevel--;
+ ada << getIndent() << "end " << pkg << ";" << m_endl << m_endl;
+ return;
+ }
+
+ // Write class Documentation if non-empty or if force option set.
+ if (forceDoc() || !c->getDoc().isEmpty()) {
+ ada << "--" << m_endl;
+ ada << "-- class " << classname << endl;
+ ada << formatDoc(c->getDoc(), "-- ");
+ ada << m_endl;
+ }
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+
+ const QString name = className(c);
+ ada << getIndent() << "type " << name << " is ";
+ if (c->getAbstract())
+ ada << "abstract ";
+ if (superclasses.isEmpty()) {
+ ada << "tagged ";
+ } else {
+ // FIXME: Multiple inheritance is not yet supported
+ UMLClassifier* parent = superclasses.first();
+ ada << "new " << className(parent, false) << " with ";
+ }
+ ada << "private;" << m_endl << m_endl;
+ ada << getIndent() << "type " << name << "_Ptr is access all " << name << "'Class;" << m_endl << m_endl;
+ ada << getIndent() << "type " << name << "_Array is array (Positive range <>) of " << name << "_Ptr;" << m_endl << m_endl;
+ ada << getIndent() << "type " << name << "_Array_Ptr is access " << name << "_Array;" << m_endl << m_endl;
+
+ // Generate accessors for public attributes.
+ UMLAttributeList atl;
+ if (isClass) {
+ UMLAttributeList atpub;
+ atpub.setAutoDelete(false);
+
+ atl = c->getAttributeList();
+
+ UMLAttribute *at;
+ for (at = atl.first(); at; at = atl.next()) {
+ if (at->getVisibility() == Uml::Visibility::Public)
+ atpub.append(at);
+ }
+ if (forceSections() || atpub.count())
+ ada << getIndent() << "-- Accessors for public attributes:" << m_endl << m_endl;
+ for (at = atpub.first(); at; at = atpub.next()) {
+ QString member = cleanName(at->getName());
+ ada << getIndent() << "procedure Set_" << member << " (";
+ if (! at->getStatic())
+ ada << "Self : access " << name << "; ";
+ ada << "To : " << at->getTypeName() << ");" << m_endl;
+ ada << getIndent() << "function Get_" << member;
+ if (! at->getStatic())
+ ada << " (Self : access " << name << ")";
+ ada << " return " << at->getTypeName() << ";" << m_endl
+ << m_endl;
+ }
+ }
+
+ // Generate public operations.
+ UMLOperationList opl(c->getOpList());
+ UMLOperationList oppub;
+ oppub.setAutoDelete(false);
+ UMLOperation *op;
+ for (op = opl.first(); op; op = opl.next()) {
+ if (op->getVisibility() == Uml::Visibility::Public)
+ oppub.append(op);
+ }
+ if (forceSections() || oppub.count())
+ ada << getIndent() << "-- Public methods:" << m_endl << m_endl;
+ for (op = oppub.first(); op; op = oppub.next())
+ writeOperation(op, ada);
+
+ m_indentLevel--;
+ ada << getIndent() << "private" << m_endl << m_endl;
+ m_indentLevel++;
+
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ ada << getIndent() << "type " << name << " is ";
+ if (c->getAbstract())
+ ada << "abstract ";
+ if (superclasses.isEmpty()) {
+ ada << "tagged ";
+ } else {
+ // FIXME: Multiple inheritance is not yet supported
+ UMLClassifier* parent = superclasses.first();
+ ada << "new " << className(parent, false) << " with ";
+ }
+ ada << "record" << m_endl;
+ m_indentLevel++;
+
+ if (forceSections() || !aggregations.isEmpty()) {
+ ada << getIndent() << "-- Aggregations:" << m_endl;
+ for (UMLAssociation *a = aggregations.first(); a; a = aggregations.next()) {
+ if (c != a->getObject(Uml::A))
+ continue;
+ QString typeName, roleName;
+ computeAssocTypeAndRole(c, a, typeName, roleName);
+ ada << getIndent() << roleName << " : " << typeName << ";" << m_endl;
+ }
+ ada << endl;
+ }
+ if (forceSections() || !compositions.isEmpty()) {
+ ada << getIndent() << "-- Compositions:" << m_endl;
+ for (UMLAssociation *a = compositions.first(); a; a = compositions.next()) {
+ if (c != a->getObject(Uml::A))
+ continue;
+ QString typeName, roleName;
+ computeAssocTypeAndRole(c, a, typeName, roleName);
+ ada << getIndent() << roleName << " : " << typeName << ";" << m_endl;
+ }
+ ada << endl;
+ }
+
+ if (isClass && (forceSections() || atl.count())) {
+ ada << getIndent() << "-- Attributes:" << m_endl;
+ UMLAttribute *at;
+ for (at = atl.first(); at; at = atl.next()) {
+ if (at->getStatic())
+ continue;
+ ada << getIndent() << cleanName(at->getName()) << " : "
+ << at->getTypeName();
+ if (at && at->getInitialValue().latin1() && ! at->getInitialValue().isEmpty())
+ ada << " := " << at->getInitialValue();
+ ada << ";" << m_endl;
+ }
+ }
+ bool haveAttrs = (isClass && atl.count());
+ if (aggregations.isEmpty() && compositions.isEmpty() && !haveAttrs)
+ ada << getIndent() << "null;" << m_endl;
+ m_indentLevel--;
+ ada << getIndent() << "end record;" << m_endl << m_endl;
+ if (haveAttrs) {
+ bool seen_static_attr = false;
+ for (UMLAttribute *at = atl.first(); at; at = atl.next()) {
+ if (! at->getStatic())
+ continue;
+ if (! seen_static_attr) {
+ ada << getIndent() << "-- Static attributes:" << m_endl;
+ seen_static_attr = true;
+ }
+ ada << getIndent();
+ if (at->getVisibility() == Uml::Visibility::Private)
+ ada << "-- Private: ";
+ ada << cleanName(at->getName()) << " : " << at->getTypeName();
+ if (at && at->getInitialValue().latin1() && ! at->getInitialValue().isEmpty())
+ ada << " := " << at->getInitialValue();
+ ada << ";" << m_endl;
+ }
+ if (seen_static_attr)
+ ada << m_endl;
+ }
+ // Generate protected operations.
+ UMLOperationList opprot;
+ opprot.setAutoDelete(false);
+ for (op = opl.first(); op; op = opl.next()) {
+ if (op->getVisibility() == Uml::Visibility::Protected)
+ opprot.append(op);
+ }
+ if (forceSections() || opprot.count())
+ ada << getIndent() << "-- Protected methods:" << m_endl << m_endl;
+ for (op = opprot.first(); op; op = opprot.next())
+ writeOperation(op, ada);
+
+ // Generate private operations.
+ // These are currently only generated as comments in the private part
+ // of the spec.
+ // Once umbrello supports the merging of automatically generated and
+ // hand written code sections, private operations should be generated
+ // into the package body.
+ UMLOperationList oppriv;
+ oppriv.setAutoDelete(false);
+ for (op = opl.first(); op; op = opl.next()) {
+ const Uml::Visibility::Value vis = op->getVisibility();
+ if (vis == Uml::Visibility::Private ||
+ vis == Uml::Visibility::Implementation)
+ oppriv.append(op);
+ }
+ if (forceSections() || oppriv.count())
+ ada << getIndent() << "-- Private methods:" << m_endl << m_endl;
+ for (op = oppriv.first(); op; op = oppriv.next())
+ writeOperation(op, ada, true);
+
+ m_indentLevel--;
+ ada << getIndent() << "end " << pkg << ";" << m_endl << m_endl;
+ file.close();
+ emit codeGenerated(c, true);
+}
+
+
+void AdaWriter::writeOperation(UMLOperation *op, QTextStream &ada, bool is_comment) {
+ UMLAttributeList atl = op->getParmList();
+ QString rettype = op->getTypeName();
+ bool use_procedure = (rettype.isEmpty() || rettype == "void");
+
+ ada << getIndent();
+ if (is_comment)
+ ada << "-- ";
+ if (use_procedure)
+ ada << "procedure ";
+ else
+ ada << "function ";
+ ada << cleanName(op->getName()) << " ";
+ if (! (op->getStatic() && atl.count() == 0))
+ ada << "(";
+ UMLClassifier *parentClassifier = static_cast<UMLClassifier*>(op->getUMLPackage());
+ if (! op->getStatic()) {
+ ada << "Self : access " << className(parentClassifier);
+ if (atl.count())
+ ada << ";" << m_endl;
+ }
+ if (atl.count()) {
+ uint i = 0;
+ m_indentLevel++;
+ for (UMLAttribute *at = atl.first(); at; at = atl.next()) {
+ ada << getIndent();
+ if (is_comment)
+ ada << "-- ";
+ ada << cleanName(at->getName()) << " : ";
+ Uml::Parameter_Direction pk = at->getParmKind();
+ if (pk == Uml::pd_Out)
+ ada << "out ";
+ else if (pk == Uml::pd_InOut)
+ ada << "in out ";
+ else
+ ada << "in ";
+ ada << at->getTypeName();
+ if (! at->getInitialValue().isEmpty())
+ ada << " := " << at->getInitialValue();
+ if (++i < atl.count()) //FIXME gcc warning
+ ada << ";" << m_endl;
+ }
+ m_indentLevel--;
+ }
+ if (! (op->getStatic() && atl.count() == 0))
+ ada << ")";
+ if (! use_procedure)
+ ada << " return " << rettype;
+ if (op->getAbstract())
+ ada << " is abstract";
+ ada << ";" << m_endl << m_endl;
+}
+
+QStringList AdaWriter::defaultDatatypes() {
+ QStringList l;
+ l.append("Boolean");
+ l.append("Character");
+ l.append("Positive");
+ l.append("Natural");
+ l.append("Integer");
+ l.append("Short_Integer");
+ l.append("Long_Integer");
+ l.append("Float");
+ l.append("Long_Float");
+ l.append("Duration");
+ l.append("String");
+ return l;
+}
+
+/**
+ * Check whether the given string is a reserved word for the
+ * language of this code generator
+ *
+ * @param rPossiblyReservedKeyword The string to check.
+ */
+bool AdaWriter::isReservedKeyword(const QString & rPossiblyReservedKeyword) {
+
+ const QStringList keywords = reservedKeywords();
+
+ QStringList::ConstIterator it;
+ for (it = keywords.begin(); it != keywords.end(); ++it)
+ if ((*it).lower() == rPossiblyReservedKeyword.lower())
+ return true;
+
+ return false;
+}
+
+/**
+ * get list of reserved keywords
+ */
+const QStringList AdaWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if ( keywords.isEmpty() ) {
+ keywords.append( "abort" );
+ keywords.append( "abs" );
+ keywords.append( "abstract" );
+ keywords.append( "accept" );
+ keywords.append( "access" );
+ keywords.append( "aliased" );
+ keywords.append( "all" );
+ keywords.append( "and" );
+ keywords.append( "Argument_Error" );
+ keywords.append( "array" );
+ keywords.append( "Assert_Failure" );
+ keywords.append( "at" );
+ keywords.append( "begin" );
+ keywords.append( "body" );
+ keywords.append( "Boolean" );
+ keywords.append( "case" );
+ keywords.append( "Character" );
+ keywords.append( "constant" );
+ keywords.append( "Constraint_Error" );
+ keywords.append( "Conversion_Error" );
+ keywords.append( "Data_Error" );
+ keywords.append( "declare" );
+ keywords.append( "delay" );
+ keywords.append( "delta" );
+ keywords.append( "Dereference_Error" );
+ keywords.append( "Device_Error" );
+ keywords.append( "digits" );
+ keywords.append( "do" );
+ keywords.append( "Duration" );
+ keywords.append( "else" );
+ keywords.append( "elsif" );
+ keywords.append( "end" );
+ keywords.append( "End_Error" );
+ keywords.append( "entry" );
+ keywords.append( "exception" );
+ keywords.append( "exit" );
+ keywords.append( "false" );
+ keywords.append( "Float" );
+ keywords.append( "for" );
+ keywords.append( "function" );
+ keywords.append( "generic" );
+ keywords.append( "goto" );
+ keywords.append( "if" );
+ keywords.append( "in" );
+ keywords.append( "Index_Error" );
+ keywords.append( "Integer" );
+ keywords.append( "is" );
+ keywords.append( "Layout_Error" );
+ keywords.append( "Length_Error" );
+ keywords.append( "limited" );
+ keywords.append( "Long_Float" );
+ keywords.append( "Long_Integer" );
+ keywords.append( "Long_Long_Float" );
+ keywords.append( "Long_Long_Integer" );
+ keywords.append( "loop" );
+ keywords.append( "mod" );
+ keywords.append( "Mode_Error" );
+ keywords.append( "Name_Error" );
+ keywords.append( "Natural" );
+ keywords.append( "new" );
+ keywords.append( "not" );
+ keywords.append( "null" );
+ keywords.append( "of" );
+ keywords.append( "or" );
+ keywords.append( "others" );
+ keywords.append( "out" );
+ keywords.append( "package" );
+ keywords.append( "Pattern_Error" );
+ keywords.append( "Picture_Error" );
+ keywords.append( "Pointer_Error" );
+ keywords.append( "Positive" );
+ keywords.append( "pragma" );
+ keywords.append( "private" );
+ keywords.append( "procedure" );
+ keywords.append( "Program_Error" );
+ keywords.append( "protected" );
+ keywords.append( "raise" );
+ keywords.append( "range" );
+ keywords.append( "record" );
+ keywords.append( "rem" );
+ keywords.append( "renames" );
+ keywords.append( "requeue" );
+ keywords.append( "return" );
+ keywords.append( "reverse" );
+ keywords.append( "select" );
+ keywords.append( "separate" );
+ keywords.append( "Short_Float" );
+ keywords.append( "Short_Integer" );
+ keywords.append( "Short_Short_Float" );
+ keywords.append( "Short_Short_Integer" );
+ keywords.append( "Status_Error" );
+ keywords.append( "Storage_Error" );
+ keywords.append( "String" );
+ keywords.append( "subtype" );
+ keywords.append( "Tag_Error" );
+ keywords.append( "tagged" );
+ keywords.append( "task" );
+ keywords.append( "Tasking_Error" );
+ keywords.append( "terminate" );
+ keywords.append( "Terminator_Error" );
+ keywords.append( "then" );
+ keywords.append( "Time_Error" );
+ keywords.append( "Translation_Error" );
+ keywords.append( "true" );
+ keywords.append( "type" );
+ keywords.append( "until" );
+ keywords.append( "Update_Error" );
+ keywords.append( "use" );
+ keywords.append( "Use_Error" );
+ keywords.append( "when" );
+ keywords.append( "while" );
+ keywords.append( "Wide_Character" );
+ keywords.append( "Wide_String" );
+ keywords.append( "with" );
+ keywords.append( "xor" );
+ }
+
+ return keywords;
+}
+
+#include "adawriter.moc"
diff --git a/umbrello/umbrello/codegenerators/adawriter.h b/umbrello/umbrello/codegenerators/adawriter.h
new file mode 100644
index 00000000..ca5d9f67
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/adawriter.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ adawriter.h - description
+ -------------------
+ Based on javawriter.h by Luis De la Parra Blum
+ begin : Sat Dec 14 2002
+ copyright : (C) 2002 by Oliver Kellogg
+ email : okellogg@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef ADAWRITER_H
+#define ADAWRITER_H
+
+#include "simplecodegenerator.h"
+
+class UMLAssociation;
+class UMLOperation;
+
+/**
+ * class AdaWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate an Ada package spec for
+ * that concept
+ */
+class AdaWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ /**
+ * Basic Constructor
+ */
+ AdaWriter ();
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~AdaWriter ();
+
+ /**
+ * call this method to generate Ada code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass (UMLClassifier *c);
+
+ /**
+ * returns "Ada"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ QStringList defaultDatatypes();
+
+ /**
+ * Check whether the given string is a reserved word for the
+ * language of this code generator
+ *
+ * @param rPossiblyReservedKeyword The string to check.
+ * @return true if the keyword is reserved
+ */
+ virtual bool isReservedKeyword(const QString & rPossiblyReservedKeyword);
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * write one operation
+ * @param op the class for which we are generating code
+ * @param ada the stream associated with the output file
+ */
+ void writeOperation (UMLOperation *op, QTextStream &ada, bool is_comment = false);
+
+ /**
+ * Compute the type and role name from the given association.
+ *
+ * @param c The UMLClassifier for which code is being generated.
+ * @param a The UMLAssociation to analyze.
+ * @param typeName Return value: type name.
+ * @param roleName Return value: role name.
+ */
+ void computeAssocTypeAndRole (UMLClassifier *c,
+ UMLAssociation *a,
+ QString& typeName, QString& roleName);
+
+ bool isOOClass (UMLClassifier *c);
+
+ QString className(UMLClassifier *c, bool inOwnScope = true);
+
+ QString packageName(UMLPackage *p);
+
+ static const QString defaultPackageSuffix;
+
+};
+
+#endif // ADAWRITER_H
diff --git a/umbrello/umbrello/codegenerators/aswriter.cpp b/umbrello/umbrello/codegenerators/aswriter.cpp
new file mode 100644
index 00000000..ad55839d
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/aswriter.cpp
@@ -0,0 +1,775 @@
+/***************************************************************************
+ begin : Sat Feb 08 2003
+ copyright : (C) 2003 by Alexander Blum
+ email : blum@kewbee.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "aswriter.h"
+#include "../association.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../umldoc.h"
+#include "../attribute.h"
+
+#include <kdebug.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+ASWriter::ASWriter() {
+}
+
+ASWriter::~ASWriter() {}
+
+
+void ASWriter::writeClass(UMLClassifier *c)
+{
+ if(!c)
+ {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ QString classname = cleanName(c->getName());
+ QString fileName = c->getName().lower();
+
+ //find an appropriate name for our file
+ fileName = findFileName(c,".as");
+ if (fileName.isEmpty())
+ {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile fileas;
+ if(!openFile(fileas,fileName))
+ {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream as(&fileas);
+
+ //////////////////////////////
+ //Start generating the code!!
+ /////////////////////////////
+
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".as");
+ if(!str.isEmpty())
+ {
+ str.replace(QRegExp("%filename%"),fileName+".as");
+ str.replace(QRegExp("%filepath%"),fileas.name());
+ as << str << m_endl;
+ }
+
+
+ //write includes
+ UMLPackageList includes;
+ findObjectsRelated(c,includes);
+ for (UMLPackage *conc = includes.first(); conc; conc = includes.next())
+ {
+ QString headerName = findFileName(conc, ".as");
+ if ( !headerName.isEmpty() )
+ {
+ as << "#include \"" << findFileName(conc,".as") << "\"" << m_endl;
+ }
+ }
+ as << m_endl;
+
+ //Write class Documentation if there is somthing or if force option
+ if(forceDoc() || !c->getDoc().isEmpty())
+ {
+ as << m_endl << "/**" << m_endl;
+ as << " * class " << classname << m_endl;
+ as << formatDoc(c->getDoc()," * ");
+ as << " */" << m_endl << m_endl;
+ }
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ //check if class is abstract and / or has abstract methods
+ if(c->getAbstract() && !hasAbstractOps(c))
+ as << "/******************************* Abstract Class ****************************" << m_endl << " "
+ << classname << " does not have any pure virtual methods, but its author" << m_endl
+ << " defined it as an abstract class, so you should not use it directly." << m_endl
+ << " Inherit from it instead and create only objects from the derived classes" << m_endl
+ << "*****************************************************************************/" << m_endl << m_endl;
+
+ as << classname << " = function ()" << m_endl;
+ as << "{" << m_endl;
+ as << m_indentation << "this._init ();" << m_endl;
+ as << "}" << m_endl;
+ as << m_endl;
+
+ for(UMLClassifier *obj = superclasses.first();
+ obj; obj = superclasses.next()) {
+ as << classname << ".prototype = new " << cleanName(obj->getName()) << " ();" << m_endl;
+ }
+
+ as << m_endl;
+
+ const bool isClass = !c->isInterface();
+ if (isClass) {
+
+ UMLAttributeList atl = c->getAttributeList();
+
+ as << "/**" << m_endl;
+ QString temp = "_init sets all " + classname +
+ " attributes to their default values. " +
+ "Make sure to call this method within your class constructor";
+ as << formatDoc(temp, " * ");
+ as << " */" << m_endl;
+ as << classname << ".prototype._init = function ()" << m_endl;
+ as << "{" << m_endl;
+ for(UMLAttribute *at = atl.first(); at ; at = atl.next())
+ {
+ if (forceDoc() || !at->getDoc().isEmpty())
+ {
+ as << m_indentation << "/**" << m_endl
+ << formatDoc(at->getDoc(), m_indentation + " * ")
+ << m_indentation << " */" << m_endl;
+ }
+ if(!at->getInitialValue().isEmpty())
+ {
+ as << m_indentation << "this.m_" << cleanName(at->getName()) << " = " << at->getInitialValue() << ";" << m_endl;
+ }
+ else
+ {
+ as << m_indentation << "this.m_" << cleanName(at->getName()) << " = \"\";" << m_endl;
+ }
+ }
+ }
+
+ //associations
+ if (forceSections() || !aggregations.isEmpty ())
+ {
+ as << m_endl << m_indentation << "/**Aggregations: */" << m_endl;
+ writeAssociation(classname, aggregations , as );
+
+ }
+
+ if( forceSections() || !compositions.isEmpty())
+ {
+ as << m_endl << m_indentation << "/**Compositions: */" << m_endl;
+ writeAssociation(classname, compositions , as );
+ }
+
+ as << m_endl;
+ as << m_indentation << "/**Protected: */" << m_endl;
+
+ if (isClass) {
+ UMLAttributeList atl = c->getAttributeList();
+ for (UMLAttribute *at = atl.first(); at ; at = atl.next())
+ {
+ if (at->getVisibility() == Uml::Visibility::Protected)
+ {
+ as << m_indentation << "ASSetPropFlags (this, \"" << cleanName(at->getName()) << "\", 1);" << m_endl;
+ }
+ }
+ }
+
+ UMLOperationList opList(c->getOpList());
+ for (UMLOperation *op = opList.first(); op; op = opList.next())
+ {
+ if (op->getVisibility() == Uml::Visibility::Protected)
+ {
+ as << m_indentation << "ASSetPropFlags (this, \"" << cleanName(op->getName()) << "\", 1);" << m_endl;
+ }
+ }
+ as << m_endl;
+ as << m_indentation << "/**Private: */" << m_endl;
+ if (isClass) {
+ UMLAttributeList atl = c->getAttributeList();
+ for (UMLAttribute *at = atl.first(); at; at = atl.next())
+ {
+ if (at->getVisibility() == Uml::Visibility::Private)
+ {
+ as << m_indentation << "ASSetPropFlags (this, \"" << cleanName(at->getName()) << "\", 7);" << m_endl;
+ }
+ }
+ }
+
+ for (UMLOperation *op = opList.first(); op; op = opList.next())
+ {
+ if (op->getVisibility() == Uml::Visibility::Protected)
+ {
+ as << m_indentation << "ASSetPropFlags (this, \"" << cleanName(op->getName()) << "\", 7);" << m_endl;
+ }
+ }
+ as << "}" << m_endl;
+
+ as << m_endl;
+
+ //operations
+ UMLOperationList ops(c->getOpList());
+ writeOperations(classname, &ops, as);
+
+ as << m_endl;
+
+ //finish file
+
+ //close files and notfiy we are done
+ fileas.close();
+ emit codeGenerated(c, true);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+
+void ASWriter::writeAssociation(QString& classname, UMLAssociationList& assocList , QTextStream &as )
+{
+ for(UMLAssociation *a = assocList.first(); a; a = assocList.next())
+ {
+ // association side
+ Uml::Role_Type role = a->getObject(Uml::A)->getName() == classname ? Uml::B:Uml::A;
+
+ QString roleName(cleanName(a->getRoleName(role)));
+
+ if (!roleName.isEmpty()) {
+
+ // association doc
+ if (forceDoc() || !a->getDoc().isEmpty()) {
+ as << m_indentation << "/**" << m_endl
+ << formatDoc(a->getDoc(), m_indentation + " * ")
+ << m_indentation << " */" << m_endl;
+ }
+
+ // role doc
+ if (forceDoc() || !a->getRoleDoc(role).isEmpty()) {
+ as << m_indentation << "/**" << m_endl
+ << formatDoc(a->getRoleDoc(role), m_indentation + " * ")
+ << m_indentation << " */" << m_endl;
+ }
+
+ bool okCvt;
+ int nMulti = a->getMulti(role).toInt(&okCvt,10);
+ bool isNotMulti = a->getMulti(role).isEmpty() || (okCvt && nMulti == 1);
+
+ QString typeName(cleanName(a->getObject(role)->getName()));
+
+ if (isNotMulti)
+ as << m_indentation << "this.m_" << roleName << " = new " << typeName << "();" << m_endl;
+ else
+ as << m_indentation << "this.m_" << roleName << " = new Array();" << m_endl;
+
+ // role visibility
+ if (a->getVisibility(role) == Uml::Visibility::Private)
+ {
+ as << m_indentation << "ASSetPropFlags (this, \"m_" << roleName << "\", 7);" << m_endl;
+ }
+ else if (a->getVisibility(role)== Uml::Visibility::Protected)
+ {
+ as << m_indentation << "ASSetPropFlags (this, \"m_" << roleName << "\", 1);" << m_endl;
+ }
+ }
+ }
+}
+
+void ASWriter::writeOperations(QString classname, UMLOperationList *opList, QTextStream &as)
+{
+ UMLOperation *op;
+ UMLAttributeList atl;
+ UMLAttribute *at;
+
+ for(op = opList->first(); op; op = opList->next())
+ {
+ atl = op -> getParmList();
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+ for (at = atl.first(); at ; at = atl.next())
+ writeDoc |= !at->getDoc().isEmpty();
+
+ if( writeDoc ) //write method documentation
+ {
+ as << "/**" << m_endl << formatDoc(op->getDoc()," * ");
+
+ for (at = atl.first(); at; at = atl.next()) //write parameter documentation
+ {
+ if(forceDoc() || !at->getDoc().isEmpty())
+ {
+ as << " * @param " + cleanName(at->getName())<<m_endl;
+ as << formatDoc(at->getDoc()," * ");
+ }
+ }//end for : write parameter documentation
+ as << " */" << m_endl;
+ }//end if : write method documentation
+
+ as << classname << ".prototype." << cleanName(op->getName()) << " = function " << "(";
+
+ int i= atl.count();
+ int j=0;
+ for (at = atl.first(); at; at = atl.next(),j++)
+ {
+ as << cleanName(at->getName())
+ << (!(at->getInitialValue().isEmpty()) ? (QString(" = ")+at->getInitialValue()) : QString(""))
+ << ((j < i-1)?", ":"");
+ }
+ as << ")" << m_endl << "{" << m_endl <<
+ m_indentation << m_endl << "}" << m_endl;
+ as << m_endl << m_endl;
+ }//end for
+}
+
+/**
+ * returns "ActionScript"
+ */
+Uml::Programming_Language ASWriter::getLanguage() {
+ return Uml::pl_ActionScript;
+}
+
+const QStringList ASWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if ( keywords.isEmpty() ) {
+ keywords << "abs"
+ << "acos"
+ << "add"
+ << "addListener"
+ << "addProperty"
+ << "align"
+ << "_alpha"
+ << "and"
+ << "appendChild"
+ << "apply"
+ << "Array"
+ << "asin"
+ << "atan"
+ << "atan2"
+ << "attachMovie"
+ << "attachSound"
+ << "attributes"
+ << "autoSize"
+ << "background"
+ << "backgroundColor"
+ << "BACKSPACE"
+ << "beginFill"
+ << "beginGradientFill"
+ << "blockIndent"
+ << "bold"
+ << "Boolean"
+ << "border"
+ << "borderColor"
+ << "bottomScroll"
+ << "break"
+ << "bullet"
+ << "call"
+ << "callee"
+ << "caller"
+ << "capabilities"
+ << "CAPSLOCK"
+ << "case"
+ << "ceil"
+ << "charAt"
+ << "charCodeAt"
+ << "childNodes"
+ << "chr"
+ << "clear"
+ << "clearInterval"
+ << "cloneNode"
+ << "close"
+ << "color"
+ << "Color"
+ << "comment"
+ << "concat"
+ << "connect"
+ << "contentType"
+ << "continue"
+ << "CONTROL"
+ << "cos"
+ << "createElement"
+ << "createEmptyMovieClip"
+ << "createTextField"
+ << "createTextNode"
+ << "_currentframe"
+ << "curveTo"
+ << "Date"
+ << "default"
+ << "delete"
+ << "DELETEKEY"
+ << "do"
+ << "docTypeDecl"
+ << "DOWN"
+ << "_droptarget"
+ << "duplicateMovieClip"
+ << "duration"
+ << "E"
+ << "else"
+ << "embedFonts"
+ << "enabled"
+ << "END"
+ << "endFill"
+ << "endinitclip"
+ << "ENTER"
+ << "eq"
+ << "escape"
+ << "ESCAPE"
+ << "eval"
+ << "evaluate"
+ << "exp"
+ << "false"
+ << "firstChild"
+ << "floor"
+ << "focusEnabled"
+ << "_focusrect"
+ << "font"
+ << "for"
+ << "_framesloaded"
+ << "fromCharCode"
+ << "fscommand"
+ << "function"
+ << "ge"
+ << "get"
+ << "getAscii"
+ << "getBeginIndex"
+ << "getBounds"
+ << "getBytesLoaded"
+ << "getBytesTotal"
+ << "getCaretIndex"
+ << "getCode"
+ << "getDate"
+ << "getDay"
+ << "getDepth"
+ << "getEndIndex"
+ << "getFocus"
+ << "getFontList"
+ << "getFullYear"
+ << "getHours"
+ << "getMilliseconds"
+ << "getMinutes"
+ << "getMonth"
+ << "getNewTextFormat"
+ << "getPan"
+ << "getProperty"
+ << "getRGB"
+ << "getSeconds"
+ << "getTextExtent"
+ << "getTextFormat"
+ << "getTime"
+ << "getTimer"
+ << "getTimezoneOffset"
+ << "getTransform"
+ << "getURL"
+ << "getUTCDate"
+ << "getUTCDay"
+ << "getUTCFullYear"
+ << "getUTCHours"
+ << "getUTCMilliseconds"
+ << "getUTCMinutes"
+ << "getUTCMonth"
+ << "getUTCSeconds"
+ << "getVersion"
+ << "getVolume"
+ << "getYear"
+ << "_global"
+ << "globalToLocal"
+ << "goto"
+ << "gotoAndPlay"
+ << "gotoAndStop"
+ << "gt"
+ << "hasAccessibility"
+ << "hasAudio"
+ << "hasAudioEncoder"
+ << "hasChildNodes"
+ << "hasMP3"
+ << "hasVideoEncoder"
+ << "height"
+ << "_height"
+ << "hide"
+ << "_highquality"
+ << "hitArea"
+ << "hitTest"
+ << "HOME"
+ << "hscroll"
+ << "html"
+ << "htmlText"
+ << "if"
+ << "ifFrameLoaded"
+ << "ignoreWhite"
+ << "in"
+ << "include"
+ << "indent"
+ << "indexOf"
+ << "initclip"
+ << "INSERT"
+ << "insertBefore"
+ << "install"
+ << "instanceof"
+ << "int"
+ << "isActive"
+ << "isDown"
+ << "isFinite"
+ << "isNaN"
+ << "isToggled"
+ << "italic"
+ << "join"
+ << "lastChild"
+ << "lastIndexOf"
+ << "le"
+ << "leading"
+ << "LEFT"
+ << "leftMargin"
+ << "length"
+ << "_level"
+ << "lineStyle"
+ << "lineTo"
+ << "list"
+ << "LN10"
+ << "LN2"
+ << "load"
+ << "loaded"
+ << "loadMovie"
+ << "loadMovieNum"
+ << "loadSound"
+ << "loadVariables"
+ << "loadVariablesNum"
+ << "LoadVars"
+ << "localToGlobal"
+ << "log"
+ << "LOG10E"
+ << "LOG2E"
+ << "max"
+ << "maxChars"
+ << "maxhscroll"
+ << "maxscroll"
+ << "MAX_VALUE"
+ << "mbchr"
+ << "mblength"
+ << "mbord"
+ << "mbsubstring"
+ << "method"
+ << "min"
+ << "MIN_VALUE"
+ << "moveTo"
+ << "multiline"
+ << "_name"
+ << "NaN"
+ << "ne"
+ << "NEGATIVE_INFINITY"
+ << "new"
+ << "newline"
+ << "nextFrame"
+ << "nextScene"
+ << "nextSibling"
+ << "nodeName"
+ << "nodeType"
+ << "nodeValue"
+ << "not"
+ << "null"
+ << "Number"
+ << "Object"
+ << "on"
+ << "onChanged"
+ << "onClipEvent"
+ << "onClose"
+ << "onConnect"
+ << "onData"
+ << "onDragOut"
+ << "onDragOver"
+ << "onEnterFrame"
+ << "onKeyDown"
+ << "onKeyUp"
+ << "onKillFocus"
+ << "onLoad"
+ << "onMouseDown"
+ << "onMouseMove"
+ << "onMouseUp"
+ << "onPress"
+ << "onRelease"
+ << "onReleaseOutside"
+ << "onResize"
+ << "onRollOut"
+ << "onRollOver"
+ << "onScroller"
+ << "onSetFocus"
+ << "onSoundComplete"
+ << "onUnload"
+ << "onUpdate"
+ << "onXML"
+ << "or"
+ << "ord"
+ << "_parent"
+ << "parentNode"
+ << "parseFloat"
+ << "parseInt"
+ << "parseXML"
+ << "password"
+ << "PGDN"
+ << "PGUP"
+ << "PI"
+ << "pixelAspectRatio"
+ << "play"
+ << "pop"
+ << "position"
+ << "POSITIVE_INFINITY"
+ << "pow"
+ << "prevFrame"
+ << "previousSibling"
+ << "prevScene"
+ << "print"
+ << "printAsBitmap"
+ << "printAsBitmapNum"
+ << "printNum"
+ << "__proto__"
+ << "prototype"
+ << "push"
+ << "_quality"
+ << "random"
+ << "registerClass"
+ << "removeListener"
+ << "removeMovieClip"
+ << "removeNode"
+ << "removeTextField"
+ << "replaceSel"
+ << "restrict"
+ << "return"
+ << "reverse"
+ << "RIGHT"
+ << "rightMargin"
+ << "_root"
+ << "_rotation"
+ << "round"
+ << "scaleMode"
+ << "screenColor"
+ << "screenDPI"
+ << "screenResolutionX"
+ << "screenResolutionY"
+ << "scroll"
+ << "selectable"
+ << "send"
+ << "sendAndLoad"
+ << "set"
+ << "setDate"
+ << "setFocus"
+ << "setFullYear"
+ << "setHours"
+ << "setInterval"
+ << "setMask"
+ << "setMilliseconds"
+ << "setMinutes"
+ << "setMonth"
+ << "setNewTextFormat"
+ << "setPan"
+ << "setProperty"
+ << "setRGB"
+ << "setSeconds"
+ << "setSelection"
+ << "setTextFormat"
+ << "setTime"
+ << "setTransform"
+ << "setUTCDate"
+ << "setUTCFullYear"
+ << "setUTCHours"
+ << "setUTCMilliseconds"
+ << "setUTCMinutes"
+ << "setUTCMonth"
+ << "setUTCSeconds"
+ << "setVolume"
+ << "setYear"
+ << "shift"
+ << "SHIFT"
+ << "show"
+ << "showMenu"
+ << "sin"
+ << "size"
+ << "slice"
+ << "sort"
+ << "sortOn"
+ << "Sound"
+ << "_soundbuftime"
+ << "SPACE"
+ << "splice"
+ << "split"
+ << "sqrt"
+ << "SQRT1_2"
+ << "SQRT2"
+ << "start"
+ << "startDrag"
+ << "status"
+ << "stop"
+ << "stopAllSounds"
+ << "stopDrag"
+ << "String"
+ << "substr"
+ << "substring"
+ << "super"
+ << "swapDepths"
+ << "switch"
+ << "TAB"
+ << "tabChildren"
+ << "tabEnabled"
+ << "tabIndex"
+ << "tabStops"
+ << "tan"
+ << "target"
+ << "_target"
+ << "targetPath"
+ << "tellTarget"
+ << "text"
+ << "textColor"
+ << "TextFormat"
+ << "textHeight"
+ << "textWidth"
+ << "this"
+ << "toggleHighQuality"
+ << "toLowerCase"
+ << "toString"
+ << "_totalframes"
+ << "toUpperCase"
+ << "trace"
+ << "trackAsMenu"
+ << "true"
+ << "type"
+ << "typeof"
+ << "undefined"
+ << "underline"
+ << "unescape"
+ << "uninstall"
+ << "unloadMovie"
+ << "unloadMovieNum"
+ << "unshift"
+ << "unwatch"
+ << "UP"
+ << "updateAfterEvent"
+ << "url"
+ << "_url"
+ << "useHandCursor"
+ << "UTC"
+ << "valueOf"
+ << "var"
+ << "variable"
+ << "_visible"
+ << "void"
+ << "watch"
+ << "while"
+ << "width"
+ << "_width"
+ << "with"
+ << "wordWrap"
+ << "_x"
+ << "XML"
+ << "xmlDecl"
+ << "XMLSocket"
+ << "_xmouse"
+ << "_xscale"
+ << "_y"
+ << "_ymouse";
+ }
+
+ return keywords;
+}
+
+#include "aswriter.moc"
diff --git a/umbrello/umbrello/codegenerators/aswriter.h b/umbrello/umbrello/codegenerators/aswriter.h
new file mode 100644
index 00000000..51a4a922
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/aswriter.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ aswriter.h - description
+ -------------------
+ begin : Sat Feb 08 2003
+ copyright : (C) 2003 by Alexander Blum
+ email : blum@kewbee.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef ASWRITER_H
+#define ASWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umloperationlist.h"
+#include "../umlassociationlist.h"
+
+/**
+ * class ASWriter is a ActionScript code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class ASWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ ASWriter();
+ virtual ~ASWriter();
+
+ /**
+ * call this method to generate Actionscript code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "ActionScript"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+
+private:
+
+ /**
+ * we do not want to write the comment "Private methods" twice
+ */
+ bool bPrivateSectionCommentIsWritten;
+
+ /**
+ * write a list of class operations
+ *
+ * @param classname the name of the class
+ * @param opList the list of operations
+ * @param as output stream for the AS file
+ */
+ void writeOperations(QString classname, UMLOperationList *opList, QTextStream &as);
+
+ /**
+ * write a list of associations
+ *
+ * @param classname the name of the class
+ * @param assocList the list of associations
+ * @param as output stream for the AS file
+ */
+ void writeAssociation(QString& classname, UMLAssociationList& assoclist , QTextStream &as);
+
+};
+
+#endif //ASWRITER
diff --git a/umbrello/umbrello/codegenerators/classifierinfo.cpp b/umbrello/umbrello/codegenerators/classifierinfo.cpp
new file mode 100644
index 00000000..690238cf
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/classifierinfo.cpp
@@ -0,0 +1,140 @@
+/***************************************************************************
+ * *
+ * 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) 2003 Brian Thomas brian.thomas@gsfc.nasa.gov *
+ * (C) 2004-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+
+#include "classifierinfo.h"
+
+#include "../classifier.h"
+#include "../operation.h"
+
+ClassifierInfo::ClassifierInfo( UMLClassifier *classifier)
+{
+ classifier_ = classifier;
+
+ // set default class, file names
+ className = classifier->getName();
+ fileName = classifier->getName().lower();
+
+ // determine up-front what we are dealing with
+ isInterface = classifier->isInterface();
+
+ // sort attributes by Scope
+ if(!isInterface) {
+ UMLAttributeList atl = classifier->getAttributeList();
+ for(UMLAttribute *at=atl.first(); at ; at=atl.next()) {
+ switch(at->getVisibility())
+ {
+ case Uml::Visibility::Public:
+ if(at->getStatic())
+ static_atpub.append(at);
+ else
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ if(at->getStatic())
+ static_atprot.append(at);
+ else
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ case Uml::Visibility::Implementation:
+ if(at->getStatic())
+ static_atpriv.append(at);
+ else
+ atpriv.append(at);
+ break;
+ }
+ }
+ }
+
+ // inheritance issues
+ superclasses = classifier->getSuperClasses(); // list of what we inherit from
+
+ subclasses = classifier->getSubClasses(); // list of what inherits from us
+
+ // another preparation, determine what we have
+ plainAssociations = classifier->getSpecificAssocs(Uml::at_Association); // BAD! only way to get "general" associations.
+
+ uniAssociations = classifier->getUniAssociationToBeImplemented();
+
+ aggregations = classifier->getAggregations();
+
+ compositions = classifier->getCompositions();
+
+ // set some summary information about the classifier now
+ hasAssociations = plainAssociations.count() > 0 || aggregations.count() > 0 || compositions.count() > 0 || uniAssociations.count() > 0;
+ hasAttributes = atpub.count() > 0 || atprot.count() > 0 || atpriv.count() > 0
+ || static_atpub.count() > 0
+ || static_atprot.count() > 0
+ || static_atpriv.count() > 0;
+
+ hasStaticAttributes = static_atpub.count() > 0
+ || static_atprot.count() > 0
+ || static_atpriv.count() > 0;
+
+ hasAccessorMethods = hasAttributes || hasAssociations;
+
+ hasOperationMethods = classifier->getOpList().last() ? true : false;
+
+ hasMethods = hasOperationMethods || hasAccessorMethods;
+
+ // this is a bit too simplistic..some associations are for
+ // SINGLE objects, and WONT be declared as Vectors, so this
+ // is a bit overly inclusive (I guess that's better than the other way around)
+ hasVectorFields = hasAssociations ? true : false;
+}
+
+ClassifierInfo::~ClassifierInfo() { }
+
+UMLClassifierList ClassifierInfo::getPlainAssocChildClassifierList()
+{
+ return findAssocClassifierObjsInRoles(&plainAssociations);
+}
+
+UMLClassifierList ClassifierInfo::getAggregateChildClassifierList()
+{
+ return findAssocClassifierObjsInRoles(&aggregations);
+}
+
+UMLClassifierList ClassifierInfo::getCompositionChildClassifierList()
+{
+ return findAssocClassifierObjsInRoles(&compositions);
+}
+
+UMLClassifierList ClassifierInfo::findAssocClassifierObjsInRoles (UMLAssociationList * list)
+{
+ UMLClassifierList classifiers;
+
+ for (UMLAssociation *a = list->first(); a; a = list->next()) {
+ // DONT accept a classifier IF the association role is empty, by
+ // convention, that means to ignore the classifier on that end of
+ // the association.
+ // We also ignore classifiers which are the same as the current one
+ // (e.g. id matches), we only want the "other" classifiers
+ if (a->getObjectId(Uml::A) == classifier_->getID() && !a->getRoleName(Uml::B).isEmpty()) {
+ UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::B));
+ if(c)
+ classifiers.append(c);
+ } else if (a->getObjectId(Uml::B) == classifier_->getID() && !a->getRoleName(Uml::A).isEmpty()) {
+ UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::A));
+ if(c)
+ classifiers.append(c);
+ }
+ }
+
+ return classifiers;
+}
+
+UMLAttributeList ClassifierInfo::getAttList()
+{
+ return classifier_->getAttributeList();
+}
+
diff --git a/umbrello/umbrello/codegenerators/classifierinfo.h b/umbrello/umbrello/codegenerators/classifierinfo.h
new file mode 100644
index 00000000..53b7c02b
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/classifierinfo.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * *
+ * 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) 2003 Brian Thomas <brian.thomas@gsfc.nasa.gov> *
+ * copyright (C) 2004-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef CLASSIFIERINFO_H
+#define CLASSIFIERINFO_H
+
+#include "../umldoc.h"
+#include "../attribute.h"
+#include "../association.h"
+#include "../umlclassifierlist.h"
+#include "../umlassociationlist.h"
+#include "../umlattributelist.h"
+
+#include <qstring.h>
+
+
+class UMLClassifier;
+
+
+/**
+ * class ClassInfo is an object to hold summary information about a classifier
+ * in a convenient form for easy access by a code generator.
+ */
+class ClassifierInfo {
+public:
+
+ /**
+ * Constructor, initialises a couple of variables
+ */
+ ClassifierInfo (UMLClassifier * classifier);
+
+ /**
+ * Destructor, empty
+ */
+ virtual ~ClassifierInfo();
+
+ // Fields
+ //
+
+ /**
+ * Lists of attributes of this classifier (if a class)
+ * Sorted by scope.
+ */
+ UMLAttributeList atpub;
+ UMLAttributeList atprot;
+ UMLAttributeList atpriv;
+
+ /**
+ * Lists of static attributes of this classifier (if a class)
+ */
+ UMLAttributeList static_atpub;
+ UMLAttributeList static_atprot;
+ UMLAttributeList static_atpriv;
+
+ /**
+ * Lists of types of associations this classifier has
+ */
+ UMLAssociationList plainAssociations;
+ UMLAssociationList uniAssociations;
+ UMLAssociationList aggregations;
+ UMLAssociationList compositions;
+
+ /**
+ * what sub and super classifiers are related to this class
+ */
+ UMLClassifierList superclasses;
+ UMLClassifierList subclasses;
+
+ /**
+ * Various conditional information about our classifier.
+ */
+ bool isInterface; // Whether or not this classifier is an interface.
+ bool hasAssociations;
+ bool hasAttributes;
+ bool hasStaticAttributes;
+ bool hasMethods;
+ bool hasAccessorMethods;
+ bool hasOperationMethods;
+ bool hasVectorFields;
+
+ /**
+ * Class and File names
+ */
+ QString className;
+ QString fileName;
+
+ /**
+ * utility functions to allow easy determination of what classifiers
+ * are "owned" by the current one via named association type (e.g.
+ * plain, aggregate or compositions).
+ */
+ UMLClassifierList getPlainAssocChildClassifierList();
+ UMLClassifierList getAggregateChildClassifierList();
+ UMLClassifierList getCompositionChildClassifierList();
+
+ /**
+ * Utility method to obtain list of attributes, if they exist, for
+ * the current classfier.
+ */
+ UMLAttributeList getAttList();
+
+private:
+
+ UMLClassifier* classifier_;
+
+ /**
+ * Utility method called by "get*ChildClassfierList()" methods. It basically
+ * finds all the classifiers named in each association in the given association list
+ * which arent the current one. Usefull for finding which classifiers are "owned" by the
+ * current one via declared associations such as in aggregations/compositions.
+ */
+ UMLClassifierList findAssocClassifierObjsInRoles (UMLAssociationList * list);
+
+};
+
+#endif // CLASSIFIERINFO_H
+
diff --git a/umbrello/umbrello/codegenerators/codegen_utils.cpp b/umbrello/umbrello/codegenerators/codegen_utils.cpp
new file mode 100644
index 00000000..cb94cdde
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/codegen_utils.cpp
@@ -0,0 +1,413 @@
+/***************************************************************************
+ * *
+ * 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> *
+ ***************************************************************************/
+
+// own header
+#include "codegen_utils.h"
+// app includes
+#include "../uml.h"
+#include "../umldoc.h"
+
+namespace Codegen_Utils {
+
+QStringList cppDatatypes() {
+ QStringList l;
+ l.append("int");
+ l.append("char");
+ l.append("bool");
+ l.append("float");
+ l.append("double");
+ l.append("short");
+ l.append("long");
+ l.append("unsigned int");
+ l.append("unsigned short");
+ l.append("unsigned long");
+ l.append("string");
+ return l;
+}
+
+const QStringList reservedCppKeywords() {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords.append( "and" );
+ keywords.append( "and_eq" );
+ keywords.append( "__asm__" );
+ keywords.append( "asm" );
+ keywords.append( "__attribute__" );
+ keywords.append( "auto" );
+ keywords.append( "bitand" );
+ keywords.append( "bitor" );
+ keywords.append( "bool" );
+ keywords.append( "break" );
+ keywords.append( "BUFSIZ" );
+ keywords.append( "case" );
+ keywords.append( "catch" );
+ keywords.append( "char" );
+ keywords.append( "CHAR_BIT" );
+ keywords.append( "CHAR_MAX" );
+ keywords.append( "CHAR_MIN" );
+ keywords.append( "class" );
+ keywords.append( "CLOCKS_PER_SEC" );
+ keywords.append( "clock_t" );
+ keywords.append( "compl" );
+ keywords.append( "__complex__" );
+ keywords.append( "complex" );
+ keywords.append( "const" );
+ keywords.append( "const_cast" );
+ keywords.append( "continue" );
+ keywords.append( "__DATE__" );
+ keywords.append( "DBL_DIG" );
+ keywords.append( "DBL_EPSILON" );
+ keywords.append( "DBL_MANT_DIG" );
+ keywords.append( "DBL_MAX" );
+ keywords.append( "DBL_MAX_10_EXP" );
+ keywords.append( "DBL_MAX_EXP" );
+ keywords.append( "DBL_MIN" );
+ keywords.append( "DBL_MIN_10_EXP" );
+ keywords.append( "DBL_MIN_EXP" );
+ keywords.append( "default" );
+ keywords.append( "delete" );
+ keywords.append( "DIR" );
+ keywords.append( "div_t" );
+ keywords.append( "do" );
+ keywords.append( "double" );
+ keywords.append( "dynamic_cast" );
+ keywords.append( "E2BIG" );
+ keywords.append( "EACCES" );
+ keywords.append( "EAGAIN" );
+ keywords.append( "EBADF" );
+ keywords.append( "EBADMSG" );
+ keywords.append( "EBUSY" );
+ keywords.append( "ECANCELED" );
+ keywords.append( "ECHILD" );
+ keywords.append( "EDEADLK" );
+ keywords.append( "EDOM" );
+ keywords.append( "EEXIST" );
+ keywords.append( "EFAULT" );
+ keywords.append( "EFBIG" );
+ keywords.append( "EILSEQ" );
+ keywords.append( "EINPROGRESS" );
+ keywords.append( "EINTR" );
+ keywords.append( "EINVAL" );
+ keywords.append( "EIO" );
+ keywords.append( "EISDIR" );
+ keywords.append( "else" );
+ keywords.append( "EMFILE" );
+ keywords.append( "EMLINK" );
+ keywords.append( "EMSGSIZE" );
+ keywords.append( "ENAMETOOLONG" );
+ keywords.append( "ENFILE" );
+ keywords.append( "ENODEV" );
+ keywords.append( "ENOENT" );
+ keywords.append( "ENOEXEC" );
+ keywords.append( "ENOLCK" );
+ keywords.append( "ENOMEM" );
+ keywords.append( "ENOSPC" );
+ keywords.append( "ENOSYS" );
+ keywords.append( "ENOTDIR" );
+ keywords.append( "ENOTEMPTY" );
+ keywords.append( "ENOTSUP" );
+ keywords.append( "ENOTTY" );
+ keywords.append( "enum" );
+ keywords.append( "ENXIO" );
+ keywords.append( "EOF" );
+ keywords.append( "EPERM" );
+ keywords.append( "EPIPE" );
+ keywords.append( "ERANGE" );
+ keywords.append( "EROFS" );
+ keywords.append( "ESPIPE" );
+ keywords.append( "ESRCH" );
+ keywords.append( "ETIMEDOUT" );
+ keywords.append( "EXDEV" );
+ keywords.append( "EXIT_FAILURE" );
+ keywords.append( "EXIT_SUCCESS" );
+ keywords.append( "explicit" );
+ keywords.append( "export" );
+ keywords.append( "extern" );
+ keywords.append( "false" );
+ keywords.append( "__FILE__" );
+ keywords.append( "FILE" );
+ keywords.append( "FILENAME_MAX" );
+ keywords.append( "float" );
+ keywords.append( "FLT_DIG" );
+ keywords.append( "FLT_EPSILON" );
+ keywords.append( "FLT_MANT_DIG" );
+ keywords.append( "FLT_MAX" );
+ keywords.append( "FLT_MAX_10_EXP" );
+ keywords.append( "FLT_MAX_EXP" );
+ keywords.append( "FLT_MIN" );
+ keywords.append( "FLT_MIN_10_EXP" );
+ keywords.append( "FLT_MIN_EXP" );
+ keywords.append( "FLT_RADIX" );
+ keywords.append( "FLT_ROUNDS" );
+ keywords.append( "FOPEN_MAX" );
+ keywords.append( "for" );
+ keywords.append( "fpos_t" );
+ keywords.append( "friend" );
+ keywords.append( "__FUNCTION__" );
+ keywords.append( "__GNUC__" );
+ keywords.append( "goto" );
+ keywords.append( "HUGE_VAL" );
+ keywords.append( "if" );
+ keywords.append( "__imag__" );
+ keywords.append( "inline" );
+ keywords.append( "int" );
+ keywords.append( "INT16_MAX" );
+ keywords.append( "INT16_MIN" );
+ keywords.append( "int16_t" );
+ keywords.append( "INT32_MAX" );
+ keywords.append( "INT32_MIN" );
+ keywords.append( "int32_t" );
+ keywords.append( "INT64_MAX" );
+ keywords.append( "INT64_MIN" );
+ keywords.append( "int64_t" );
+ keywords.append( "INT8_MAX" );
+ keywords.append( "INT8_MIN" );
+ keywords.append( "int8_t" );
+ keywords.append( "INT_FAST16_MAX" );
+ keywords.append( "INT_FAST16_MIN" );
+ keywords.append( "int_fast16_t" );
+ keywords.append( "INT_FAST32_MAX" );
+ keywords.append( "INT_FAST32_MIN" );
+ keywords.append( "int_fast32_t" );
+ keywords.append( "INT_FAST64_MAX" );
+ keywords.append( "INT_FAST64_MIN" );
+ keywords.append( "int_fast64_t" );
+ keywords.append( "INT_FAST8_MAX" );
+ keywords.append( "INT_FAST8_MIN" );
+ keywords.append( "int_fast8_t" );
+ keywords.append( "INT_LEAST16_MAX" );
+ keywords.append( "INT_LEAST16_MIN" );
+ keywords.append( "int_least16_t" );
+ keywords.append( "INT_LEAST32_MAX" );
+ keywords.append( "INT_LEAST32_MIN" );
+ keywords.append( "int_least32_t" );
+ keywords.append( "INT_LEAST64_MAX" );
+ keywords.append( "INT_LEAST64_MIN" );
+ keywords.append( "int_least64_t" );
+ keywords.append( "INT_LEAST8_MAX" );
+ keywords.append( "INT_LEAST8_MIN" );
+ keywords.append( "int_least8_t" );
+ keywords.append( "INT_MAX" );
+ keywords.append( "INTMAX_MAX" );
+ keywords.append( "INTMAX_MIN" );
+ keywords.append( "intmax_t" );
+ keywords.append( "INT_MIN" );
+ keywords.append( "INTPTR_MAX" );
+ keywords.append( "INTPTR_MIN" );
+ keywords.append( "intptr_t" );
+ keywords.append( "_IOFBF" );
+ keywords.append( "_IOLBF" );
+ keywords.append( "_IONBF" );
+ keywords.append( "jmp_buf" );
+ keywords.append( "__label__" );
+ keywords.append( "LC_ALL" );
+ keywords.append( "LC_COLLATE" );
+ keywords.append( "LC_CTYPE" );
+ keywords.append( "LC_MONETARY" );
+ keywords.append( "LC_NUMERIC" );
+ keywords.append( "LC_TIME" );
+ keywords.append( "LDBL_DIG" );
+ keywords.append( "LDBL_EPSILON" );
+ keywords.append( "LDBL_MANT_DIG" );
+ keywords.append( "LDBL_MAX" );
+ keywords.append( "LDBL_MAX_10_EXP" );
+ keywords.append( "LDBL_MAX_EXP" );
+ keywords.append( "LDBL_MIN" );
+ keywords.append( "LDBL_MIN_10_EXP" );
+ keywords.append( "LDBL_MIN_EXP" );
+ keywords.append( "ldiv_t" );
+ keywords.append( "__LINE__" );
+ keywords.append( "LLONG_MAX" );
+ keywords.append( "long" );
+ keywords.append( "LONG_MAX" );
+ keywords.append( "LONG_MIN" );
+ keywords.append( "L_tmpnam" );
+ keywords.append( "M_1_PI" );
+ keywords.append( "M_2_PI" );
+ keywords.append( "M_2_SQRTPI" );
+ keywords.append( "MB_CUR_MAX" );
+ keywords.append( "MB_LEN_MAX" );
+ keywords.append( "mbstate_t" );
+ keywords.append( "M_E" );
+ keywords.append( "M_LN10" );
+ keywords.append( "M_LN2" );
+ keywords.append( "M_LOG10E" );
+ keywords.append( "M_LOG2E" );
+ keywords.append( "M_PI" );
+ keywords.append( "M_PI_2" );
+ keywords.append( "M_PI_4" );
+ keywords.append( "M_SQRT1_2" );
+ keywords.append( "M_SQRT2" );
+ keywords.append( "mutable" );
+ keywords.append( "namespace" );
+ keywords.append( "new" );
+ keywords.append( "not" );
+ keywords.append( "not_eq" );
+ keywords.append( "NPOS" );
+ keywords.append( "NULL" );
+ keywords.append( "operator" );
+ keywords.append( "or" );
+ keywords.append( "or_eq" );
+ keywords.append( "__PRETTY_FUNCTION__" );
+ keywords.append( "private" );
+ keywords.append( "protected" );
+ keywords.append( "PTRDIFF_MAX" );
+ keywords.append( "PTRDIFF_MIN" );
+ keywords.append( "ptrdiff_t" );
+ keywords.append( "public" );
+ keywords.append( "RAND_MAX" );
+ keywords.append( "__real__" );
+ keywords.append( "register" );
+ keywords.append( "reinterpret_cast" );
+ keywords.append( "restrict" );
+ keywords.append( "return" );
+ keywords.append( "SCHAR_MAX" );
+ keywords.append( "SCHAR_MIN" );
+ keywords.append( "SEEK_CUR" );
+ keywords.append( "SEEK_END" );
+ keywords.append( "SEEK_SET" );
+ keywords.append( "short" );
+ keywords.append( "SHRT_MAX" );
+ keywords.append( "SHRT_MIN" );
+ keywords.append( "SIGABRT" );
+ keywords.append( "SIGALRM" );
+ keywords.append( "SIG_ATOMIC_MAX" );
+ keywords.append( "SIG_ATOMIC_MIN" );
+ keywords.append( "sig_atomic_t" );
+ keywords.append( "SIGCHLD" );
+ keywords.append( "SIGCONT" );
+ keywords.append( "SIG_DFL" );
+ keywords.append( "SIG_ERR" );
+ keywords.append( "SIGFPE" );
+ keywords.append( "SIGHUP" );
+ keywords.append( "SIG_IGN" );
+ keywords.append( "SIGILL" );
+ keywords.append( "SIGINT" );
+ keywords.append( "SIGKILL" );
+ keywords.append( "signed" );
+ keywords.append( "SIGPIPE" );
+ keywords.append( "SIGQUIT" );
+ keywords.append( "SIGSEGV" );
+ keywords.append( "SIGSTOP" );
+ keywords.append( "SIGTERM" );
+ keywords.append( "SIGTRAP" );
+ keywords.append( "SIGTSTP" );
+ keywords.append( "SIGTTIN" );
+ keywords.append( "SIGTTOU" );
+ keywords.append( "SIGUSR1" );
+ keywords.append( "SIGUSR2" );
+ keywords.append( "SINT_MAX" );
+ keywords.append( "SINT_MIN" );
+ keywords.append( "SIZE_MAX" );
+ keywords.append( "sizeof" );
+ keywords.append( "size_t" );
+ keywords.append( "SLONG_MAX" );
+ keywords.append( "SLONG_MIN" );
+ keywords.append( "SSHRT_MAX" );
+ keywords.append( "SSHRT_MIN" );
+ keywords.append( "ssize_t" );
+ keywords.append( "static" );
+ keywords.append( "static_cast" );
+ keywords.append( "__STDC__" );
+ keywords.append( "__STDC_VERSION__" );
+ keywords.append( "stderr" );
+ keywords.append( "stdin" );
+ keywords.append( "stdout" );
+ keywords.append( "struct" );
+ keywords.append( "switch" );
+ keywords.append( "template" );
+ keywords.append( "this" );
+ keywords.append( "throw" );
+ keywords.append( "__TIME__" );
+ keywords.append( "time_t" );
+ keywords.append( "TMP_MAX" );
+ keywords.append( "true" );
+ keywords.append( "try" );
+ keywords.append( "typedef" );
+ keywords.append( "typeid" );
+ keywords.append( "typename" );
+ keywords.append( "typeof" );
+ keywords.append( "UCHAR_MAX" );
+ keywords.append( "UINT16_MAX" );
+ keywords.append( "uint16_t" );
+ keywords.append( "UINT32_MAX" );
+ keywords.append( "uint32_t" );
+ keywords.append( "UINT64_MAX" );
+ keywords.append( "uint64_t" );
+ keywords.append( "UINT8_MAX" );
+ keywords.append( "uint8_t" );
+ keywords.append( "UINT_FAST16_MAX" );
+ keywords.append( "uint_fast16_t" );
+ keywords.append( "UINT_FAST32_MAX" );
+ keywords.append( "uint_fast32_t" );
+ keywords.append( "UINT_FAST64_MAX" );
+ keywords.append( "uint_fast64_t" );
+ keywords.append( "UINT_FAST8_MAX" );
+ keywords.append( "uint_fast8_t" );
+ keywords.append( "UINT_LEAST16_MAX" );
+ keywords.append( "uint_least16_t" );
+ keywords.append( "UINT_LEAST32_MAX" );
+ keywords.append( "uint_least32_t" );
+ keywords.append( "UINT_LEAST64_MAX" );
+ keywords.append( "uint_least64_t" );
+ keywords.append( "UINT_LEAST8_MAX" );
+ keywords.append( "uint_least8_t" );
+ keywords.append( "UINT_MAX" );
+ keywords.append( "UINTMAX_MAX" );
+ keywords.append( "uintmax_t" );
+ keywords.append( "UINTPTR_MAX" );
+ keywords.append( "uintptr_t" );
+ keywords.append( "ULLONG_MAX" );
+ keywords.append( "ULONG_MAX" );
+ keywords.append( "union" );
+ keywords.append( "unsigned" );
+ keywords.append( "USHRT_MAX" );
+ keywords.append( "using" );
+ keywords.append( "va_list" );
+ keywords.append( "virtual" );
+ keywords.append( "void" );
+ keywords.append( "__volatile__" );
+ keywords.append( "volatile" );
+ keywords.append( "WCHAR_MAX" );
+ keywords.append( "WCHAR_MIN" );
+ keywords.append( "wchar_t" );
+ keywords.append( "wctrans_t" );
+ keywords.append( "wctype_t" );
+ keywords.append( "WEOF" );
+ keywords.append( "while" );
+ keywords.append( "WINT_MAX" );
+ keywords.append( "WINT_MIN" );
+ keywords.append( "wint_t" );
+ keywords.append( "xor" );
+ keywords.append( "xor_eq" );
+ }
+
+ return keywords;
+}
+
+void createCppStereotypes() {
+ UMLDoc *umldoc = UMLApp::app()->getDocument();
+ umldoc->findOrCreateStereotype("constructor");
+ // declares an operation as friend
+ umldoc->findOrCreateStereotype("friend");
+ // to use in methods that aren't abstract
+ umldoc->findOrCreateStereotype("virtual");
+}
+
+QString capitalizeFirstLetter(const QString &string) {
+ QChar firstChar = string.at(0);
+ return firstChar.upper() + string.mid(1);
+}
+
+} // end namespace Codegen_Utils
+
diff --git a/umbrello/umbrello/codegenerators/codegen_utils.h b/umbrello/umbrello/codegenerators/codegen_utils.h
new file mode 100644
index 00000000..aaa7d117
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/codegen_utils.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * *
+ * 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> *
+ ***************************************************************************/
+
+#ifndef CODEGEN_UTILS_H
+#define CODEGEN_UTILS_H
+
+#include <qstringlist.h>
+
+namespace Codegen_Utils {
+
+/**
+ * Return list of C++ datatypes
+ */
+QStringList cppDatatypes();
+
+/**
+ * Get list of C++ reserved keywords
+ */
+const QStringList reservedCppKeywords();
+
+/**
+ * Add C++ stereotypes
+ */
+void createCppStereotypes();
+
+/**
+ * Return the input string with the first letter capitalized.
+ */
+QString capitalizeFirstLetter(const QString &string);
+
+}
+
+#endif // CODEGEN_UTILS_H
+
diff --git a/umbrello/umbrello/codegenerators/codegenfactory.cpp b/umbrello/umbrello/codegenerators/codegenfactory.cpp
new file mode 100644
index 00000000..00401653
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/codegenfactory.cpp
@@ -0,0 +1,360 @@
+/***************************************************************************
+ begin : Mon Jun 17 2002
+ copyright : (C) 2002 Luis De la Parra Blum <luis@delaparra.org>
+ and Brian Thomas
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2003-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "codegenfactory.h"
+
+// qt/kde includes
+#include <kdebug.h>
+
+// app includes
+#include "../codegenerator.h"
+#include "../umldoc.h"
+#include "../uml.h"
+#include "../optionstate.h"
+#include "../operation.h"
+#include "../attribute.h"
+#include "../umlrole.h"
+
+#include "adawriter.h"
+#include "cppwriter.h"
+#include "csharpwriter.h"
+#include "dwriter.h"
+#include "idlwriter.h"
+#include "javawriter.h"
+#include "pascalwriter.h"
+#include "perlwriter.h"
+#include "phpwriter.h"
+#include "php5writer.h"
+#include "pythonwriter.h"
+#include "rubywriter.h"
+#include "sqlwriter.h"
+#include "aswriter.h"
+#include "jswriter.h"
+#include "tclwriter.h"
+#include "xmlschemawriter.h"
+
+// the new
+#include "cppcodegenerator.h"
+#include "javacodegenerator.h"
+#include "rubycodegenerator.h"
+
+#include "cppheadercodedocument.h"
+#include "cppsourcecodedocument.h"
+#include "javaclassifiercodedocument.h"
+#include "rubyclassifiercodedocument.h"
+#include "javaantcodedocument.h"
+
+#include "cppheadercodeoperation.h"
+#include "cppsourcecodeoperation.h"
+#include "javacodeoperation.h"
+#include "rubycodeoperation.h"
+
+#include "cppcodeclassfield.h"
+#include "javacodeclassfield.h"
+#include "rubycodeclassfield.h"
+
+#include "cppheadercodeaccessormethod.h"
+#include "cppsourcecodeaccessormethod.h"
+#include "javacodeaccessormethod.h"
+#include "rubycodeaccessormethod.h"
+
+#include "cppheadercodeclassfielddeclarationblock.h"
+#include "cppsourcecodeclassfielddeclarationblock.h"
+#include "javacodeclassfielddeclarationblock.h"
+#include "rubycodeclassfielddeclarationblock.h"
+
+#include "cppcodedocumentation.h"
+#include "javacodecomment.h"
+#include "rubycodecomment.h"
+#include "xmlcodecomment.h"
+
+#include "cppcodegenerationpolicy.h"
+#include "javacodegenerationpolicy.h"
+#include "rubycodegenerationpolicy.h"
+
+namespace CodeGenFactory {
+
+CodeGenerator* createObject(Uml::Programming_Language pl) {
+ CodeGenerator* obj = 0;
+ Settings::OptionState optionState = Settings::getOptionState();
+ UMLApp::app()->setPolicyExt(NULL);
+ switch (pl) {
+ case Uml::pl_Ada:
+ obj = new AdaWriter();
+ break;
+ case Uml::pl_ActionScript:
+ obj = new ASWriter();
+ break;
+ case Uml::pl_Cpp:
+ if (optionState.generalState.newcodegen) {
+ obj = new CPPCodeGenerator();
+ obj->connect_newcodegen_slots();
+ } else {
+ obj = new CppWriter();
+ }
+ {
+ CPPCodeGenerationPolicy *p =
+ new CPPCodeGenerationPolicy(UMLApp::app()->getConfig());
+ UMLApp::app()->setPolicyExt(p);
+ }
+ break;
+ case Uml::pl_CSharp:
+ obj = new CSharpWriter();
+ break;
+ case Uml::pl_D:
+ obj = new DWriter();
+ break;
+ case Uml::pl_IDL:
+ obj = new IDLWriter();
+ break;
+ case Uml::pl_Java:
+ if (optionState.generalState.newcodegen) {
+ obj = new JavaCodeGenerator();
+ obj->connect_newcodegen_slots();
+ JavaCodeGenerationPolicy *p =
+ new JavaCodeGenerationPolicy(UMLApp::app()->getConfig());
+ UMLApp::app()->setPolicyExt(p);
+ } else
+ obj = new JavaWriter();
+ break;
+ case Uml::pl_JavaScript:
+ obj = new JSWriter();
+ break;
+ case Uml::pl_PHP:
+ obj = new PhpWriter();
+ break;
+ case Uml::pl_PHP5:
+ obj = new Php5Writer();
+ break;
+ case Uml::pl_Pascal:
+ obj = new PascalWriter();
+ break;
+ case Uml::pl_Perl:
+ obj = new PerlWriter();
+ break;
+ case Uml::pl_Python:
+ obj = new PythonWriter();
+ break;
+ case Uml::pl_Ruby:
+ if (optionState.generalState.newcodegen) {
+ obj = new RubyCodeGenerator();
+ obj->connect_newcodegen_slots();
+ RubyCodeGenerationPolicy *p =
+ new RubyCodeGenerationPolicy(UMLApp::app()->getConfig());
+ UMLApp::app()->setPolicyExt(p);
+ } else
+ obj = new RubyWriter();
+ break;
+ case Uml::pl_SQL:
+ obj = new SQLWriter();
+ break;
+ case Uml::pl_Tcl:
+ obj = new TclWriter();
+ break;
+ case Uml::pl_XMLSchema:
+ obj = new XMLSchemaWriter();
+ break;
+ default:
+ kWarning() << "cannot create object of type " << pl
+ << ". Type unknown" << endl;
+ break;
+ }
+ if (obj)
+ obj->initFromParentDocument();
+ return obj;
+}
+
+CodeDocument * newClassifierCodeDocument (UMLClassifier * c)
+{
+ Settings::OptionState optionState = Settings::getOptionState();
+ if (!optionState.generalState.newcodegen)
+ return NULL;
+ ClassifierCodeDocument *retval = NULL;
+ switch (UMLApp::app()->getActiveLanguage()) {
+ case Uml::pl_Cpp:
+ retval = new CPPSourceCodeDocument(c);
+ break;
+ case Uml::pl_Java:
+ retval = new JavaClassifierCodeDocument(c);
+ break;
+ case Uml::pl_Ruby:
+ retval = new RubyClassifierCodeDocument(c);
+ break;
+ default:
+ break;
+ }
+ retval->initCodeClassFields();
+ retval->synchronize();
+ return retval;
+}
+
+CodeOperation *newCodeOperation(ClassifierCodeDocument *ccd, UMLOperation * op) {
+ CodeOperation *retval = NULL;
+ switch (UMLApp::app()->getActiveLanguage()) {
+ case Uml::pl_Cpp:
+ {
+ CPPHeaderCodeDocument *hcd = dynamic_cast<CPPHeaderCodeDocument*>(ccd);
+ if (hcd)
+ return new CPPHeaderCodeOperation(hcd, op);
+ CPPSourceCodeDocument *scd = dynamic_cast<CPPSourceCodeDocument*>(ccd);
+ if (scd)
+ return new CPPSourceCodeOperation(scd, op);
+ }
+ break;
+ case Uml::pl_Java:
+ retval = new JavaCodeOperation(dynamic_cast<JavaClassifierCodeDocument*>(ccd), op);
+ break;
+ case Uml::pl_Ruby:
+ retval = new RubyCodeOperation(dynamic_cast<RubyClassifierCodeDocument*>(ccd), op);
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+
+CodeClassField * newCodeClassField(ClassifierCodeDocument *ccd, UMLAttribute *at) {
+ CodeClassField *retval = NULL;
+ switch (UMLApp::app()->getActiveLanguage()) {
+ case Uml::pl_Cpp:
+ retval = new CPPCodeClassField(ccd, at);
+ break;
+ case Uml::pl_Java:
+ retval = new JavaCodeClassField(ccd, at);
+ break;
+ case Uml::pl_Ruby:
+ retval = new RubyCodeClassField(ccd, at);
+ break;
+ default:
+ break;
+ }
+ retval->finishInitialization();
+ return retval;
+}
+
+CodeClassField * newCodeClassField(ClassifierCodeDocument *ccd, UMLRole *role) {
+ CodeClassField *retval = NULL;
+ switch (UMLApp::app()->getActiveLanguage()) {
+ case Uml::pl_Cpp:
+ retval = new CPPCodeClassField(ccd, role);
+ break;
+ case Uml::pl_Java:
+ retval = new JavaCodeClassField(ccd, role);
+ break;
+ case Uml::pl_Ruby:
+ retval = new RubyCodeClassField(ccd, role);
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+CodeAccessorMethod * newCodeAccessorMethod(ClassifierCodeDocument *ccd,
+ CodeClassField *cf,
+ CodeAccessorMethod::AccessorType type) {
+ CodeAccessorMethod *retval = NULL;
+ switch (UMLApp::app()->getActiveLanguage()) {
+ case Uml::pl_Cpp:
+ {
+ CPPHeaderCodeDocument *hcd = dynamic_cast<CPPHeaderCodeDocument*>(ccd);
+ if (hcd) {
+ CPPHeaderCodeAccessorMethod *chcam = new CPPHeaderCodeAccessorMethod(cf, type);
+ chcam->update();
+ retval = chcam;
+ } else {
+ CPPSourceCodeAccessorMethod *cscam = new CPPSourceCodeAccessorMethod(cf, type);
+ cscam->update();
+ retval = cscam;
+ }
+ }
+ break;
+ case Uml::pl_Java:
+ {
+ JavaCodeAccessorMethod *jcam = new JavaCodeAccessorMethod(cf, type);
+ jcam->update();
+ retval = jcam;
+ retval->setOverallIndentationLevel(1);
+ }
+ break;
+ case Uml::pl_Ruby:
+ {
+ RubyCodeAccessorMethod *rcam = new RubyCodeAccessorMethod(cf, type);
+ rcam->update();
+ retval = rcam;
+ retval->setOverallIndentationLevel(1);
+ }
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+CodeClassFieldDeclarationBlock * newDeclarationCodeBlock (ClassifierCodeDocument *cd,
+ CodeClassField * cf) {
+ CodeClassFieldDeclarationBlock *retval = NULL;
+ switch (UMLApp::app()->getActiveLanguage()) {
+ case Uml::pl_Cpp:
+ {
+ CPPHeaderCodeDocument *hcd = dynamic_cast<CPPHeaderCodeDocument*>(cd);
+ if (hcd)
+ return new CPPHeaderCodeClassFieldDeclarationBlock(cf);
+ CPPSourceCodeDocument *scd = dynamic_cast<CPPSourceCodeDocument*>(cd);
+ if (scd)
+ return new CPPSourceCodeClassFieldDeclarationBlock(cf);
+ }
+ break;
+ case Uml::pl_Java:
+ retval = new JavaCodeClassFieldDeclarationBlock(cf);
+ break;
+ case Uml::pl_Ruby:
+ retval = new RubyCodeClassFieldDeclarationBlock(cf);
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+CodeComment * newCodeComment (CodeDocument *cd) {
+ switch (UMLApp::app()->getActiveLanguage()) {
+ case Uml::pl_Cpp:
+ if (dynamic_cast<CPPHeaderCodeDocument*>(cd) ||
+ dynamic_cast<CPPSourceCodeDocument*>(cd))
+ return new CPPCodeDocumentation(cd);
+ break;
+ case Uml::pl_Java:
+ if (dynamic_cast<JavaClassifierCodeDocument*>(cd))
+ return new JavaCodeComment(cd);
+ break;
+ case Uml::pl_Ruby:
+ if (dynamic_cast<RubyClassifierCodeDocument*>(cd))
+ return new RubyCodeComment(cd);
+ break;
+ default:
+ break;
+ }
+ if (dynamic_cast<JavaANTCodeDocument*>(cd))
+ return new XMLCodeComment(cd);
+ return new CodeComment(cd);
+}
+
+} // end namespace CodeGenFactory
+
diff --git a/umbrello/umbrello/codegenerators/codegenfactory.h b/umbrello/umbrello/codegenerators/codegenfactory.h
new file mode 100644
index 00000000..27a0f293
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/codegenfactory.h
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef CODEGENFACTORY_H
+#define CODEGENFACTORY_H
+
+#include "../umlnamespace.h"
+#include "../codeaccessormethod.h"
+
+// fwd decls
+class CodeGenerator;
+class ClassifierCodeDocument;
+class CodeOperation;
+class CodeClassField;
+class CodeClassFieldDeclarationBlock;
+class UMLClassifier;
+class UMLOperation;
+class UMLAttribute;
+class UMLRole;
+
+/**
+ * CodeGenFactory allows creating the available code generators as well
+ * as the auxiliary objects required for the advanced code generators.
+ *
+ * @author Jonathan Riddell
+ * @author Oliver Kellogg <okellogg@users.sourceforge.net>
+ * Bugs and comments to uml-devel@lists.sf.net or http://bugs.kde.org
+ */
+namespace CodeGenFactory {
+
+ /**
+ * Create a code generator specific to the given language.
+ */
+ CodeGenerator* createObject(Uml::Programming_Language pl);
+
+
+ /**
+ * Create a CodeOperation belonging to the given ClassifierCodeDocument.
+ * Only applies to the advanced generators.
+ *
+ * @param cd the parent ClassifierCodeDocument.
+ * @param op the related UMLOperation
+ * @return CodeOperation which is specific to the current language
+ */
+ CodeOperation *newCodeOperation(ClassifierCodeDocument *cd, UMLOperation * op);
+
+ /**
+ * Create an attribute CodeClassField belonging to the given
+ * ClassifierCodeDocument.
+ * Only applies to the advanced generators.
+ *
+ * @param cd the parent ClassifierCodeDocument
+ * @param at attribute which is parent of this class field
+ * @return CodeClassField which is specific to the current language
+ */
+ CodeClassField * newCodeClassField (ClassifierCodeDocument *cd, UMLAttribute * at);
+
+ /**
+ * Create an association role CodeClassField belonging to the given
+ * ClassifierCodeDocument.
+ * Only applies to the advanced generators.
+ *
+ * @param cd the parent ClassifierCodeDocument
+ * @param role association role which is parent of this class field
+ * @return CodeClassField which is specific to the current language
+ */
+ CodeClassField * newCodeClassField(ClassifierCodeDocument *cd, UMLRole *role);
+
+ /**
+ * Create a CodeAccessorMethod object belonging to the given ClassifierCodeDocument.
+ * Only applies to the advanced generators.
+ *
+ * @param cd the parent ClassifierCodeDocument
+ * @param cf CodeClassField which is parent of this object
+ * @param type CodeAccessorMethod::AccessorType to create
+ *
+ * @return CodeAccessorMethod which is specific to the current language
+ */
+ CodeAccessorMethod * newCodeAccessorMethod(ClassifierCodeDocument *cd,
+ CodeClassField *cf,
+ CodeAccessorMethod::AccessorType type);
+
+ /**
+ * Create a CodeClassFieldDeclarationBlock object belonging to the given
+ * ClassifierCodeDocument.
+ * Only applies to the advanced generators.
+ *
+ * @param cd the parent ClassifierCodeDocument
+ * @param cf CodeClassField which is parent of this object
+ *
+ * @return CodeClassFieldDeclarationBlock which is specific to the current language
+ */
+ CodeClassFieldDeclarationBlock * newDeclarationCodeBlock (ClassifierCodeDocument *cd,
+ CodeClassField * cf);
+
+ /**
+ * Create a new CodeComment object belonging to the given CodeDocument.
+ * Only applies to the advanced generators.
+ *
+ * @param cd the parent CodeDocument
+ * @return CodeBlockWithComments
+ */
+ CodeComment * newCodeComment (CodeDocument *cd);
+
+ /**
+ * Currently unused (for possible future use)
+ */
+ CodeDocument * newClassifierCodeDocument (UMLClassifier * classifier);
+}
+
+#endif //CODEGENFACTORY_H
diff --git a/umbrello/umbrello/codegenerators/codegenpolicyext.h b/umbrello/umbrello/codegenerators/codegenpolicyext.h
new file mode 100644
index 00000000..97ace9f2
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/codegenpolicyext.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * *
+ * 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) 2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef CODEGENPOLICYEXT_H
+#define CODEGENPOLICYEXT_H
+
+#include <qobject.h>
+
+class QWidget;
+class KConfig;
+class CodeGenerationPolicyPage;
+
+/**
+ * Base class for programming language specific code generation policy extensions.
+ * Not to be confused with CodeGenerationPolicy which contains the programming
+ * language independent policies.
+ *
+ * @author Oliver Kellogg <okellogg@users.sourceforge.net>
+ * Bugs and comments to uml-devel@lists.sf.net or http://bugs.kde.org
+ */
+
+class CodeGenPolicyExt : public QObject {
+public:
+ CodeGenPolicyExt() {}
+ virtual ~CodeGenPolicyExt() {}
+
+ /**
+ * Create a new dialog interface for this object.
+ * @return dialog object
+ */
+ virtual CodeGenerationPolicyPage * createPage(QWidget *parent = 0, const char *name = 0) = 0;
+
+ /**
+ * set the defaults from a config file for this code generator from the passed KConfig pointer.
+ */
+ virtual void setDefaults(KConfig * config, bool emitUpdateSignal = true) = 0;
+
+ /**
+ * write Default params to passed KConfig pointer.
+ */
+ virtual void writeConfig (KConfig * config) = 0;
+};
+
+#endif
diff --git a/umbrello/umbrello/codegenerators/cppcodeclassfield.cpp b/umbrello/umbrello/codegenerators/cppcodeclassfield.cpp
new file mode 100644
index 00000000..b6b2fb72
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodeclassfield.cpp
@@ -0,0 +1,108 @@
+/***************************************************************************
+ * *
+ * 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 : Mon Sep 1 2003
+ */
+
+// own header
+#include "cppcodeclassfield.h"
+
+// qt/kde includes
+#include <kdebug.h>
+
+// local includes
+#include "../codegenerator.h"
+#include "../classifiercodedocument.h"
+#include "../attribute.h"
+#include "../umlobject.h"
+#include "../umlrole.h"
+#include "../uml.h"
+#include "cppcodegenerationpolicy.h"
+
+
+// Constructors/Destructors
+//
+
+CPPCodeClassField::CPPCodeClassField (ClassifierCodeDocument * parentDoc, UMLRole * role)
+ : CodeClassField(parentDoc, role)
+{
+
+}
+
+CPPCodeClassField::CPPCodeClassField (ClassifierCodeDocument * parentDoc, UMLAttribute * attrib)
+ : CodeClassField(parentDoc, attrib)
+{
+
+}
+
+CPPCodeClassField::~CPPCodeClassField ( ) { }
+
+//
+// Methods
+//
+
+// Other methods
+//
+
+QString CPPCodeClassField::getFieldName() {
+ if (parentIsAttribute())
+ {
+ UMLAttribute * at = (UMLAttribute*) getParentObject();
+ return cleanName(at->getName());
+ }
+ else
+ {
+ UMLRole * role = (UMLRole*) getParentObject();
+ QString roleName = role->getName();
+ if(fieldIsSingleValue()) {
+ return roleName.replace(0, 1, roleName.left(1).lower());
+ } else {
+ return roleName.lower() + "Vector";
+ }
+ }
+}
+
+QString CPPCodeClassField::getListFieldClassName () {
+ CodeGenPolicyExt * p = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy *policy = dynamic_cast<CPPCodeGenerationPolicy*>(p);
+ return policy->getVectorClassName();
+}
+
+QString CPPCodeClassField::getInitialValue() {
+
+ if (parentIsAttribute())
+ {
+ UMLAttribute * at = dynamic_cast<UMLAttribute*>( getParentObject() );
+ if (at) {
+ return fixInitialStringDeclValue(at->getInitialValue(), getTypeName());
+ } else {
+ kError() << "CPPCodeClassField::getInitialValue: parent object is not a UMLAttribute"
+ << endl;
+ return "";
+ }
+ }
+ else
+ {
+ if(fieldIsSingleValue()) {
+ // FIX : IF the multiplicity is "1" then we should init a new object here, if its 0 or 1,
+ // then we can just return 'empty' string (minor problem).
+ return "";
+ } else {
+ return " new "+getListFieldClassName()+"( )";
+ }
+ }
+
+}
+
+
+#include "cppcodeclassfield.moc"
diff --git a/umbrello/umbrello/codegenerators/cppcodeclassfield.h b/umbrello/umbrello/codegenerators/cppcodeclassfield.h
new file mode 100644
index 00000000..d9c20255
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodeclassfield.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+
+
+#ifndef CPPCODECLASSFIELD_H
+#define CPPCODECLASSFIELD_H
+
+#include <qstring.h>
+
+#include "../codeclassfield.h"
+
+class ClassifierCodeDocument;
+
+class CPPCodeClassField : public CodeClassField
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructors
+ */
+ CPPCodeClassField (ClassifierCodeDocument * parentDoc, UMLRole * role);
+ CPPCodeClassField (ClassifierCodeDocument * parentDoc, UMLAttribute * attrib);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPCodeClassField ( );
+
+ QString getFieldType();
+ QString getFieldName();
+ QString getInitialValue();
+ /** get the name of the class which holds lists, e.g. "QPtrlist" or
+ * "Vector" or "List" and so on.
+ */
+ QString getListFieldClassName();
+
+
+protected:
+
+private:
+
+};
+
+#endif // CPPCODECLASSFIELD_H
diff --git a/umbrello/umbrello/codegenerators/cppcodecomment.cpp b/umbrello/umbrello/codegenerators/cppcodecomment.cpp
new file mode 100644
index 00000000..8d480e93
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodecomment.cpp
@@ -0,0 +1,98 @@
+
+/***************************************************************************
+ * *
+ * 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 : Mon Sep 1 2003
+ */
+
+// own header
+#include "cppcodecomment.h"
+
+// qt/kde includes
+#include <qregexp.h>
+
+// Constructors/Destructors
+//
+
+CPPCodeComment::CPPCodeComment ( CodeDocument * doc, const QString & text )
+ : CodeComment (doc, text)
+{
+
+}
+
+CPPCodeComment::~CPPCodeComment ( ) { }
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+
+// Public attribute accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * Save the XMI representation of this object
+ */
+void CPPCodeComment::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "cppcodecomment" );
+ setAttributesOnNode(doc, blockElement); // as we added no additional fields to this class we may
+ // just use parent TextBlock method
+ root.appendChild( blockElement );
+}
+
+/**
+ * @return QString
+ */
+QString CPPCodeComment::toString ( )
+{
+
+ QString output = "";
+
+ // simple output method
+ if(getWriteOutText())
+ {
+ QString indent = getIndentationString();
+ QString endLine = getNewLineEndingChars();
+ output.append(formatMultiLineText (getText()+endLine, indent +"// ", endLine));
+ }
+
+ return output;
+}
+
+QString CPPCodeComment::getNewEditorLine ( int amount ) {
+ QString line = getIndentationString(amount) + "// ";
+ return line;
+}
+
+/** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+QString CPPCodeComment::unformatText ( const QString & text , const QString & indent)
+{
+
+ // remove leading or trailing comment stuff
+ QString mytext = TextBlock::unformatText(text, indent);
+
+ // now leading slashes
+ mytext.remove(QRegExp("^\\/\\/\\s*"));
+ return mytext;
+}
+
+#include "cppcodecomment.moc"
diff --git a/umbrello/umbrello/codegenerators/cppcodecomment.h b/umbrello/umbrello/codegenerators/cppcodecomment.h
new file mode 100644
index 00000000..085e1a7f
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodecomment.h
@@ -0,0 +1,83 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+
+
+#ifndef CPPCODECOMMENT_H
+#define CPPCODECOMMENT_H
+
+#include <qstring.h>
+#include "../codecomment.h"
+
+/**
+ * class CPPCodeComment
+ * A CPP code comment. There is only a single styles of comments:
+ * these are simply started with double slash sequence and no terminating
+ * characters
+ */
+
+class CPPCodeComment : virtual public CodeComment
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructors
+ */
+ explicit CPPCodeComment ( CodeDocument * doc, const QString & text = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPCodeComment ( );
+
+ // Public attributes
+ //
+
+
+ // other
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+
+ /** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+ virtual QString unformatText ( const QString & text, const QString & indent = "" );
+
+ /** a special version here because we want to not only indent
+ * the new line, but to add the "//" sequence as well.
+ */
+ virtual QString getNewEditorLine ( int amount );
+
+protected:
+
+private:
+
+};
+
+#endif // CPPCODECOMMENT_H
diff --git a/umbrello/umbrello/codegenerators/cppcodedocumentation.cpp b/umbrello/umbrello/codegenerators/cppcodedocumentation.cpp
new file mode 100644
index 00000000..833e648e
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodedocumentation.cpp
@@ -0,0 +1,141 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+// own header
+#include "cppcodedocumentation.h"
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+// app includes
+#include "../codedocument.h"
+#include "../codegenerator.h"
+#include "../codegenerationpolicy.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+CPPCodeDocumentation::CPPCodeDocumentation ( CodeDocument * doc, const QString & text )
+ : CodeComment (doc, text)
+{
+
+}
+
+CPPCodeDocumentation::~CPPCodeDocumentation ( ) { }
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * Save the XMI representation of this object
+ */
+void CPPCodeDocumentation::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "cppcodedocumentation" );
+ setAttributesOnNode(doc, blockElement); // as we added no additional fields to this class we may
+ // just use parent TextBlock method
+ root.appendChild( blockElement );
+}
+
+/**
+ * @return QString
+ */
+QString CPPCodeDocumentation::toString ( )
+{
+
+ QString output = "";
+
+ // simple output method
+ if(getWriteOutText())
+ {
+ bool useDoubleDashOutput = true;
+
+ // need to figure out output type from cpp policy
+ CodeGenerationPolicy * p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ useDoubleDashOutput = false;
+
+ QString indent = getIndentationString();
+ QString endLine = getNewLineEndingChars();
+ QString body = getText();
+ if(useDoubleDashOutput)
+ {
+ if(!body.isEmpty())
+ output.append(formatMultiLineText (body, indent +"// ", endLine));
+ } else {
+ output.append(indent+"/**"+endLine);
+ output.append(formatMultiLineText (body, indent +" * ", endLine));
+ output.append(indent+" */"+endLine);
+ }
+ }
+
+ return output;
+}
+
+QString CPPCodeDocumentation::getNewEditorLine ( int amount )
+{
+ CodeGenerationPolicy * p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ return getIndentationString(amount) + " * ";
+ else
+ return getIndentationString(amount) + "// ";
+}
+
+int CPPCodeDocumentation::firstEditableLine() {
+ CodeGenerationPolicy * p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ return 1;
+ return 0;
+}
+
+int CPPCodeDocumentation::lastEditableLine() {
+ CodeGenerationPolicy * p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ {
+ return -1; // very last line is NOT editable
+ }
+ return 0;
+}
+
+/** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+QString CPPCodeDocumentation::unformatText ( const QString & text , const QString & indent)
+{
+
+ QString mytext = TextBlock::unformatText(text, indent);
+ CodeGenerationPolicy * p = UMLApp::app()->getCommonPolicy();
+ // remove leading or trailing comment stuff
+ mytext.remove(QRegExp('^'+indent));
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ {
+ mytext.remove(QRegExp("^\\/\\*\\*\\s*\n?"));
+ mytext.remove(QRegExp("\\s*\\*\\/\\s*\n?$"));
+ mytext.remove(QRegExp("^\\s*\\*\\s*"));
+ } else
+ mytext.remove(QRegExp("^\\/\\/\\s*"));
+
+ return mytext;
+}
+
+
diff --git a/umbrello/umbrello/codegenerators/cppcodedocumentation.h b/umbrello/umbrello/codegenerators/cppcodedocumentation.h
new file mode 100644
index 00000000..79bc4fe0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodedocumentation.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+
+
+#ifndef CPPCODEDOCUMENTATION_H
+#define CPPCODEDOCUMENTATION_H
+
+#include <qstring.h>
+#include "../codecomment.h"
+
+class CodeDocument;
+
+/**
+ * class CPPCodeDocumentation
+ * A CPP code comment. There is only a single styles of comments:
+ * these are simply started with double slash sequence and no terminating
+ * characters
+ */
+
+class CPPCodeDocumentation : virtual public CodeComment
+{
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructors
+ */
+ explicit CPPCodeDocumentation ( CodeDocument * doc, const QString & text = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPCodeDocumentation ( );
+
+ // Public attributes
+ //
+
+ // Other
+ //
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+
+ /** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+ virtual QString unformatText ( const QString & text, const QString & indent = "" );
+
+ /** a special version here because we want to not only indent
+ * the new line, but to add the " * " sequence as well.
+ */
+ virtual QString getNewEditorLine ( int amount );
+
+ /** Ush. These are terrifically bad and must one day go away.
+ * Both methods indicate the range of lines in this textblock
+ * which may be edited by the codeeditor (assuming that any are
+ * actually editable). The default case is no lines are editable.
+ * The line numbering starts with '0' and a '-1' means no line
+ * qualifies.
+ */
+ virtual int firstEditableLine();
+ virtual int lastEditableLine();
+
+protected:
+
+private:
+
+};
+
+#endif // CPPCODEDOCUMENTATION_H
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerationform.cpp b/umbrello/umbrello/codegenerators/cppcodegenerationform.cpp
new file mode 100644
index 00000000..a4acf713
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerationform.cpp
@@ -0,0 +1,305 @@
+/***************************************************************************
+ * *
+ * 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 Nov 20 2003
+ */
+
+// own header
+#include "cppcodegenerationform.h"
+
+// qt/kde includes
+#include <qlabel.h>
+#include <qregexp.h>
+#include <qlistview.h>
+#include <kfiledialog.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kcombobox.h>
+#include <kmessagebox.h>
+
+
+CPPCodeGenerationForm::CPPCodeGenerationForm( QWidget *parent, const char *name )
+ : CPPCodeGenerationFormBase (parent,name)
+{
+ init();
+
+ GeneralOptionsListView->addColumn(tr2i18n("General Options"));
+ pOptionPackageIsANamespace = new QCheckListItem( GeneralOptionsListView,
+ tr2i18n("Package is a namespace"),
+ QCheckListItem::CheckBox );
+ pOptionVirtualDestructors = new QCheckListItem( GeneralOptionsListView,
+ tr2i18n("Virtual destructors"),
+ QCheckListItem::CheckBox );
+ pOptionGenerateEmptyConstructors = new QCheckListItem( GeneralOptionsListView,
+ tr2i18n("Generate empty constructors"),
+ QCheckListItem::CheckBox );
+ pOptionGenerateAccessorMethods = new QCheckListItem( GeneralOptionsListView,
+ tr2i18n("Generate accessor methods"),
+ QCheckListItem::CheckBox );
+ pOptionOperationsAreInline = new QCheckListItem( GeneralOptionsListView,
+ tr2i18n("Operations are inline"),
+ QCheckListItem::CheckBox );
+ pOptionAccessorsAreInline = new QCheckListItem( GeneralOptionsListView,
+ tr2i18n("Accessors are inline"),
+ QCheckListItem::CheckBox );
+
+ pOptionAccessorsArePublic = new QCheckListItem( GeneralOptionsListView,
+ tr2i18n("Accessors are public"),
+ QCheckListItem::CheckBox );
+
+ connect(GeneralOptionsListView,
+ SIGNAL(clicked(QListViewItem *)), this,
+ SLOT(generalOptionsListViewClicked(QListViewItem *))
+ );
+
+}
+
+CPPCodeGenerationForm::~CPPCodeGenerationForm()
+{
+}
+
+void CPPCodeGenerationForm::browseClicked()
+{
+ QString button = sender()->name();
+ QString file = KFileDialog::getOpenFileName( QString::null, "*.h", this, "Get Header File");
+
+ if(file.isEmpty())
+ return;
+
+ if(button=="m_browseStringButton") {
+ // search for match in history list, if absent, then add it
+ m_stringIncludeFileHistoryCombo->setCurrentItem(file, true);
+ }
+ else if(button=="m_browseListButton") {
+ // search for match in history list, if absent, then add it
+ m_listIncludeFileHistoryCombo->setCurrentItem(file, true);
+ }
+}
+
+void CPPCodeGenerationForm::generalOptionsListViewClicked(QListViewItem *pSender) {
+
+ // operations are inline and accessors are operations :)
+ if (pOptionOperationsAreInline->isOn() && pOptionGenerateAccessorMethods->isOn())
+ pOptionAccessorsAreInline->setOn(true);
+
+ if (pSender == pOptionPackageIsANamespace) {
+#if 0
+ KMessageBox::error(0, "CPPCodeGenerationForm::generalOptionsListViewClicked(): "
+ "sender=pOptionPackageIsANamespace");
+#endif
+ return;
+ }
+ if (pSender == pOptionVirtualDestructors) {
+#if 0
+ KMessageBox::error(0, "CPPCodeGenerationForm::generalOptionsListViewClicked(): "
+ "sender=pOptionVirtualDestructors");
+#endif
+ return;
+ }
+ if (pSender == pOptionGenerateEmptyConstructors) {
+#if 0
+ KMessageBox::error(0, "CPPCodeGenerationForm::generalOptionsListViewClicked(): "
+ "sender=pOptionVirtualDestructors");
+#endif
+ return;
+ }
+ if (pSender == pOptionGenerateAccessorMethods) {
+ pOptionAccessorsAreInline->setEnabled(pOptionGenerateAccessorMethods->isOn());
+ pOptionAccessorsArePublic->setEnabled(pOptionGenerateAccessorMethods->isOn());
+ // reset the value if needed
+ if (!pOptionGenerateAccessorMethods->isOn())
+ {
+ pOptionAccessorsAreInline->setOn(false);
+ pOptionAccessorsArePublic->setOn(false);
+ }
+#if 0
+ KMessageBox::error(0, "CPPCodeGenerationForm::generalOptionsListViewClicked(): "
+ "sender=pOptionGenerateAccessorMethods");
+#endif
+ return;
+ }
+ if (pSender == pOptionOperationsAreInline) {
+#if 0
+ KMessageBox::error(0, "CPPCodeGenerationForm::generalOptionsListViewClicked(): "
+ "sender=pOptionOperationsAreInline");
+#endif
+ return;
+ }
+ if (pSender == pOptionAccessorsAreInline) {
+#if 0
+ KMessageBox::error(0, "CPPCodeGenerationForm::generalOptionsListViewClicked(): "
+ "sender=pOptionAccessorsAreInline");
+#endif
+ return;
+ }
+
+#if 0
+ KMessageBox::error(0, "CPPCodeGenerationForm::generalOptionsListViewClicked(): "
+ "unknown sender");
+#endif
+ return;
+}
+
+void CPPCodeGenerationForm::init() {
+ pOptionPackageIsANamespace = NULL;
+ pOptionVirtualDestructors = NULL;
+ pOptionGenerateEmptyConstructors = NULL;
+ pOptionGenerateAccessorMethods = NULL;
+ pOptionOperationsAreInline = NULL;
+ pOptionAccessorsAreInline = NULL;
+}
+
+/**
+ *
+ * set the display state of option "Package Is Namespace"
+ *
+ */
+void CPPCodeGenerationForm::setPackageIsANamespace(bool bFlag) {
+ pOptionPackageIsANamespace->setOn(bFlag);
+}
+
+/**
+ *
+ * set the display state of option "Virtual Destructors"
+ *
+ */
+void CPPCodeGenerationForm::setVirtualDestructors(bool bFlag) {
+ pOptionVirtualDestructors->setOn(bFlag);
+}
+
+/**
+ *
+ * set the display state of option "Generate Empty Constructors"
+ *
+ */
+void CPPCodeGenerationForm::setGenerateEmptyConstructors(bool bFlag) {
+ pOptionGenerateEmptyConstructors->setOn(bFlag);
+}
+
+/**
+ *
+ * set the display state of option "Generate Accessor Methods"
+ *
+ */
+void CPPCodeGenerationForm::setGenerateAccessorMethods(bool bFlag) {
+ pOptionGenerateAccessorMethods->setOn(bFlag);
+ // initial settings
+ pOptionAccessorsAreInline->setEnabled(pOptionGenerateAccessorMethods->isOn());
+ pOptionAccessorsArePublic->setEnabled(pOptionGenerateAccessorMethods->isOn());
+ // reset the value if needed
+ if (!pOptionGenerateAccessorMethods->isOn())
+ {
+ pOptionAccessorsAreInline->setOn(false);
+ pOptionAccessorsArePublic->setOn(false);
+ }
+}
+
+/**
+ *
+ * set the display state of option "Operations Are Inline"
+ *
+ */
+void CPPCodeGenerationForm::setOperationsAreInline(bool bFlag) {
+ pOptionOperationsAreInline->setOn(bFlag);
+}
+
+/**
+ *
+ * set the display state of option "Accessors Are Inline"
+ *
+ */
+void CPPCodeGenerationForm::setAccessorsAreInline(bool bFlag) {
+ pOptionAccessorsAreInline->setOn(bFlag);
+}
+
+/**
+ *
+ * set the display state of option "Accessors Are Public"
+ *
+ */
+void CPPCodeGenerationForm::setAccessorsArePublic(bool bFlag) {
+ pOptionAccessorsArePublic->setOn(bFlag);
+}
+
+/**
+ *
+ * get the display state of option "Package Is Namespace"
+ *
+ */
+bool CPPCodeGenerationForm::getPackageIsANamespace()
+{
+ return pOptionPackageIsANamespace->isOn();
+}
+
+/**
+ *
+ * get the display state of option "Virtual Destructors"
+ *
+ */
+bool CPPCodeGenerationForm::getVirtualDestructors()
+{
+ return pOptionVirtualDestructors->isOn();
+}
+
+/**
+ *
+ * get the display state of option "Generate Empty Constructors"
+ *
+ */
+bool CPPCodeGenerationForm::getGenerateEmptyConstructors()
+{
+ return pOptionGenerateEmptyConstructors->isOn();
+}
+
+/**
+ *
+ * get the display state of option "Generate Accessor Methods"
+ *
+ */
+bool CPPCodeGenerationForm::getGenerateAccessorMethods()
+{
+ return pOptionGenerateAccessorMethods->isOn();
+}
+
+/**
+ *
+ * get the display state of option "Operations Are Inline"
+ *
+ */
+bool CPPCodeGenerationForm::getOperationsAreInline()
+{
+ return pOptionOperationsAreInline->isOn();
+}
+
+/**
+ *
+ * get the display state of option "Accessors Are Inline"
+ *
+ */
+bool CPPCodeGenerationForm::getAccessorsAreInline()
+{
+ return pOptionAccessorsAreInline->isOn();
+}
+
+/**
+ *
+ * get the display state of option "Accessors Are Public"
+ *
+ */
+bool CPPCodeGenerationForm::getAccessorsArePublic()
+{
+ return pOptionAccessorsArePublic->isOn();
+}
+
+
+#include "cppcodegenerationform.moc"
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerationform.h b/umbrello/umbrello/codegenerators/cppcodegenerationform.h
new file mode 100644
index 00000000..73441a82
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerationform.h
@@ -0,0 +1,150 @@
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 30 2003
+ */
+
+#ifndef CPPCODEGENERATIONFORM_H
+#define CPPCODEGENERATIONFORM_H
+
+#include "cppcodegenerationformbase.h"
+
+class QCheckListItem;
+
+/**
+ * @author Brian Thomas
+ */
+
+class CPPCodeGenerationForm : public CPPCodeGenerationFormBase {
+ Q_OBJECT
+public:
+
+ /**
+ * std ctor
+ */
+ explicit CPPCodeGenerationForm (QWidget *parent=0, const char *name=0);
+
+ /**
+ * std dtor
+ */
+ virtual ~CPPCodeGenerationForm();
+
+ /**
+ * set the display state of option "Package Is A Namespace"
+ */
+ void setPackageIsANamespace(bool bFlag = true);
+
+ /**
+ * set the display state of option "Virtual Destructors"
+ */
+ void setVirtualDestructors(bool bFlag = true);
+
+ /**
+ * set the display state of option "Generate Empty Constructors"
+ */
+ void setGenerateEmptyConstructors(bool bFlag = true);
+
+ /**
+ * set the display state of option "Generate Accessor Methods"
+ */
+ void setGenerateAccessorMethods(bool bFlag = true);
+
+ /**
+ * set the display state of option "Operations Are Inline"
+ */
+ void setOperationsAreInline(bool bFlag = true);
+
+ /**
+ * set the display state of option "Accessors Are Inline"
+ */
+ void setAccessorsAreInline(bool bFlag = true);
+
+ /**
+ * set the display state of option "Accessors Are Public"
+ */
+ void setAccessorsArePublic(bool bFlag = true);
+
+ /**
+ * set the display state of option "Generate Makefile Document"
+ */
+ void setGenerateMakefileDocument(bool bFlag = true);
+
+ /**
+ * get the display state of option "Package Is A Namespace"
+ */
+ bool getPackageIsANamespace();
+
+ /**
+ * get the display state of option "Virtual Destructors"
+ */
+ bool getVirtualDestructors();
+
+ /**
+ * get the display state of option "Generate Empty Constructors"
+ */
+ bool getGenerateEmptyConstructors();
+
+ /**
+ * get the display state of option "Generate Accessors Methods"
+ */
+ bool getGenerateAccessorMethods();
+
+ /**
+ * get the display state of option "Operations Are Inline"
+ */
+ bool getOperationsAreInline();
+
+ /**
+ * get the display state of option "Accessors Are Inline"
+ */
+ bool getAccessorsAreInline();
+
+ /**
+ * get the display state of option "Accessors Are Public"
+ */
+ bool getAccessorsArePublic();
+
+ /**
+ * get the display state of option "Generate Makefile Document"
+ */
+ bool getGenerateMakefileDocument();
+
+protected:
+
+public slots:
+
+ virtual void browseClicked();
+
+private slots:
+ virtual void generalOptionsListViewClicked(QListViewItem *);
+
+private:
+
+ /*
+ * check boxes for the available options
+ */
+ QCheckListItem *pOptionPackageIsANamespace;
+ QCheckListItem *pOptionVirtualDestructors;
+ QCheckListItem *pOptionGenerateEmptyConstructors;
+ QCheckListItem *pOptionGenerateAccessorMethods;
+ QCheckListItem *pOptionOperationsAreInline;
+ QCheckListItem *pOptionAccessorsAreInline;
+ QCheckListItem *pOptionAccessorsArePublic;
+
+ /**
+ * initialize all attributes
+ */
+ void init();
+
+};
+
+#endif
+
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerationformbase.ui b/umbrello/umbrello/codegenerators/cppcodegenerationformbase.ui
new file mode 100644
index 00000000..2599ae35
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerationformbase.ui
@@ -0,0 +1,481 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>CPPCodeGenerationFormBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>CPPCodeGenerationFormBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>648</width>
+ <height>549</height>
+ </rect>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>44</y>
+ <width>436</width>
+ <height>72</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Documentation</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox" row="0" column="1">
+ <item>
+ <property name="text">
+ <string>Slash-Slash (//)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Slash-Star (/** */)</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_SelectCommentStyle</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Style:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>11</y>
+ <width>436</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p align="center"&gt;C++ Code Generation&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>tabWidget2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>120</y>
+ <width>436</width>
+ <height>305</height>
+ </rect>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>General</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView">
+ <property name="name">
+ <cstring>GeneralOptionsListView</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Method Body Generation</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>410</width>
+ <height>113</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Use following for classes in generated code:</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout17</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KHistoryCombo" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_listClassHCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ <property name="currentItem">
+ <number>0</number>
+ </property>
+ <property name="insertionPolicy">
+ <enum>NoInsertion</enum>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="historyItems">
+ <stringlist>
+ <string>QPtrList</string>
+ <string>vector</string>
+ </stringlist>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel1_3_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Variable&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="4" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_browseStringButton</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="7">
+ <property name="name">
+ <cstring>m_globalStringCheckBox</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="KHistoryCombo" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_stringClassHCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ <property name="currentItem">
+ <number>0</number>
+ </property>
+ <property name="insertionPolicy">
+ <enum>NoInsertion</enum>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="historyItems">
+ <stringlist>
+ <string>QString</string>
+ <string>string</string>
+ </stringlist>
+ </property>
+ </widget>
+ <spacer row="2" column="6">
+ <property name="name">
+ <cstring>spacer2_2_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Minimum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="6">
+ <property name="name">
+ <cstring>spacer1_2_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Minimum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>stringClassTextLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p align="center"&gt;String&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>listClassTextLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p align="center"&gt;List&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="KHistoryCombo" row="1" column="3">
+ <property name="name">
+ <cstring>m_listIncludeFileHistoryCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentItem">
+ <number>0</number>
+ </property>
+ <property name="insertionPolicy">
+ <enum>AtTop</enum>
+ </property>
+ <property name="historyItems">
+ <stringlist>
+ <string>qptrlist.h</string>
+ <string>vector</string>
+ </stringlist>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="5" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel4_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;global?&lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="KHistoryCombo" row="2" column="3">
+ <property name="name">
+ <cstring>m_stringIncludeFileHistoryCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentItem">
+ <number>0</number>
+ </property>
+ <property name="insertionPolicy">
+ <enum>AtTop</enum>
+ </property>
+ <property name="historyItems">
+ <stringlist>
+ <string>qstring.h</string>
+ <string>string</string>
+ </stringlist>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="7">
+ <property name="name">
+ <cstring>m_globalListCheckBox</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel3_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Class name</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="4" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_browseListButton</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="3" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel5_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;&lt;p align="center"&gt;Include file&lt;/p&gt;&lt;/i&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>m_browseListButton</sender>
+ <signal>clicked()</signal>
+ <receiver>CPPCodeGenerationFormBase</receiver>
+ <slot>browseClicked()</slot>
+ </connection>
+ <connection>
+ <sender>m_browseStringButton</sender>
+ <signal>clicked()</signal>
+ <receiver>CPPCodeGenerationFormBase</receiver>
+ <slot>browseClicked()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot>browseClicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerationpolicy.cpp b/umbrello/umbrello/codegenerators/cppcodegenerationpolicy.cpp
new file mode 100644
index 00000000..d0359603
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerationpolicy.cpp
@@ -0,0 +1,390 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+// own header
+#include "cppcodegenerationpolicy.h"
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+#include <kconfig.h>
+// app includes
+#include "cppcodegenerationpolicypage.h"
+#include "../uml.h"
+
+const bool CPPCodeGenerationPolicy::DEFAULT_AUTO_GEN_ACCESSORS = true;
+const bool CPPCodeGenerationPolicy::DEFAULT_INLINE_ACCESSORS = false;
+const bool CPPCodeGenerationPolicy::DEFAULT_INLINE_OPERATIONS = false;
+const bool CPPCodeGenerationPolicy::DEFAULT_VIRTUAL_DESTRUCTORS = true;
+const bool CPPCodeGenerationPolicy::DEFAULT_PACKAGE_IS_NAMESPACE = true;
+const char * CPPCodeGenerationPolicy::DEFAULT_STRING_CLASS_NAME = "string";
+const char * CPPCodeGenerationPolicy::DEFAULT_STRING_CLASS_INCLUDE = "string";
+const char * CPPCodeGenerationPolicy::DEFAULT_VECTOR_CLASS_NAME = "vector";
+const char * CPPCodeGenerationPolicy::DEFAULT_VECTOR_CLASS_INCLUDE = "vector";
+const char * CPPCodeGenerationPolicy::DEFAULT_VECTOR_METHOD_APPEND = "%VARNAME%.push_back(value);";
+const char * CPPCodeGenerationPolicy::DEFAULT_VECTOR_METHOD_REMOVE = "int size = %VARNAME%.size();\nfor ( int i = 0; i < size; ++i) {\n\t%ITEMCLASS% item = %VARNAME%.at(i);\n\tif(item == value) {\n\t\tvector<%ITEMCLASS%>::iterator it = %VARNAME%.begin() + i;\n\t\t%VARNAME%.erase(it);\n\t\treturn;\n\t}\n }";
+const char * CPPCodeGenerationPolicy::DEFAULT_VECTOR_METHOD_INIT = ""; // nothing to do in std::vector
+const char * CPPCodeGenerationPolicy::DEFAULT_OBJECT_METHOD_INIT = "%VARNAME% = new %ITEMCLASS%( );";
+const bool CPPCodeGenerationPolicy::DEFAULT_STRING_INCLUDE_GLOBAL = true;
+const bool CPPCodeGenerationPolicy::DEFAULT_VECTOR_INCLUDE_GLOBAL = true;
+const bool CPPCodeGenerationPolicy::DEFAULT_PUBLIC_ACCESSORS = false;
+
+
+// Constructors/Destructors
+//
+
+CPPCodeGenerationPolicy::CPPCodeGenerationPolicy(KConfig *config)
+{
+ init();
+ setDefaults(config,false);
+}
+
+CPPCodeGenerationPolicy::~CPPCodeGenerationPolicy ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+/**
+ * Set the value of m_publicAccessors
+ * @param new_var the new value
+ */
+void CPPCodeGenerationPolicy::setAccessorsArePublic ( bool var )
+{
+ m_publicAccessors = var;
+ // @todo we should probably use an own signal for this
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+/**
+ * Get the value of m_publicAccessors
+ * @return value the boolean value of m_publicAccessors
+ */
+bool CPPCodeGenerationPolicy::getAccessorsArePublic( )
+{
+ return m_publicAccessors;
+}
+
+/**
+ * Set the value of m_inlineAccessors
+ * @param new_var the new value
+ */
+void CPPCodeGenerationPolicy::setAccessorsAreInline ( bool var )
+{
+ m_inlineAccessors = var;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+/**
+ * Get the value of m_inlineAccessors
+ * @return value the boolean value of m_inlineAccessors
+ */
+bool CPPCodeGenerationPolicy::getAccessorsAreInline( )
+{
+ return m_inlineAccessors;
+}
+
+/**
+ * Set the value of m_inlineOperations
+ * @param new_var the new value
+ */
+void CPPCodeGenerationPolicy::setOperationsAreInline ( bool var )
+{
+ m_inlineOperations = var;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+/**
+ * Get the value of m_inlineOperations
+ * @return value the boolean value of m_inlineOperations
+ */
+bool CPPCodeGenerationPolicy::getOperationsAreInline( )
+{
+ return m_inlineOperations;
+}
+
+/**
+ * Set the value of m_virtualDestructors
+ * @param new_var the new value
+ */
+void CPPCodeGenerationPolicy::setDestructorsAreVirtual ( bool var )
+{
+ m_virtualDestructors = var;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+/**
+ * Get the value of m_virtualDestructors
+ * @return value the boolean value of m_virtualDestructors
+ */
+bool CPPCodeGenerationPolicy::getDestructorsAreVirtual( )
+{
+ return m_virtualDestructors;
+}
+
+/**
+ * Set the value of m_packageIsNamespace
+ * @param new_var the new value
+ */
+void CPPCodeGenerationPolicy::setPackageIsNamespace ( bool var ) {
+ m_packageIsNamespace = var;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+/**
+ * Get the value of m_packageIsNamespace
+ * @return value the boolean value of m_packageIsNamespace
+ */
+bool CPPCodeGenerationPolicy::getPackageIsNamespace( ) {
+ return m_packageIsNamespace;
+}
+
+/**
+ * Set the value of m_autoGenerateAccessors
+ * @param new_var the new value
+ */
+void CPPCodeGenerationPolicy::setAutoGenerateAccessors( bool var ) {
+ m_autoGenerateAccessors = var;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+bool CPPCodeGenerationPolicy::getAutoGenerateAccessors( ){
+ return m_autoGenerateAccessors;
+}
+
+QString CPPCodeGenerationPolicy::getStringClassName() {
+ return m_stringClassName;
+}
+
+QString CPPCodeGenerationPolicy::getStringClassNameInclude() {
+ return m_stringClassNameInclude;
+}
+
+QString CPPCodeGenerationPolicy::getVectorClassName() {
+ return m_vectorClassName;
+}
+
+QString CPPCodeGenerationPolicy::getVectorClassNameInclude() {
+ return m_vectorClassNameInclude;
+}
+
+void CPPCodeGenerationPolicy::setStringClassName(const QString &value) {
+ m_stringClassName = value;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+void CPPCodeGenerationPolicy::setStringClassNameInclude(const QString &value) {
+ m_stringClassNameInclude = value;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+void CPPCodeGenerationPolicy::setVectorClassName(const QString &value) {
+ m_vectorClassName = value;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+void CPPCodeGenerationPolicy::setVectorClassNameInclude(const QString &value) {
+ m_vectorClassNameInclude = value;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+/** determine if the string include is global one */
+bool CPPCodeGenerationPolicy::stringIncludeIsGlobal () {
+ return m_stringIncludeIsGlobal;
+}
+
+bool CPPCodeGenerationPolicy::vectorIncludeIsGlobal () {
+ return m_vectorIncludeIsGlobal;
+}
+
+void CPPCodeGenerationPolicy::setStringIncludeIsGlobal(bool value) {
+ m_stringIncludeIsGlobal = value;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+void CPPCodeGenerationPolicy::setVectorIncludeIsGlobal(bool value) {
+ m_vectorIncludeIsGlobal = value;
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+QString CPPCodeGenerationPolicy::getVectorMethodAppend(const QString & variableName, const QString & itemClassName) {
+ QString value = m_vectorMethodAppendBase;
+ if(!variableName.isEmpty())
+ value.replace(QRegExp("%VARNAME%"),variableName);
+ value.replace(QRegExp("%VECTORTYPENAME%"), m_vectorClassName);
+ if(!itemClassName.isEmpty())
+ value.replace(QRegExp("%ITEMCLASS%"),itemClassName);
+ return value;
+}
+
+QString CPPCodeGenerationPolicy::getVectorMethodRemove(const QString & variableName, const QString & itemClassName) {
+ QString value = m_vectorMethodRemoveBase;
+ if(!variableName.isEmpty())
+ value.replace(QRegExp("%VARNAME%"),variableName);
+ value.replace(QRegExp("%VECTORTYPENAME%"), m_vectorClassName);
+ if(!itemClassName.isEmpty())
+ value.replace(QRegExp("%ITEMCLASS%"),itemClassName);
+ return value;
+}
+
+QString CPPCodeGenerationPolicy::getVectorMethodInit(const QString & variableName, const QString & itemClassName) {
+ QString value = m_vectorMethodInitBase;
+ if(!variableName.isEmpty())
+ value.replace(QRegExp("%VARNAME%"),variableName);
+ value.replace(QRegExp("%VECTORTYPENAME%"), m_vectorClassName);
+ if(!itemClassName.isEmpty())
+ value.replace(QRegExp("%ITEMCLASS%"),itemClassName);
+ return value;
+}
+
+QString CPPCodeGenerationPolicy::getObjectMethodInit(const QString & variableName, const QString & itemClassName) {
+ QString value = m_objectMethodInitBase;
+ if(!variableName.isEmpty())
+ value.replace(QRegExp("%VARNAME%"),variableName);
+ value.replace(QRegExp("%VECTORTYPENAME%"), m_vectorClassName);
+ if(!itemClassName.isEmpty())
+ value.replace(QRegExp("%ITEMCLASS%"),itemClassName);
+ return value;
+}
+
+// Other methods
+//
+
+void CPPCodeGenerationPolicy::writeConfig ( KConfig * config )
+{
+
+ // write ONLY the CPP specific stuff
+ config->setGroup("CPP Code Generation");
+
+ config->writeEntry("autoGenAccessors",getAutoGenerateAccessors());
+
+ config->writeEntry("inlineAccessors",getAccessorsAreInline());
+ config->writeEntry("publicAccessors",getAccessorsArePublic());
+ config->writeEntry("inlineOps",getOperationsAreInline());
+ config->writeEntry("virtualDestructors",getDestructorsAreVirtual());
+ config->writeEntry("packageIsNamespace",getPackageIsNamespace());
+
+ config->writeEntry("stringClassName",getStringClassName());
+ config->writeEntry("stringClassNameInclude",getStringClassNameInclude());
+ config->writeEntry("stringIncludeIsGlobal",stringIncludeIsGlobal());
+
+ config->writeEntry("vectorClassName",getVectorClassName());
+ config->writeEntry("vectorClassNameInclude",getVectorClassNameInclude());
+ config->writeEntry("vectorIncludeIsGlobal",vectorIncludeIsGlobal());
+
+}
+
+void CPPCodeGenerationPolicy::setDefaults ( CPPCodeGenerationPolicy * cppclone, bool emitUpdateSignal )
+{
+ blockSignals(true); // we need to do this because otherwise most of these
+ // settors below will each send the modifiedCodeContent() signal
+ // needlessly (we can just make one call at the end).
+
+ {
+ setAutoGenerateAccessors(cppclone->getAutoGenerateAccessors());
+
+ setAccessorsAreInline(cppclone->getAccessorsAreInline());
+ setOperationsAreInline(cppclone->getOperationsAreInline());
+ setDestructorsAreVirtual(cppclone->getDestructorsAreVirtual());
+ setPackageIsNamespace(cppclone->getPackageIsNamespace());
+
+ setStringClassName(cppclone->getStringClassName() );
+ setStringClassNameInclude(cppclone->getStringClassNameInclude());
+ setStringIncludeIsGlobal(cppclone->stringIncludeIsGlobal());
+
+ setVectorClassName(cppclone->getVectorClassName());
+ setVectorClassNameInclude(cppclone->getVectorClassNameInclude());
+ setVectorIncludeIsGlobal(cppclone->vectorIncludeIsGlobal());
+
+ }
+
+ blockSignals(false); // "as you were citizen"
+
+ if(emitUpdateSignal)
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+
+}
+
+void CPPCodeGenerationPolicy::setDefaults( KConfig * config, bool emitUpdateSignal )
+{
+
+ if(!config)
+ return;
+
+ blockSignals(true); // we need to do this because otherwise most of these
+ // settors below will each send the modifiedCodeContent() signal
+ // needlessly (we can just make one call at the end).
+
+ // now do cpp specific stuff
+ config -> setGroup("CPP Code Generation");
+
+ setAutoGenerateAccessors(config->readBoolEntry("autoGenAccessors",DEFAULT_AUTO_GEN_ACCESSORS));
+
+ setAccessorsAreInline(config->readBoolEntry("inlineAccessors",DEFAULT_INLINE_ACCESSORS));
+ setAccessorsArePublic(config->readBoolEntry("publicAccessors",DEFAULT_PUBLIC_ACCESSORS));
+ setOperationsAreInline(config->readBoolEntry("inlineOps",DEFAULT_INLINE_OPERATIONS));
+ setDestructorsAreVirtual(config->readBoolEntry("virtualDestructors",DEFAULT_VIRTUAL_DESTRUCTORS));
+ setPackageIsNamespace(config->readBoolEntry("packageIsNamespace",DEFAULT_PACKAGE_IS_NAMESPACE));
+
+ setStringClassName(config->readEntry("stringClassName",DEFAULT_STRING_CLASS_NAME) );
+ setStringClassNameInclude(config->readEntry("stringClassNameInclude",DEFAULT_STRING_CLASS_INCLUDE ) );
+ setStringIncludeIsGlobal(config->readBoolEntry("stringIncludeIsGlobal",DEFAULT_STRING_INCLUDE_GLOBAL) );
+
+ setVectorClassName(config->readEntry("vectorClassName",DEFAULT_VECTOR_CLASS_NAME) );
+ setVectorClassNameInclude(config->readEntry("vectorClassNameInclude",DEFAULT_VECTOR_CLASS_INCLUDE) );
+ setVectorIncludeIsGlobal(config->readBoolEntry("vectorIncludeIsGlobal",DEFAULT_VECTOR_INCLUDE_GLOBAL) );
+
+ blockSignals(false); // "as you were citizen"
+
+ if(emitUpdateSignal)
+ UMLApp::app()->getCommonPolicy()->emitModifiedCodeContentSig();
+}
+
+
+/**
+ * Create a new dialog interface for this object.
+ * @return dialog object
+ */
+CodeGenerationPolicyPage * CPPCodeGenerationPolicy::createPage ( QWidget *parent, const char *name ) {
+ return new CPPCodeGenerationPolicyPage ( parent, name, this );
+}
+
+void CPPCodeGenerationPolicy::init() {
+
+ m_inlineAccessors = DEFAULT_INLINE_ACCESSORS;
+ m_publicAccessors = DEFAULT_PUBLIC_ACCESSORS;
+ m_inlineOperations = DEFAULT_INLINE_OPERATIONS;
+ m_virtualDestructors = DEFAULT_VIRTUAL_DESTRUCTORS;
+ m_packageIsNamespace = DEFAULT_PACKAGE_IS_NAMESPACE;
+
+ m_stringClassName = DEFAULT_STRING_CLASS_NAME;
+ m_stringClassNameInclude = DEFAULT_STRING_CLASS_INCLUDE;
+ m_stringIncludeIsGlobal = DEFAULT_STRING_INCLUDE_GLOBAL;
+
+ m_vectorClassName = DEFAULT_VECTOR_CLASS_NAME;
+ m_vectorClassNameInclude = DEFAULT_VECTOR_CLASS_INCLUDE;
+ m_vectorIncludeIsGlobal = DEFAULT_VECTOR_INCLUDE_GLOBAL;
+
+ m_vectorMethodAppendBase = DEFAULT_VECTOR_METHOD_APPEND;
+ m_vectorMethodRemoveBase = DEFAULT_VECTOR_METHOD_REMOVE;
+ m_vectorMethodInitBase = DEFAULT_VECTOR_METHOD_INIT;
+ m_objectMethodInitBase = DEFAULT_OBJECT_METHOD_INIT;
+
+}
+
+
+#include "cppcodegenerationpolicy.moc"
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerationpolicy.h b/umbrello/umbrello/codegenerators/cppcodegenerationpolicy.h
new file mode 100644
index 00000000..cda5d1f8
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerationpolicy.h
@@ -0,0 +1,227 @@
+/***************************************************************************
+ * *
+ * 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) 2003-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+#ifndef CPPCODEGENERATIONPOLICY_H
+#define CPPCODEGENERATIONPOLICY_H
+
+#include <qstring.h>
+#include "codegenpolicyext.h"
+#include "../codegenerationpolicy.h"
+
+class KConfig;
+class CodeGenerationPolicyPage;
+
+class CPPCodeGenerationPolicy : public CodeGenPolicyExt
+{
+ Q_OBJECT
+public:
+
+ static const bool DEFAULT_AUTO_GEN_EMPTY_CONSTRUCTORS;
+ static const bool DEFAULT_AUTO_GEN_ACCESSORS;
+ static const bool DEFAULT_INLINE_ACCESSORS;
+ static const bool DEFAULT_INLINE_OPERATIONS;
+ static const bool DEFAULT_VIRTUAL_DESTRUCTORS;
+ static const bool DEFAULT_PACKAGE_IS_NAMESPACE;
+ static const bool DEFAULT_PUBLIC_ACCESSORS;
+
+ static const bool DEFAULT_STRING_INCLUDE_GLOBAL;
+ static const bool DEFAULT_VECTOR_INCLUDE_GLOBAL;
+
+ static const char * DEFAULT_STRING_CLASS_NAME;
+ static const char * DEFAULT_STRING_CLASS_INCLUDE;
+ static const char * DEFAULT_VECTOR_CLASS_NAME;
+ static const char * DEFAULT_VECTOR_CLASS_INCLUDE;
+ static const char * DEFAULT_VECTOR_METHOD_APPEND;
+ static const char * DEFAULT_VECTOR_METHOD_REMOVE;
+ static const char * DEFAULT_VECTOR_METHOD_INIT;
+ static const char * DEFAULT_OBJECT_METHOD_INIT;
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructors
+ */
+ CPPCodeGenerationPolicy ( KConfig * config = 0 );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPCodeGenerationPolicy ( );
+
+ // Public attribute accessor methods
+ //
+
+ /**
+ * Set the value of m_inlineAccessors
+ * @param var the new value
+ */
+ void setAccessorsAreInline ( bool var );
+
+ /**
+ * Get the value of m_inlineAccessors
+ * @return value the boolean value of m_inlineAccessors
+ */
+ bool getAccessorsAreInline( );
+
+ /**
+ * Set the value of m_inlineOperations
+ * @param var the new value
+ */
+ void setOperationsAreInline ( bool var );
+
+ /**
+ * Get the value of m_inlineOperations
+ * @return value the boolean value of m_inlineOperations
+ */
+ bool getOperationsAreInline( );
+
+ /**
+ * Set the value of m_virtualDestructors
+ * @param var the new value
+ */
+ void setDestructorsAreVirtual ( bool var );
+
+ /**
+ * Get the value of m_virtualDestructors
+ * @return value the boolean value of m_virtualDestructors
+ */
+ bool getDestructorsAreVirtual( );
+
+ /**
+ * Set the value of m_packageIsNamespace
+ * @param var the new value
+ */
+ void setPackageIsNamespace ( bool var );
+
+ /**
+ * Get the value of m_packageIsNamespace
+ * @return value the boolean value of m_packageIsNamespace
+ */
+ bool getPackageIsNamespace( );
+
+
+ /**
+ * Set the value of m_autoGenerateAccessors
+ * @param var the new value
+ */
+ void setAutoGenerateAccessors ( bool var );
+
+ /**
+ * Get the value of m_autoGenerateAccessors
+ * @return value the boolean value of m_autoGenerateAccessors
+ */
+ bool getAutoGenerateAccessors( );
+
+ /**
+ * Set the value of m_publicAccessors
+ * @param var the new value
+ */
+ void setAccessorsArePublic ( bool var );
+
+ /**
+ * Get the value of m_publicAccessors
+ * @return value the boolean value of m_inlineAccessors
+ */
+ bool getAccessorsArePublic( );
+
+ /** We want to be flexible about which classes are allowed for generation
+ * of the CPP code. In the next 4 methods, we give accessors that allow getting
+ * the names of the classes, and their include files for string and vectors.
+ */
+ QString getStringClassName();
+ QString getStringClassNameInclude();
+ QString getVectorClassName();
+ QString getVectorClassNameInclude();
+
+ /** determine if the string include is global one */
+ bool stringIncludeIsGlobal ();
+ bool vectorIncludeIsGlobal ();
+
+ /** also allow setting these parameters! */
+ void setStringClassName(const QString &value);
+ void setStringClassNameInclude(const QString &value);
+ void setVectorClassName(const QString &value);
+ void setVectorClassNameInclude(const QString &value);
+
+ /** allow setting of these params */
+ void setStringIncludeIsGlobal (bool value);
+ void setVectorIncludeIsGlobal (bool value);
+
+ /** More flexible generation. We want to allow the user to specify how the
+ * bodies of the vector methods should be auto-generated.
+ */
+ QString getVectorMethodAppend(const QString & variableName ="", const QString & itemClassName = "");
+ QString getVectorMethodRemove(const QString & variableName ="", const QString & itemClassName = "");
+ QString getVectorMethodInit(const QString & variableName ="", const QString & itemClassName = "");
+
+ /** Be somewhat flexible about how new object classes are initialized.
+ * Not sure if this should be user configureable. For now, it isnt.
+ */
+ QString getObjectMethodInit(const QString & variableName ="", const QString & itemClassName = "");
+
+ /**
+ * set the defaults for this code generator from the passed generator.
+ */
+ virtual void setDefaults (CPPCodeGenerationPolicy * defaults, bool emitUpdateSignal = true);
+
+ /**
+ * set the defaults from a config file for this code generator from the passed KConfig pointer.
+ */
+ virtual void setDefaults(KConfig * config, bool emitUpdateSignal = true);
+
+ /**
+ * write Default params to passed KConfig pointer.
+ */
+ virtual void writeConfig (KConfig * config);
+
+ /**
+ * Create a new dialog interface for this object.
+ * @return dialog object
+ */
+ CodeGenerationPolicyPage * createPage ( QWidget *parent = 0, const char * name = 0);
+
+protected:
+
+ /**
+ */
+ void init ( );
+
+private:
+
+ bool m_autoGenerateAccessors;
+
+ bool m_inlineAccessors;
+ bool m_inlineOperations;
+ bool m_virtualDestructors;
+ bool m_packageIsNamespace;
+ bool m_publicAccessors;
+
+ bool m_stringIncludeIsGlobal;
+ bool m_vectorIncludeIsGlobal;
+
+ QString m_stringClassName;
+ QString m_stringClassNameInclude;
+ QString m_vectorClassName;
+ QString m_vectorClassNameInclude;
+ QString m_vectorMethodAppendBase;
+ QString m_vectorMethodRemoveBase;
+ QString m_vectorMethodInitBase;
+ QString m_objectMethodInitBase;
+
+};
+
+#endif // CPPCODEGENERATIONPOLICY_H
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.cpp b/umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.cpp
new file mode 100644
index 00000000..f05833dc
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.cpp
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 30 2003
+ */
+
+// own header
+#include "cppcodegenerationpolicypage.h"
+// qt/kde includes
+#include <kdebug.h>
+#include <klocale.h>
+#include <qlabel.h>
+#include <kcombobox.h>
+#include <qcheckbox.h>
+// app includes
+#include "cppcodegenerationformbase.h"
+#include "../uml.h"
+
+CPPCodeGenerationPolicyPage::CPPCodeGenerationPolicyPage( QWidget *parent, const char *name, CPPCodeGenerationPolicy * policy )
+ : CodeGenerationPolicyPage(parent, name, policy)
+{
+ CodeGenerationPolicy *common = UMLApp::app()->getCommonPolicy();
+ form = new CPPCodeGenerationForm(this);
+ form->m_SelectCommentStyle->setCurrentItem((int)(common->getCommentStyle()));
+ form->setPackageIsANamespace(policy->getPackageIsNamespace());
+ form->setVirtualDestructors(policy->getDestructorsAreVirtual());
+ form->setGenerateAccessorMethods(policy->getAutoGenerateAccessors());
+ form->setGenerateEmptyConstructors(common->getAutoGenerateConstructors());
+ form->setOperationsAreInline(policy->getOperationsAreInline());
+ form->setAccessorsAreInline(policy->getAccessorsAreInline());
+ form->setAccessorsArePublic(policy->getAccessorsArePublic());
+
+ form->m_stringClassHCombo->setCurrentItem(policy->getStringClassName(),true);
+ form->m_listClassHCombo->setCurrentItem(policy->getVectorClassName(),true);
+
+ form->m_stringIncludeFileHistoryCombo->setCurrentItem(policy->getStringClassNameInclude(),true);
+ form->m_listIncludeFileHistoryCombo->setCurrentItem(policy->getVectorClassNameInclude(),true);
+
+ form->m_globalStringCheckBox->setChecked(policy->stringIncludeIsGlobal());
+ form->m_globalListCheckBox->setChecked(policy->vectorIncludeIsGlobal());
+}
+
+CPPCodeGenerationPolicyPage::~CPPCodeGenerationPolicyPage()
+{
+}
+
+void CPPCodeGenerationPolicyPage::apply()
+{
+ CodeGenerationPolicy *common = UMLApp::app()->getCommonPolicy();
+
+ // now do our cpp-specific configs
+ CPPCodeGenerationPolicy * parent = (CPPCodeGenerationPolicy*) m_parentPolicy;
+
+ // block signals so that we don't generate too many sync signals for child code
+ // documents
+ parent->blockSignals(true);
+
+ common->setCommentStyle((CodeGenerationPolicy::CommentStyle ) form->m_SelectCommentStyle->currentItem());
+ common->setAutoGenerateConstructors(form->getGenerateEmptyConstructors());
+ parent->setAutoGenerateAccessors(form->getGenerateAccessorMethods());
+
+ parent->setDestructorsAreVirtual(form->getVirtualDestructors());
+ parent->setPackageIsNamespace(form->getPackageIsANamespace());
+ parent->setAccessorsAreInline(form->getAccessorsAreInline());
+ parent->setOperationsAreInline(form->getOperationsAreInline());
+ parent->setAccessorsArePublic(form->getAccessorsArePublic());
+
+ parent->setStringClassName(form->m_stringClassHCombo->currentText());
+ parent->setStringClassNameInclude(form->m_stringIncludeFileHistoryCombo->currentText());
+ parent->setStringIncludeIsGlobal(form->m_globalStringCheckBox->isChecked());
+
+ parent->setVectorClassName(form->m_listClassHCombo->currentText());
+ parent->setVectorClassNameInclude(form->m_listIncludeFileHistoryCombo->currentText());
+ parent->setVectorIncludeIsGlobal(form->m_globalListCheckBox->isChecked());
+
+ parent->blockSignals(false);
+
+ // now send out modified code content signal
+ common->emitModifiedCodeContentSig();
+
+}
+
+
+#include "cppcodegenerationpolicypage.moc"
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.h b/umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.h
new file mode 100644
index 00000000..a1d6633b
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * *
+ * 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) 2003-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 30 2003
+ */
+
+#ifndef CPPCODEGENERATIONPOLICYPAGE_H
+#define CPPCODEGENERATIONPOLICYPAGE_H
+
+#include "../dialogs/codegenerationpolicypage.h"
+
+#include "cppcodegenerationform.h"
+#include "cppcodegenerationpolicy.h"
+
+/**
+ * @author Brian Thomas
+ */
+
+class CPPCodeGenerationPolicyPage : public CodeGenerationPolicyPage {
+ Q_OBJECT
+public:
+
+ explicit CPPCodeGenerationPolicyPage (QWidget *parent=0, const char *name=0, CPPCodeGenerationPolicy * policy = 0);
+
+ virtual ~CPPCodeGenerationPolicyPage();
+
+protected:
+
+ CPPCodeGenerationForm * form;
+
+public slots:
+
+ void apply();
+
+};
+
+#endif
+
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerator.cpp b/umbrello/umbrello/codegenerators/cppcodegenerator.cpp
new file mode 100644
index 00000000..1130107b
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerator.cpp
@@ -0,0 +1,366 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Jun 19 2003
+ */
+
+// own header
+#include "cppcodegenerator.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+#include <kconfig.h>
+
+// app includes
+#include "cppcodedocumentation.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppsourcecodedocument.h"
+#include "cppheadercodedocument.h"
+#include "codegen_utils.h"
+#include "codeviewerdialog.h"
+#include "../codedocumentlist.h"
+#include "../uml.h"
+
+const bool CPPCodeGenerator::DEFAULT_BUILD_MAKEFILE = false;
+
+// Constructors/Destructors
+//
+
+CPPCodeGenerator::CPPCodeGenerator () {
+ initAttributes();
+}
+
+CPPCodeGenerator::~CPPCodeGenerator ( ) {
+ // destroy all separately owned codedocuments (e.g. header docs)
+ CodeDocument *doc;
+ for (CodeDocumentListIt it(m_headercodedocumentVector);
+ (doc = it.current()) != NULL; ++it)
+ delete doc;
+ m_headercodedocumentVector.clear();
+}
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+/**
+ * returns "C++"
+ */
+Uml::Programming_Language CPPCodeGenerator::getLanguage() {
+ return Uml::pl_Cpp;
+}
+
+/**
+ * Set the value of m_createMakefile
+ * @param new_var the new value of m_createMakefile
+ */
+void CPPCodeGenerator::setCreateProjectMakefile ( bool buildIt) {
+ m_createMakefile = buildIt;
+ CodeDocument * antDoc = findCodeDocumentByID(CPPMakefileCodeDocument::DOCUMENT_ID_VALUE);
+ if (antDoc)
+ antDoc->setWriteOutCode(buildIt);
+}
+
+/**
+ * Get the value of m_createMakefile
+ * @return the value of m_createMakefile
+ */
+bool CPPCodeGenerator::getCreateProjectMakefile ( ) {
+ return m_createMakefile;
+}
+
+bool CPPCodeGenerator::addHeaderCodeDocument ( CPPHeaderCodeDocument * doc )
+{
+
+ QString tag = doc->getID();
+
+ // assign a tag if one doesn't already exist
+ if(tag.isEmpty())
+ {
+ tag = "cppheader"+ID2STR(doc->getParentClassifier()->getID());
+ doc->setID(tag);
+ }
+
+ if(m_codeDocumentDictionary.find(tag))
+ return false; // return false, we already have some object with this tag in the list
+ else
+ m_codeDocumentDictionary.insert(tag, doc);
+
+ m_headercodedocumentVector.append(doc);
+ return true;
+}
+
+/**
+ * Remove a header CodeDocument object from m_headercodedocumentVector List
+ */
+bool CPPCodeGenerator::removeHeaderCodeDocument ( CPPHeaderCodeDocument * remove_object ) {
+ QString tag = remove_object->getID();
+ if(!(tag.isEmpty()))
+ m_codeDocumentDictionary.remove(tag);
+ else
+ return false;
+
+ m_headercodedocumentVector.remove(remove_object);
+ return true;
+}
+
+// In the C++ version, we need to make both source and header files as well
+// as the makefile available.
+CodeViewerDialog * CPPCodeGenerator::getCodeViewerDialog ( QWidget* parent, CodeDocument *doc,
+ Settings::CodeViewerState state)
+{
+
+ ClassifierCodeDocument * cdoc = dynamic_cast<ClassifierCodeDocument*>(doc);
+ if(!cdoc)
+ // bah..not a classcode document?? then just use vanilla version
+ return CodeGenerator::getCodeViewerDialog(parent,doc,state);
+ else {
+ // build with passed (source) code document
+ CodeViewerDialog *dialog;
+
+ // use classifier to find appropriate header document
+ UMLClassifier * c = cdoc->getParentClassifier();
+ CPPHeaderCodeDocument * hdoc = findHeaderCodeDocumentByClassifier(c);
+ if(hdoc)
+ {
+ // if we have a header document..build with that
+ dialog = new CodeViewerDialog(parent, hdoc, state);
+ dialog->addCodeDocument(doc);
+ } else
+ // shouldn't happen, but lets try to gracefully deliver something.
+ dialog = new CodeViewerDialog(parent, doc, state);
+
+ // add in makefile if available and desired
+ if(getCreateProjectMakefile())
+ dialog->addCodeDocument(findCodeDocumentByID(CPPMakefileCodeDocument::DOCUMENT_ID_VALUE));
+
+ return dialog;
+ }
+}
+
+// Other methods
+//
+
+// Change the following dataTypes to the ones the user really
+// wants in their code. Not yet complete.
+QString CPPCodeGenerator::fixTypeName(const QString &string)
+{
+ return cleanName(string);
+}
+
+// special method needed so that we write out the header code documents
+void CPPCodeGenerator::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement docElement = doc.createElement( "codegenerator" );
+ docElement.setAttribute("language", "C++");
+
+ CodeDocumentList * docList = getCodeDocumentList();
+ for (CodeDocument * codeDoc = docList->first(); codeDoc; codeDoc= docList->next())
+ codeDoc->saveToXMI(doc, docElement);
+
+ for (CodeDocument * hcodeDoc = m_headercodedocumentVector.first(); hcodeDoc; hcodeDoc=m_headercodedocumentVector.next())
+ hcodeDoc->saveToXMI(doc, docElement);
+
+ root.appendChild( docElement );
+}
+
+/**
+ * Force a synchronize of this code generator, and its present contents, to that of the parent UMLDocument.
+ * Need to override parent method because we have header documents to consider too.
+ */
+void CPPCodeGenerator::syncCodeToDocument ( ) {
+
+ CodeDocumentList * docList = getCodeDocumentList();
+
+ for (CodeDocument * doc = docList->first(); doc; doc=docList->next())
+ doc->synchronize();
+
+ for (CodeDocument * hcodeDoc = m_headercodedocumentVector.first(); hcodeDoc; hcodeDoc=m_headercodedocumentVector.next())
+ hcodeDoc->synchronize();
+
+}
+
+/**
+ * Write out all code documents to file as appropriate.
+ */
+void CPPCodeGenerator::writeCodeToFile ( )
+{
+ // write all source documents (incl. Makefile)
+ writeListedCodeDocsToFile(getCodeDocumentList());
+
+ // write all header documents
+ writeListedCodeDocsToFile(&m_headercodedocumentVector);
+
+}
+
+// overridden because we need to be able to generate code for
+// both the header and source documents
+void CPPCodeGenerator::writeCodeToFile ( UMLClassifierList & concepts) {
+ CodeDocumentList docs;
+ docs.setAutoDelete(false);
+
+ for (UMLClassifier *concept= concepts.first(); concept; concept= concepts.next())
+ {
+ CodeDocument * doc = findCodeDocumentByClassifier(concept);
+ if(doc)
+ docs.append(doc);
+ CodeDocument * hdoc = findHeaderCodeDocumentByClassifier(concept);
+ if(hdoc)
+ docs.append(hdoc);
+ }
+
+ writeListedCodeDocsToFile(&docs);
+}
+
+
+/**
+ * Find a cppheadercodedocument by the given classifier.
+ * @return CPPHeaderCodeDocument
+* @param classifier
+*/
+CPPHeaderCodeDocument * CPPCodeGenerator::findHeaderCodeDocumentByClassifier (UMLClassifier * classifier )
+{
+ CodeDocument * doc = findCodeDocumentByID("cppheader"+ID2STR(classifier->getID()));
+ return dynamic_cast<CPPHeaderCodeDocument*>(doc);
+}
+
+/**
+ * @return ClassifierCodeDocument
+ * @param classifier The classifier for which the CodeDocument is to be created
+ */
+// source document version.
+CodeDocument * CPPCodeGenerator::newClassifierCodeDocument (UMLClassifier * classifier)
+{
+ ClassifierCodeDocument *doc = new CPPSourceCodeDocument(classifier);
+ doc->initCodeClassFields();
+ return doc;
+}
+
+CPPHeaderCodeDocument * CPPCodeGenerator::newHeaderClassifierCodeDocument (UMLClassifier * classifier)
+{
+ CPPHeaderCodeDocument *doc = new CPPHeaderCodeDocument(classifier);
+ doc->initCodeClassFields();
+ return doc;
+}
+
+/**
+ * @return CPPMakefileCodeDocument
+ * @param this
+ */
+CPPMakefileCodeDocument * CPPCodeGenerator::newMakefileCodeDocument ( ) {
+ return new CPPMakefileCodeDocument();
+}
+
+
+/**
+ * Overloaded so that we may have both source and header documents for each
+ * classifier.
+ */
+void CPPCodeGenerator::initFromParentDocument( ) {
+
+ // Walk through the document converting classifiers into
+ // classifier code documents as needed (e.g only if doesn't exist)
+ UMLClassifierList concepts = UMLApp::app()->getDocument()->getClassesAndInterfaces();
+ for (UMLClassifier *c = concepts.first(); c; c = concepts.next())
+ {
+
+ // Doesn't exist? Then build one.
+ CodeDocument * codeDoc = findCodeDocumentByClassifier(c);
+ if (!codeDoc)
+ {
+ codeDoc = newClassifierCodeDocument(c);
+ codeDoc->synchronize();
+ addCodeDocument(codeDoc); // this will also add a unique tag to the code document
+ }
+
+ CPPHeaderCodeDocument * hcodeDoc = findHeaderCodeDocumentByClassifier(c);
+ if (!hcodeDoc)
+ {
+ hcodeDoc = newHeaderClassifierCodeDocument(c);
+ hcodeDoc->synchronize();
+ addHeaderCodeDocument(hcodeDoc); // this will also add a unique tag to the code document
+ }
+ }
+
+}
+
+// need to worry about adding both source, and header documents for each
+// classifier
+void CPPCodeGenerator::checkAddUMLObject (UMLObject * obj) {
+ if (!obj)
+ return;
+
+ // if the obj being created is a native data type
+ // there's no reason to create a .h/.cpp file
+ if (isReservedKeyword(obj->getName()))
+ return;
+
+ UMLClassifier * c = dynamic_cast<UMLClassifier*>(obj);
+ if(c) {
+ CodeDocument * cDoc = newClassifierCodeDocument(c);
+ CPPHeaderCodeDocument * hcodeDoc = newHeaderClassifierCodeDocument(c);
+ addCodeDocument(cDoc);
+ addHeaderCodeDocument(hcodeDoc); // this will also add a unique tag to the code document
+ }
+}
+
+// need to worry about removing both source, and header documents for each
+// classifier
+void CPPCodeGenerator::checkRemoveUMLObject (UMLObject * obj)
+{
+
+ if (!obj)
+ return;
+
+ UMLClassifier * c = dynamic_cast<UMLClassifier*>(obj);
+ if(c) {
+
+ // source
+ ClassifierCodeDocument * cDoc = (ClassifierCodeDocument*) findCodeDocumentByClassifier(c);
+ if (cDoc)
+ removeCodeDocument(cDoc);
+
+ // header
+ CPPHeaderCodeDocument * hcodeDoc = findHeaderCodeDocumentByClassifier(c);
+ if (hcodeDoc)
+ removeHeaderCodeDocument(hcodeDoc);
+ }
+
+}
+
+void CPPCodeGenerator::initAttributes ( )
+{
+ m_createMakefile = false;
+
+ UMLApp::app()->setPolicyExt ( new CPPCodeGenerationPolicy(UMLApp::app()->getConfig()) );
+
+ // load Classifier documents from parent document
+ //initFromParentDocument();
+}
+
+QStringList CPPCodeGenerator::defaultDatatypes() {
+ return Codegen_Utils::cppDatatypes();
+}
+
+const QStringList CPPCodeGenerator::reservedKeywords() const {
+ return Codegen_Utils::reservedCppKeywords();
+}
+
+void CPPCodeGenerator::createDefaultStereotypes (){
+ Codegen_Utils::createCppStereotypes();
+}
+
+#include "cppcodegenerator.moc"
diff --git a/umbrello/umbrello/codegenerators/cppcodegenerator.h b/umbrello/umbrello/codegenerators/cppcodegenerator.h
new file mode 100644
index 00000000..7104d403
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppcodegenerator.h
@@ -0,0 +1,167 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Jun 19 2003
+ */
+
+
+#ifndef CPPCODEGENERATOR_H
+#define CPPCODEGENERATOR_H
+
+#include <qstring.h>
+#include "../codedocumentlist.h"
+#include "../codeviewerstate.h"
+#include "../codegenerator.h"
+#include "../umldoc.h"
+#include "cppmakecodedocument.h"
+
+class CodeViewerDialog;
+class CPPHeaderCodeDocument;
+class CodeBlockWithComments;
+class KConfig;
+
+class CPPCodeGenerator : public CodeGenerator
+{
+ Q_OBJECT
+public:
+
+ static const bool DEFAULT_BUILD_MAKEFILE;
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Basic Constructor
+ */
+ CPPCodeGenerator ();
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPCodeGenerator ( );
+
+ /**
+ * Set the value of m_createMakefile
+ * @param new_var the new value of m_createMakefile
+ */
+ void setCreateProjectMakefile ( bool new_var );
+
+ /**
+ * Get the value of m_createMakefile
+ * @return the value of m_createMakefile
+ */
+ bool getCreateProjectMakefile ( );
+
+ // Public attribute accessor methods
+ //
+
+ QString fixTypeName(const QString &string);
+
+ /**
+ * Add a header CodeDocument object from m_headercodedocumentVector List
+ */
+ bool addHeaderCodeDocument ( CPPHeaderCodeDocument * doc );
+
+ /**
+ * Remove a header CodeDocument object from m_headercodedocumentVector List
+ */
+ bool removeHeaderCodeDocument ( CPPHeaderCodeDocument * remove_object );
+
+ /**
+ * returns "Cpp"
+ */
+ Uml::Programming_Language getLanguage();
+
+ // generate 2 different types of classifier code documents.
+ CodeDocument * newClassifierCodeDocument (UMLClassifier * classifier);
+ CPPHeaderCodeDocument * newHeaderClassifierCodeDocument (UMLClassifier * classifier);
+
+ /** Get the editing dialog for this code document
+ */
+ virtual CodeViewerDialog * getCodeViewerDialog( QWidget* parent, CodeDocument * doc,
+ Settings::CodeViewerState state);
+
+ /**
+ * Write out all code documents to file as appropriate.
+ */
+ virtual void writeCodeToFile ( );
+
+ // this method is here to provide class wizard the
+ // ability to write out only those classes which
+ // are selected by the user.
+ virtual void writeCodeToFile(UMLClassifierList &list);
+
+ /**
+ * Add C++ primitives as datatypes
+ */
+ QStringList defaultDatatypes();
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+ /**
+ * Add the default stereotypes for c++ (constructor, int etc)
+ */
+ virtual void createDefaultStereotypes ();
+
+ void initFromParentDocument( );
+
+protected:
+
+ /**
+ * @return CPPMakeCodeDocument
+ */
+ CPPMakefileCodeDocument * newMakefileCodeDocument ( );
+
+ /**
+ * Find a cppheadercodedocument by the given classifier.
+ * @return CPPHeaderCodeDocument
+ * @param classifier
+ */
+ CPPHeaderCodeDocument * findHeaderCodeDocumentByClassifier (UMLClassifier * classifier );
+
+private:
+
+ bool m_createMakefile;
+
+ // a separate list for recording the header documents
+ CodeDocumentList m_headercodedocumentVector;
+
+ void initAttributes ( ) ;
+
+public slots:
+
+ /** These 2 functions check for adding or removing objects to the UMLDocument
+ * they are need to be overridden here because unlike in the Java (or most other lang)
+ * we add 2 types of classifiercodedocument per classifier,
+ * e.g. a "source" and a "header" document.
+ */
+ virtual void checkAddUMLObject (UMLObject * obj);
+ virtual void checkRemoveUMLObject (UMLObject * obj);
+
+ /**
+ * Force a synchronize of this code generator, and its present contents, to that of the parent UMLDocument.
+ * "UserGenerated" code will be preserved, but Autogenerated contents will be updated/replaced
+ * or removed as is apppropriate.
+ */
+ virtual void syncCodeToDocument ( );
+};
+
+#endif // CPPCODEGENERATOR_H
diff --git a/umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.cpp b/umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.cpp
new file mode 100644
index 00000000..ea5612c9
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.cpp
@@ -0,0 +1,160 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#include "cppheaderclassdeclarationblock.h"
+#include "cppcodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppcodedocumentation.h"
+#include "../model_utils.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+CPPHeaderClassDeclarationBlock::CPPHeaderClassDeclarationBlock
+ ( CPPHeaderCodeDocument * parentDoc, const QString &startText, const QString &endText, const QString &comment)
+ : OwnedHierarchicalCodeBlock(parentDoc->getParentClassifier(), parentDoc, startText, endText, comment)
+{
+ init(parentDoc, comment);
+}
+
+CPPHeaderClassDeclarationBlock::~CPPHeaderClassDeclarationBlock ( ) { }
+
+//
+// Methods
+//
+
+/**
+ * load params from the appropriate XMI element node.
+ */
+void CPPHeaderClassDeclarationBlock::loadFromXMI ( QDomElement & root )
+{
+ setAttributesFromNode(root);
+}
+
+/** set the class attributes from a passed object
+ */
+void CPPHeaderClassDeclarationBlock::setAttributesFromObject (TextBlock * obj)
+{
+ HierarchicalCodeBlock::setAttributesFromObject(obj);
+}
+
+/**
+ * Save the XMI representation of this object
+ */
+void CPPHeaderClassDeclarationBlock::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "cppheaderclassdeclarationblock" );
+
+ setAttributesOnNode(doc, blockElement);
+
+ root.appendChild( blockElement );
+}
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * update the start and end text for this hierarchicalcodeblock.
+ */
+void CPPHeaderClassDeclarationBlock::updateContent ( )
+{
+
+ CPPHeaderCodeDocument *parentDoc = dynamic_cast<CPPHeaderCodeDocument*>(getParentDocument());
+ UMLClassifier *c = parentDoc->getParentClassifier();
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+ bool isInterface = parentDoc->parentIsInterface(); // a little shortcut
+ QString CPPHeaderClassName = CodeGenerator::cleanName(c->getName());
+ bool forceDoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
+
+ // COMMENT
+
+ //check if class is abstract.. it should have abstract methods
+ if(!isInterface && c->getAbstract() && !c->hasAbstractOps())
+ {
+ getComment()->setText("******************************* Abstract Class ****************************"+endLine
+ +CPPHeaderClassName+" does not have any pure virtual methods, but its author"+endLine
+ +" defined it as an abstract class, so you should not use it directly."+endLine
+ +" Inherit from it instead and create only objects from the derived classes"+endLine
+ +"*****************************************************************************");
+ } else {
+ if(isInterface)
+ getComment()->setText("Interface "+CPPHeaderClassName+endLine+c->getDoc());
+ else
+ getComment()->setText("Class "+CPPHeaderClassName+endLine+c->getDoc());
+ }
+
+ if(forceDoc || !c->getDoc().isEmpty())
+ getComment()->setWriteOutText(true);
+ else
+ getComment()->setWriteOutText(false);
+
+
+ // Now set START/ENDING Text
+ QString startText = "";
+
+ /*
+ */
+
+ /*
+ if(parentDoc->parentIsInterface())
+ startText.append("interface ");
+ else
+ */
+ startText.append("class ");
+
+ startText.append(CPPHeaderClassName);
+
+ // write inheritances out
+ UMLClassifierList superclasses = c->findSuperClassConcepts();
+ int nrof_superclasses = superclasses.count();
+
+ // write out inheritance
+ int i = 0;
+ if(nrof_superclasses >0)
+ startText.append(" : ");
+ for (UMLClassifier * concept= superclasses.first(); concept; concept = superclasses.next())
+ {
+ startText.append(concept->getVisibility().toString() + ' ' +
+ CodeGenerator::cleanName(concept->getName()));
+ if(i != (nrof_superclasses-1))
+ startText.append(", ");
+ i++;
+ }
+
+ // Set the header and end text for the hier.codeblock
+ setStartText(startText+" {");
+
+ // setEndText("}"); // not needed
+
+}
+
+void CPPHeaderClassDeclarationBlock::init (CPPHeaderCodeDocument *parentDoc, const QString &comment)
+{
+
+ setComment(new CPPCodeDocumentation(parentDoc));
+ getComment()->setText(comment);
+
+ setEndText("};");
+
+ updateContent();
+
+}
+
+
+#include "cppheaderclassdeclarationblock.moc"
diff --git a/umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.h b/umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.h
new file mode 100644
index 00000000..683f0475
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheaderclassdeclarationblock.h
@@ -0,0 +1,67 @@
+
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#ifndef CPPHEADERCLASSDECLARATIONBLOCK_H
+#define CPPHEADERCLASSDECLARATIONBLOCK_H
+
+#include <qstring.h>
+
+#include "cppheadercodedocument.h"
+#include "../ownedhierarchicalcodeblock.h"
+
+class CPPHeaderClassDeclarationBlock : public OwnedHierarchicalCodeBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ explicit CPPHeaderClassDeclarationBlock ( CPPHeaderCodeDocument * parentDoc, const QString &start = "", const QString &endText = "}", const QString &comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPHeaderClassDeclarationBlock ( );
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ virtual void loadFromXMI ( QDomElement & root );
+
+protected:
+
+ /** set the class attributes from a passed object
+ */
+ virtual void setAttributesFromObject (TextBlock * obj);
+
+ /**
+ * Update the start/end text of this codeblock.
+ */
+ void updateContent ( );
+
+private:
+
+ void init (CPPHeaderCodeDocument * parent, const QString &comment);
+
+};
+
+#endif // CPPHEADERCLASSDECLARATIONBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.cpp b/umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.cpp
new file mode 100644
index 00000000..0ab67b85
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.cpp
@@ -0,0 +1,170 @@
+/***************************************************************************
+ * *
+ * 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 : Fri Aug 31 2003
+ */
+
+// own header
+#include "cppheadercodeaccessormethod.h"
+
+// qt/kde includes
+#include <kdebug.h>
+
+// local includes
+#include "../attribute.h"
+#include "../classifiercodedocument.h"
+#include "cppcodegenerator.h"
+#include "../umlobject.h"
+#include "../umlrole.h"
+#include "../uml.h"
+
+#include "cppsourcecodedocument.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppcodeclassfield.h"
+#include "cppcodedocumentation.h"
+
+// Constructors/Destructors
+//
+
+CPPHeaderCodeAccessorMethod::CPPHeaderCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type)
+ : CodeAccessorMethod ( field )
+{
+ setType(type);
+}
+
+void CPPHeaderCodeAccessorMethod::update()
+{
+ updateMethodDeclaration();
+ updateContent();
+}
+
+CPPHeaderCodeAccessorMethod::~CPPHeaderCodeAccessorMethod ( ) { }
+
+// Other
+//
+
+// we basically want to update the body of this method
+void CPPHeaderCodeAccessorMethod::updateContent( )
+{
+ CodeClassField * parentField = getParentClassField();
+ CPPCodeClassField * cppfield = dynamic_cast<CPPCodeClassField*>(parentField);
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ bool isInlineMethod = policy->getAccessorsAreInline( );
+ Uml::Visibility scope = parentField->getVisibility();
+ QString variableName = cppfield->getFieldName();
+ QString itemClassName = cppfield->getTypeName();
+ QString text;
+
+ if(isInlineMethod) {
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ text = policy->getVectorMethodAppend(variableName, itemClassName);
+ break;
+ case CodeAccessorMethod::REMOVE:
+ text = policy->getVectorMethodRemove(variableName, itemClassName);
+ break;
+ case CodeAccessorMethod::SET:
+ text = variableName+" = value;";
+ break;
+ case CodeAccessorMethod::LIST:
+ case CodeAccessorMethod::GET:
+ default:
+ text = "return " + variableName + ';';
+ break;
+ }
+ }
+
+ setText(text);
+}
+
+// we basically want to update the start text of this method
+void CPPHeaderCodeAccessorMethod::updateMethodDeclaration()
+{
+
+ CodeClassField * parentField = getParentClassField();
+ ClassifierCodeDocument * doc = parentField->getParentDocument();
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ CPPCodeClassField * cppfield = dynamic_cast<CPPCodeClassField*>(parentField);
+
+ bool isInlineMethod = policy->getAccessorsAreInline( );
+
+ QString vectorClassName = policy->getVectorClassName();
+ QString fieldName = cppfield->getFieldName();
+ QString fieldType = cppfield->getTypeName();
+ QString objectType = cppfield->getListObjectType();
+ if(objectType.isEmpty())
+ objectType = fieldName;
+
+ QString methodReturnType = "void";
+ QString methodName;
+ QString methodParams;
+ QString headerText;
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ methodName = "add_"+fieldType;
+ methodReturnType = "void";
+ methodParams = objectType+" value ";
+ headerText = "Add a "+fieldName+" object to the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return void";
+ break;
+ case CodeAccessorMethod::REMOVE:
+ methodName = "remove_"+fieldType;
+ methodParams = objectType+" value ";
+ methodReturnType = "void";
+ headerText = "Remove a "+fieldName+" object from the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return void";
+ break;
+ case CodeAccessorMethod::LIST:
+ methodName = "get_"+fieldType+"_list";
+ methodReturnType = vectorClassName;
+ headerText = "Get the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return "+vectorClassName+"with list of objects";
+ break;
+ case CodeAccessorMethod::SET:
+ methodName = "set_"+fieldName;
+ methodParams = fieldType+" value ";
+ methodReturnType = "void";
+ headerText = "Set the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@param value the value of "+fieldName;
+ break;
+ case CodeAccessorMethod::GET:
+ default:
+ methodName = "get_"+fieldName;
+ methodReturnType = fieldType;
+ headerText = "Get the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@return the value of "+fieldName;
+ break;
+ }
+
+ // set header
+ CPPCodeDocumentation * header = new CPPCodeDocumentation(doc);
+ if(!getParentObject()->getDoc().isEmpty())
+ header->setText(headerText);
+ setComment(header);
+
+ // set start/end method text
+ QString startText = methodReturnType + ' ' + methodName + " (" + methodParams +')';
+ if (isInlineMethod)
+ startText += " {";
+ else
+ startText += ';';
+ QString endText = (isInlineMethod ? "}" : "");
+
+ setStartMethodText(startText);
+ setEndMethodText(endText);
+
+ setOverallIndentationLevel(1);
+}
+
+
+
+#include "cppheadercodeaccessormethod.moc"
diff --git a/umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.h b/umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.h
new file mode 100644
index 00000000..7b39fc6d
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodeaccessormethod.h
@@ -0,0 +1,57 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Fri Aug 31 2003
+ */
+
+#ifndef CPPHEADERACCESSORMETHOD_H
+#define CPPHEADERACCESSORMETHOD_H
+
+#include "../codeaccessormethod.h"
+
+#include <qstring.h>
+
+class CodeClassField;
+
+class CPPHeaderCodeAccessorMethod : public CodeAccessorMethod
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ CPPHeaderCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPHeaderCodeAccessorMethod ( );
+
+ /**
+ * Must be called before this object is usable
+ */
+ void update();
+
+protected:
+
+ virtual void updateMethodDeclaration();
+ virtual void updateContent();
+
+private:
+
+};
+
+#endif // CPPHEADERACCESSORMETHOD_H
diff --git a/umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.cpp b/umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.cpp
new file mode 100644
index 00000000..0fdfeb0a
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.cpp
@@ -0,0 +1,78 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#include "cppheadercodeclassfielddeclarationblock.h"
+
+#include "cppcodeclassfield.h"
+#include "cppheadercodedocument.h"
+
+// Constructors/Destructors
+//
+
+CPPHeaderCodeClassFieldDeclarationBlock::CPPHeaderCodeClassFieldDeclarationBlock ( CodeClassField * parent )
+ : CodeClassFieldDeclarationBlock ( parent )
+{
+ setOverallIndentationLevel(1);
+ updateContent();
+}
+
+CPPHeaderCodeClassFieldDeclarationBlock::~CPPHeaderCodeClassFieldDeclarationBlock ( ) { }
+
+//
+// Methods
+//
+
+// Other methods
+//
+
+/**
+ */
+void CPPHeaderCodeClassFieldDeclarationBlock::updateContent( )
+{
+ UMLObject *umlparent = CodeClassFieldDeclarationBlock::getParentObject();
+ if (umlparent == NULL) {
+ return;
+ }
+
+ CodeClassField * cf = getParentClassField();
+ CPPCodeClassField * hcppcf = dynamic_cast<CPPCodeClassField*>(cf);
+
+ // Set the comment
+ QString notes = umlparent->getDoc();
+ getComment()->setText(notes);
+ if(notes.isEmpty())
+ getComment()->setWriteOutText(false);
+ else
+ getComment()->setWriteOutText(true);
+
+
+ // Set the body
+ QString staticValue = umlparent->getStatic() ? "static " : "";
+ QString typeName = hcppcf->getTypeName();
+ QString fieldName = hcppcf->getFieldName();
+
+ // Ugh. Sloppy exception.
+ if (!cf->parentIsAttribute() && !cf->fieldIsSingleValue())
+ typeName = hcppcf->getListFieldClassName();
+
+ QString body = staticValue + ' ' + typeName + ' ' + fieldName + ';';
+
+ setText(body);
+
+}
+
+
+
+#include "cppheadercodeclassfielddeclarationblock.moc"
diff --git a/umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.h b/umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.h
new file mode 100644
index 00000000..755507c6
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodeclassfielddeclarationblock.h
@@ -0,0 +1,51 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#ifndef CPPHEADERCODECLASSFIELDDECLARATIONBLOCK_H
+#define CPPHEADERCODECLASSFIELDDECLARATIONBLOCK_H
+
+#include <qstring.h>
+
+#include "../codeclassfielddeclarationblock.h"
+
+class CPPHeaderCodeClassFieldDeclarationBlock : public CodeClassFieldDeclarationBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ CPPHeaderCodeClassFieldDeclarationBlock ( CodeClassField * parent );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPHeaderCodeClassFieldDeclarationBlock ( );
+
+protected:
+
+ // this will be called by syncToParent whenever the parent object is "modified"
+ void updateContent ( );
+
+private:
+
+
+};
+
+#endif // CPPHEADERCODECLASSFIELDDECLARATIONBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp b/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp
new file mode 100644
index 00000000..fe909c5d
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp
@@ -0,0 +1,813 @@
+/***************************************************************************
+ * *
+ * 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 Aug 28 2003
+ */
+
+/**
+ We carve the CPP document up into 2 documents, "source" and "header".
+ This one represents the header portion.
+ The sections of each are as follows:
+
+ * header
+ * includes
+ * import statements
+ * class declaration
+ * guts of the class (e.g. field decl, accessor methods, operations, dependant classes)
+*/
+
+// own header
+#include "cppheadercodedocument.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "cppcodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppcodedocumentation.h"
+#include "cppheadercodeaccessormethod.h"
+#include "cppheadercodeoperation.h"
+#include "cppheaderclassdeclarationblock.h"
+#include "cppheadercodeclassfielddeclarationblock.h"
+#include "../umlpackagelist.h"
+#include "../package.h"
+#include "../umlclassifierlistitemlist.h"
+#include "../classifierlistitem.h"
+#include "../enum.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+CPPHeaderCodeDocument::CPPHeaderCodeDocument ( UMLClassifier * concept )
+ : ClassifierCodeDocument (concept)
+{
+ setFileExtension(".h");
+
+ //initCodeClassFields(); // this is dubious because it calls down to
+ // CodeGenFactory::newCodeClassField(this)
+ // but "this" is still in construction at that time.
+
+ // needed? I doubt it, but it feels good to do it.
+ classDeclCodeBlock = 0;
+ publicBlock = 0;
+ protectedBlock = 0;
+ privateBlock = 0;
+ namespaceBlock = 0;
+ pubConstructorBlock = 0;
+ protConstructorBlock = 0;
+ privConstructorBlock = 0;
+ pubOperationsBlock = 0;
+ privOperationsBlock = 0;
+ protOperationsBlock = 0;
+
+ // this will call updateContent() as well as other things that sync our document.
+ //synchronize();
+
+}
+
+CPPHeaderCodeDocument::~CPPHeaderCodeDocument ( ) {
+ resetTextBlocks();
+}
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+CPPHeaderClassDeclarationBlock * CPPHeaderCodeDocument::getClassDecl()
+{
+
+ if(!classDeclCodeBlock) {
+ classDeclCodeBlock = new CPPHeaderClassDeclarationBlock (this); // was deleted before our load
+ classDeclCodeBlock->setTag("classDeclarationBlock");
+ }
+ return classDeclCodeBlock;
+}
+
+// Other methods
+//
+
+// Sigh. NOT optimal. The only reason that we need to have this
+// is so we can create the CPPHeaderClassDeclarationBlock.
+// would be better if we could create a handler interface that each
+// codeblock used so all we have to do here is add the handler
+void CPPHeaderCodeDocument::loadChildTextBlocksFromNode ( QDomElement & root)
+{
+
+ QDomNode tnode = root.firstChild();
+ QDomElement telement = tnode.toElement();
+ bool loadCheckForChildrenOK = false;
+ while( !telement.isNull() ) {
+ QString nodeName = telement.tagName();
+
+ if( nodeName == "textblocks" ) {
+
+ QDomNode node = telement.firstChild();
+ QDomElement element = node.toElement();
+
+ // if there is nothing to begin with, then we don't worry about it
+ loadCheckForChildrenOK = element.isNull() ? true : false;
+
+ while( !element.isNull() ) {
+ QString name = element.tagName();
+
+ if( name == "codecomment" ) {
+ CodeComment * block = new CPPCodeDocumentation(this);
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeComment to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeaccessormethod" ||
+ name == "ccfdeclarationcodeblock"
+ ) {
+ QString acctag = element.attribute("tag","");
+ // search for our method in the
+ TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
+ if(!tb || !addTextBlock(tb))
+ {
+ kError()<<"Unable to add codeclassfield child method to:"<<this<<endl;
+ // DON'T delete
+ } else
+ loadCheckForChildrenOK= true;
+
+ } else
+ if( name == "codeblock" ) {
+ CodeBlock * block = newCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeBlock to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeblockwithcomments" ) {
+ CodeBlockWithComments * block = newCodeBlockWithComments();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeBlockwithcomments to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "header" ) {
+ // do nothing.. this is treated elsewhere
+ } else
+ if( name == "hierarchicalcodeblock" ) {
+ HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeoperation" ) {
+ // find the code operation by id
+ QString id = element.attribute("parent_id","-1");
+ UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
+ UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
+ if(op) {
+ CodeOperation * block = new CPPHeaderCodeOperation(this, op);
+ block->loadFromXMI(element);
+ if(addTextBlock(block))
+ loadCheckForChildrenOK= true;
+ else
+ {
+ kError()<<"Unable to add codeoperation to:"<<this<<endl;
+ block->deleteLater();
+ }
+ } else
+ kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
+ }
+ else
+ if( name == "cppheaderclassdeclarationblock" )
+ {
+ CPPHeaderClassDeclarationBlock * block = getClassDecl();
+ block->loadFromXMI(element);
+ // normally this would be populated by the following syncToparent
+ // call, but we cant wait for it, so lets just do it now.
+ namespaceBlock = getHierarchicalCodeBlock("namespace", "Namespace", 0);
+
+ if(!namespaceBlock || !namespaceBlock->addTextBlock(block))
+ {
+ kError()<<"Error:cant add class declaration codeblock"<<endl;
+ // DON'T delete/release block
+ // block->release();
+ } else
+ loadCheckForChildrenOK= true;
+
+ }
+ // only needed for extreme debugging conditions (E.g. making new codeclassdocument loader)
+ //else
+ //kDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"<<endl;
+
+ node = element.nextSibling();
+ element = node.toElement();
+ }
+ break;
+ }
+
+ tnode = telement.nextSibling();
+ telement = tnode.toElement();
+ }
+
+ if(!loadCheckForChildrenOK)
+ {
+ CodeDocument * test = dynamic_cast<CodeDocument*>(this);
+ if(test)
+ {
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
+ } else {
+ HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
+ if(hb)
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
+ else
+ kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
+ }
+ }
+
+}
+
+void CPPHeaderCodeDocument::resetTextBlocks()
+{
+
+ // all special pointers need to be zero'd out.
+ classDeclCodeBlock = 0;
+ publicBlock = 0;
+ protectedBlock = 0;
+ privateBlock = 0;
+ namespaceBlock = 0;
+ pubConstructorBlock = 0;
+ protConstructorBlock = 0;
+ privConstructorBlock = 0;
+ pubOperationsBlock = 0;
+ privOperationsBlock = 0;
+ protOperationsBlock = 0;
+
+ // now do the traditional release of child text blocks
+ ClassifierCodeDocument::resetTextBlocks();
+
+}
+
+/**
+ * @param op
+ */
+// in the vannilla version, we just tack all operations on the end
+// of the document
+bool CPPHeaderCodeDocument::addCodeOperation (CodeOperation * op )
+{
+ Uml::Visibility scope = op->getParentOperation()->getVisibility();
+ if(!op->getParentOperation()->isLifeOperation())
+ {
+ switch (scope) {
+ default:
+ case Uml::Visibility::Public:
+ return pubOperationsBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Protected:
+ return protOperationsBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Private:
+ return privOperationsBlock->addTextBlock(op);
+ break;
+ }
+ } else {
+ switch (scope) {
+ default:
+ case Uml::Visibility::Public:
+ return pubConstructorBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Protected:
+ return protConstructorBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Private:
+ return privConstructorBlock->addTextBlock(op);
+ break;
+ }
+ }
+}
+
+
+/**
+ * Save the XMI representation of this object
+ * @return bool status of save
+ */
+/*
+void CPPHeaderCodeDocument::saveToXMI ( QDomDocument & doc, QDomElement & root )
+{
+ QDomElement docElement = doc.createElement( "" );
+
+ setAttributesOnNode(doc, docElement);
+
+ root.appendChild( docElement );
+}
+*/
+
+// This method will cause the class to rebuild its text representation.
+// based on the parent classifier object.
+// For any situation in which this is called, we are either building the code
+// document up, or replacing/regenerating the existing auto-generated parts. As
+// such, we will want to insert everything we resonablely will want
+// during creation. We can set various parts of the document (esp. the
+// comments) to appear or not, as needed.
+void CPPHeaderCodeDocument::updateContent( )
+{
+ // Gather info on the various fields and parent objects of this class...
+ UMLClassifier * c = getParentClassifier();
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+
+ // first, set the global flag on whether or not to show classfield info
+ CodeClassFieldList * cfList = getCodeClassFieldList();
+ for(CodeClassField * field = cfList->first(); field; field = cfList->next())
+ field->setWriteOutMethods(policy->getAutoGenerateAccessors());
+
+ // attribute-based ClassFields
+ // we do it this way to have the static fields sorted out from regular ones
+ CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public );
+ CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public );
+ CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected );
+ CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected );
+ CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private );
+ CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private);
+
+ // association-based ClassFields
+ // don't care if they are static or not..all are lumped together
+ CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Public);
+ CodeClassFieldList publicAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Public);
+ CodeClassFieldList publicCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Public );
+
+ CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Protected);
+ CodeClassFieldList protAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Protected);
+ CodeClassFieldList protCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Protected);
+
+ CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Private);
+ CodeClassFieldList privAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Private);
+ CodeClassFieldList privCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Private);
+
+ bool hasOperationMethods = c->getOpList().last() ? true : false;
+ bool hasNamespace = false;
+ bool isEnumeration = false;
+ bool isInterface = parentIsInterface();
+ bool hasclassFields = hasClassFields();
+ bool forcedoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+
+ UMLClassifierList superclasses = c->findSuperClassConcepts();
+
+
+ // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
+ //
+
+ // Write the hash define stuff to prevent multiple parsing/inclusion of header
+ QString cppClassName = CodeGenerator::cleanName(c->getName());
+ QString hashDefine = CodeGenerator::cleanName(c->getName().upper().simplifyWhiteSpace());
+ QString defText = "#ifndef "+hashDefine + "_H"+ endLine + "#define "+ hashDefine + "_H";
+ addOrUpdateTaggedCodeBlockWithComments("hashDefBlock", defText, "", 0, false);
+
+ // INCLUDE CODEBLOCK
+ //
+ // Q: Why all utils? Isnt just List and Vector the only classes we are using?
+ // A: doesn't matter at all; its more readable to just include '*' and cpp compilers
+ // don't slow down or anything. (TZ)
+ QString includeStatement = "";
+ bool stringGlobal = policy->stringIncludeIsGlobal();
+ QString sStartBrak = stringGlobal ? "<" : "\"";
+ QString sEndBrak = stringGlobal ? ">" : "\"";
+ includeStatement.append("#include "+sStartBrak+policy->getStringClassNameInclude()+sEndBrak+endLine);
+ if ( hasObjectVectorClassFields() )
+ {
+ bool vecGlobal = policy->vectorIncludeIsGlobal();
+ QString vStartBrak = vecGlobal ? "<" : "\"";
+ QString vEndBrak = vecGlobal ? ">" : "\"";
+ QString value ="#include "+vStartBrak+policy->getVectorClassNameInclude()+vEndBrak;
+ includeStatement.append(value+endLine);
+ }
+
+ //only include classes in a different package from this class
+ UMLPackageList includes;
+ QMap<UMLPackage *,QString> packageMap; // so we don't repeat packages
+
+ CodeGenerator::findObjectsRelated(c,includes);
+ for(UMLPackage *con = includes.first(); con ; con = includes.next())
+ if (con->getBaseType() != Uml::ot_Datatype && !packageMap.contains(con))
+ {
+ packageMap.insert(con,con->getPackage());
+ if(con != getParentClassifier())
+ includeStatement.append("#include \""+CodeGenerator::cleanName(con->getName().lower())+".h\""+endLine);
+ }
+ // now, add/update the includes codeblock
+ CodeBlockWithComments * inclBlock = addOrUpdateTaggedCodeBlockWithComments("includes", includeStatement, QString::null, 0, false);
+ if(includeStatement.isEmpty() && inclBlock->getContentType() == CodeBlock::AutoGenerated)
+ inclBlock->setWriteOutText(false);
+ else
+ inclBlock->setWriteOutText(true);
+
+ // Using
+ QString usingStatement;
+ for(UMLClassifier *classifier = superclasses.first(); classifier ; classifier = superclasses.next()) {
+ if(classifier->getPackage()!=c->getPackage() && !classifier->getPackage().isEmpty()) {
+ usingStatement.append("using "+CodeGenerator::cleanName(c->getPackage())+"::"+cleanName(c->getName())+';'+endLine);
+ }
+ }
+ CodeBlockWithComments * usingBlock = addOrUpdateTaggedCodeBlockWithComments("using", usingStatement, "", 0, false);
+ if(usingStatement.isEmpty() && usingBlock->getContentType() == CodeBlock::AutoGenerated)
+ usingBlock->setWriteOutText(false);
+ else
+ usingBlock->setWriteOutText(true);
+
+ // namespace
+ // This needs special treatment. We cant use "nowriteouttext" for this, as
+ // that will prevent the class declaration from being written. Instead, we
+ // check if "hasNamspace" is true or not, and then indent the remaining code
+ // appropriately as well as set the start/end text of this namespace block.
+ if (c->getUMLPackage() && policy->getPackageIsNamespace())
+ hasNamespace = true;
+ else
+ hasNamespace = false;
+
+ // set start/end text of namespace block
+ namespaceBlock = getHierarchicalCodeBlock("namespace", "Namespace", 0);
+ if(hasNamespace) {
+ UMLPackageList pkgList = c->getPackages();
+ QString pkgs;
+ UMLPackage *pkg;
+ for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
+ pkgs += "namespace " + CodeGenerator::cleanName(pkg->getName()) + " { ";
+ }
+ namespaceBlock->setStartText(pkgs);
+ QString closingBraces;
+ for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
+ closingBraces += "} ";
+ }
+ namespaceBlock->setEndText(closingBraces);
+ namespaceBlock->getComment()->setWriteOutText(true);
+ } else {
+ namespaceBlock->setStartText("");
+ namespaceBlock->setEndText("");
+ namespaceBlock->getComment()->setWriteOutText(false);
+ }
+
+ // Enum types for include
+ if (!isInterface) {
+ QString enumStatement;
+ QString indent = UMLApp::app()->getCommonPolicy()->getIndentation();
+ UMLEnum* e = dynamic_cast<UMLEnum*>(c);
+ if (e) {
+ enumStatement.append(indent + "enum " + cppClassName + " {" + endLine);
+
+ // populate
+ UMLClassifierListItemList ell = e->getFilteredList(Uml::ot_EnumLiteral);
+ for (UMLClassifierListItem *el=ell.first(); el ; ) {
+ enumStatement.append(indent+indent);
+ enumStatement.append(CodeGenerator::cleanName(el->getName()));
+ if ((el=ell.next()) != 0)
+ enumStatement.append(", "+endLine);
+ else
+ break;
+ enumStatement.append(endLine);
+ }
+ enumStatement.append(indent+"};");
+ isEnumeration = true;
+ }
+ namespaceBlock->addOrUpdateTaggedCodeBlockWithComments("enums", enumStatement, "", 0, false);
+ }
+
+ // CLASS DECLARATION BLOCK
+ //
+
+ // add the class declaration block to the namespace block.
+ CPPHeaderClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
+ namespaceBlock->addTextBlock(myClassDeclCodeBlock); // note: wont add if already present
+
+ // Is this really true?? hmm..
+ if(isEnumeration)
+ myClassDeclCodeBlock->setWriteOutText(false); // not written out IF its an enumeration class
+ else
+ myClassDeclCodeBlock->setWriteOutText(true);
+
+ //
+ // Main Sub-Blocks
+ //
+
+ // declare public, protected and private methods, attributes (fields).
+ // set the start text ONLY if this is the first time we created the objects.
+ bool createdPublicBlock = publicBlock == 0 ? true : false;
+ publicBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("publicBlock","Public stuff",0);
+ if (createdPublicBlock)
+ publicBlock->setStartText("public:");
+
+ bool createdProtBlock = protectedBlock == 0 ? true : false;
+ protectedBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("protectedBlock","Protected stuff",0);
+ if(createdProtBlock)
+ protectedBlock->setStartText("protected:");
+
+ bool createdPrivBlock = privateBlock == 0 ? true : false;
+ privateBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("privateBlock","Private stuff",0);
+ if(createdPrivBlock)
+ privateBlock->setStartText("private:");
+
+ //
+ // * CLASS FIELD declaration section
+ //
+
+ // setup/get/create the field declaration code block
+ //
+
+ // public fields: Update the comment: we only set comment to appear under the following conditions
+ HierarchicalCodeBlock * publicFieldDeclBlock = publicBlock->getHierarchicalCodeBlock("publicFieldsDecl", "Fields", 1);
+ CodeComment * pubFcomment = publicFieldDeclBlock->getComment();
+ if (!forcedoc && !hasclassFields )
+ pubFcomment->setWriteOutText(false);
+ else
+ pubFcomment->setWriteOutText(true);
+
+ // protected fields: Update the comment: we only set comment to appear under the following conditions
+ HierarchicalCodeBlock * protectedFieldDeclBlock = protectedBlock->getHierarchicalCodeBlock("protectedFieldsDecl", "Fields", 1);
+ CodeComment * protFcomment = protectedFieldDeclBlock->getComment();
+ if (!forcedoc && !hasclassFields )
+ protFcomment->setWriteOutText(false);
+ else
+ protFcomment->setWriteOutText(true);
+
+ // private fields: Update the comment: we only set comment to appear under the following conditions
+ HierarchicalCodeBlock * privateFieldDeclBlock = privateBlock->getHierarchicalCodeBlock("privateFieldsDecl", "Fields", 1);
+ CodeComment * privFcomment = privateFieldDeclBlock->getComment();
+ if (!forcedoc && !hasclassFields )
+ privFcomment->setWriteOutText(false);
+ else
+ privFcomment->setWriteOutText(true);
+
+
+ // now actually declare the fields within the appropriate HCodeBlock
+ //
+
+ // public
+ declareClassFields(staticPublicAttribClassFields, publicFieldDeclBlock);
+ declareClassFields(publicAttribClassFields, publicFieldDeclBlock);
+ declareClassFields(publicPlainAssocClassFields, publicFieldDeclBlock);
+ declareClassFields(publicAggregationClassFields, publicFieldDeclBlock);
+ declareClassFields(publicCompositionClassFields, publicFieldDeclBlock);
+
+ // protected
+ declareClassFields(staticProtectedAttribClassFields, protectedFieldDeclBlock);
+ declareClassFields(protectedAttribClassFields, protectedFieldDeclBlock);
+ declareClassFields(protPlainAssocClassFields, protectedFieldDeclBlock);
+ declareClassFields(protAggregationClassFields, protectedFieldDeclBlock);
+ declareClassFields(protCompositionClassFields, protectedFieldDeclBlock);
+
+ // private
+ declareClassFields(staticPrivateAttribClassFields, privateFieldDeclBlock);
+ declareClassFields(privateAttribClassFields, privateFieldDeclBlock);
+ declareClassFields(privPlainAssocClassFields, privateFieldDeclBlock);
+ declareClassFields(privAggregationClassFields, privateFieldDeclBlock);
+ declareClassFields(privCompositionClassFields, privateFieldDeclBlock);
+
+ //
+ // METHODS section
+ //
+
+ // get/create the method codeblock
+
+ // public methods
+ HierarchicalCodeBlock * pubMethodsBlock = publicBlock->getHierarchicalCodeBlock("pubMethodsBlock", "", 1);
+ CodeComment * pubMethodsComment = pubMethodsBlock->getComment();
+ // set conditions for showing this comment
+ if (!forcedoc && !hasclassFields && !hasOperationMethods)
+ pubMethodsComment->setWriteOutText(false);
+ else
+ pubMethodsComment->setWriteOutText(true);
+
+ // protected methods
+ HierarchicalCodeBlock * protMethodsBlock = protectedBlock->getHierarchicalCodeBlock("protMethodsBlock", "", 1);
+ CodeComment * protMethodsComment = protMethodsBlock->getComment();
+ // set conditions for showing this comment
+ if (!forcedoc && !hasclassFields && !hasOperationMethods)
+ protMethodsComment->setWriteOutText(false);
+ else
+ protMethodsComment->setWriteOutText(true);
+
+ // private methods
+ HierarchicalCodeBlock * privMethodsBlock = privateBlock->getHierarchicalCodeBlock("privMethodsBlock", "", 1);
+ CodeComment * privMethodsComment = privMethodsBlock->getComment();
+ // set conditions for showing this comment
+ if (!forcedoc && !hasclassFields && !hasOperationMethods)
+ privMethodsComment->setWriteOutText(false);
+ else
+ privMethodsComment->setWriteOutText(true);
+
+
+ // METHODS sub-section : constructor methods
+ //
+ CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();
+
+ // setup/get/create the constructor codeblocks
+
+ // public
+ pubConstructorBlock = pubMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
+ // special condiions for showing comment: only when autogenerateding empty constructors
+ // Although, we *should* check for other constructor methods too
+ CodeComment * pubConstComment = pubConstructorBlock->getComment();
+ if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
+ pubConstComment->setWriteOutText(false);
+ else
+ pubConstComment->setWriteOutText(true);
+
+ // protected
+ protConstructorBlock = protMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
+ // special condiions for showing comment: only when autogenerateding empty constructors
+ // Although, we *should* check for other constructor methods too
+ CodeComment * protConstComment = protConstructorBlock->getComment();
+ if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
+ protConstComment->setWriteOutText(false);
+ else
+ protConstComment->setWriteOutText(true);
+
+ // private
+ privConstructorBlock = privMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
+ // special condiions for showing comment: only when autogenerateding empty constructors
+ // Although, we *should* check for other constructor methods too
+ CodeComment * privConstComment = privConstructorBlock->getComment();
+ if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
+ privConstComment->setWriteOutText(false);
+ else
+ privConstComment->setWriteOutText(true);
+
+ // add/get the empty constructor. I guess since there is no
+ // meta-data to state what the scope of this method is, we will make it
+ // "public" as a default. This might present problems if the user wants
+ // to move the block into the "private" or "protected" blocks.
+ QString emptyConstStatement = cppClassName + " ( ) { }";
+
+ // search for this first in the entire document. IF not present, put
+ // it in the public constructor method block
+ TextBlock * emptyConstTb = findTextBlockByTag("emptyconstructor", true);
+ CodeBlockWithComments * emptyConstBlock = dynamic_cast<CodeBlockWithComments*>(emptyConstTb);
+ if(!emptyConstBlock)
+ emptyConstBlock = pubConstructorBlock->addOrUpdateTaggedCodeBlockWithComments("emptyconstructor", emptyConstStatement, "Empty Constructor", 1, false);
+
+ // Now, as an additional condition we only show the empty constructor block
+ // IF it was desired to be shown
+ if(!isInterface && pol->getAutoGenerateConstructors())
+ emptyConstBlock->setWriteOutText(true);
+ else
+ emptyConstBlock->setWriteOutText(false);
+
+
+ // METHODS subsection : ACCESSOR METHODS
+ //
+
+ // get/create the accessor codeblock
+
+ // public
+ HierarchicalCodeBlock * pubAccessorBlock = pubMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
+ // set conditions for showing section comment
+ CodeComment * pubAccessComment = pubAccessorBlock->getComment();
+ if (!forcedoc && !hasclassFields)
+ pubAccessComment->setWriteOutText(false);
+ else
+ pubAccessComment->setWriteOutText(true);
+
+ // protected
+ HierarchicalCodeBlock * protAccessorBlock = protMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
+ // set conditions for showing section comment
+ CodeComment * protAccessComment = protAccessorBlock->getComment();
+ if (!forcedoc && !hasclassFields)
+ protAccessComment->setWriteOutText(false);
+ else
+ protAccessComment->setWriteOutText(true);
+
+ // private
+ HierarchicalCodeBlock * privAccessorBlock = privMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
+ // set conditions for showing section comment
+ CodeComment * privAccessComment = privAccessorBlock->getComment();
+ // We've to copy the private accessorMethods to the public block
+ if (!forcedoc && !hasclassFields)
+ privAccessComment->setWriteOutText(false);
+ else
+ privAccessComment->setWriteOutText(true);
+
+ // now, 2 sub-sub sections in accessor block
+ // add/update accessor methods for attributes
+ HierarchicalCodeBlock * pubStaticAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubStaticAccessorMethods", "", 1);
+ HierarchicalCodeBlock * pubRegularAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubRegularAccessorMethods", "", 1);
+ pubStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
+ pubRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
+
+ HierarchicalCodeBlock * protStaticAccessors = protAccessorBlock->getHierarchicalCodeBlock("protStaticAccessorMethods", "", 1);
+ HierarchicalCodeBlock * protRegularAccessors = protAccessorBlock->getHierarchicalCodeBlock("protRegularAccessorMethods", "", 1);
+ protStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
+ protRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
+
+ HierarchicalCodeBlock * privStaticAccessors = privAccessorBlock->getHierarchicalCodeBlock("privStaticAccessorMethods", "", 1);
+ HierarchicalCodeBlock * privRegularAccessors = privAccessorBlock->getHierarchicalCodeBlock("privRegularAccessorMethods", "", 1);
+ privStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
+ privRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
+
+ // now add in accessors as appropriate
+
+ // public stuff
+ pubStaticAccessors->addCodeClassFieldMethods(staticPublicAttribClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(publicAttribClassFields);
+
+ // generate accessors as public
+ if (policy && policy->getAccessorsArePublic())
+ {
+ pubRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
+ }
+
+ pubRegularAccessors->addCodeClassFieldMethods(publicPlainAssocClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(publicAggregationClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(publicCompositionClassFields);
+
+ // protected stuff
+ protStaticAccessors->addCodeClassFieldMethods(staticProtectedAttribClassFields);
+
+ // accessors are public so we don't have to create it here
+ if (policy && !policy->getAccessorsArePublic())
+ protRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
+
+ protRegularAccessors->addCodeClassFieldMethods(protPlainAssocClassFields);
+ protRegularAccessors->addCodeClassFieldMethods(protAggregationClassFields);
+ protRegularAccessors->addCodeClassFieldMethods(protCompositionClassFields);
+
+ // private stuff
+ privStaticAccessors->addCodeClassFieldMethods(staticPrivateAttribClassFields);
+
+ // accessors are public so we don't have to create it here
+ if (policy && !policy->getAccessorsArePublic())
+ privRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
+
+ privRegularAccessors->addCodeClassFieldMethods(privPlainAssocClassFields);
+ privRegularAccessors->addCodeClassFieldMethods(privAggregationClassFields);
+ privRegularAccessors->addCodeClassFieldMethods(privCompositionClassFields);
+
+
+ // METHODS subsection : Operation methods (e.g. methods derive from operations but which arent constructors)
+ //
+
+ // setup/get/create the operations codeblock
+
+ // public
+ pubOperationsBlock = pubMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
+ // set conditions for showing section comment
+ CodeComment * pubOcomment = pubOperationsBlock->getComment();
+ if (!forcedoc && !hasOperationMethods )
+ pubOcomment->setWriteOutText(false);
+ else
+ pubOcomment->setWriteOutText(true);
+
+ //protected
+ protOperationsBlock = protMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
+ // set conditions for showing section comment
+ CodeComment * protOcomment = protOperationsBlock->getComment();
+ if (!forcedoc && !hasOperationMethods )
+ protOcomment->setWriteOutText(false);
+ else
+ protOcomment->setWriteOutText(true);
+
+ //private
+ privOperationsBlock = privMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
+ // set conditions for showing section comment
+ CodeComment * privOcomment = privOperationsBlock->getComment();
+ if (!forcedoc && !hasOperationMethods )
+ privOcomment->setWriteOutText(false);
+ else
+ privOcomment->setWriteOutText(true);
+
+ // Operations
+ //
+ // nothing to do here.. "updateOperations" in parent class puts things
+ // in the right place using the "addCodeOperation" method we defined in this class
+
+ // FINISH up with hash def block close
+ QString defTextEnd = "#endif //"+hashDefine + "_H";
+ addOrUpdateTaggedCodeBlockWithComments("hashDefBlockEnd", defTextEnd, "", 0, false);
+
+}
+
+
+#include "cppheadercodedocument.moc"
diff --git a/umbrello/umbrello/codegenerators/cppheadercodedocument.h b/umbrello/umbrello/codegenerators/cppheadercodedocument.h
new file mode 100644
index 00000000..ca75627f
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodedocument.h
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Aug 28 2003
+ */
+
+#ifndef CPPHEADERCODEDOCUMENT_H
+#define CPPHEADERCODEDOCUMENT_H
+
+#include <qstring.h>
+
+#include "../codeclassfieldlist.h"
+#include "../classifiercodedocument.h"
+#include "../hierarchicalcodeblock.h"
+#include "classifierinfo.h"
+
+class CPPHeaderClassDeclarationBlock;
+
+/**
+ * class CPPHeaderCodeDocument
+ * A CPP UMLClassifier Header Code Document.
+ */
+
+class CPPHeaderCodeDocument : public ClassifierCodeDocument
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ CPPHeaderCodeDocument (UMLClassifier * classifier);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPHeaderCodeDocument ( );
+
+ /** add a code operation to this cpp classifier code document.
+ * @return bool which is true IF the code operation was added successfully
+ */
+ bool addCodeOperation (CodeOperation * op );
+
+ /**
+ * Save the XMI representation of this object
+ */
+ //virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+protected:
+
+ // reset/clear our inventory of textblocks in this document
+ void resetTextBlocks();
+
+ /**
+ * need to overwrite this for cpp header since we need to pick up the
+ * header class declaration block.
+ */
+ virtual void loadChildTextBlocksFromNode ( QDomElement & root);
+
+ void addOrUpdateCodeClassFieldMethodsInCodeBlock(CodeClassFieldList &list, CPPHeaderClassDeclarationBlock * codeBlock);
+
+ /**
+ * create a new code comment. IN this case it is a CPPCodeDocumentation object.
+ */
+ CodeComment * newCodeComment ( );
+
+ void updateContent();
+
+private:
+
+ CPPHeaderClassDeclarationBlock * classDeclCodeBlock;
+
+ HierarchicalCodeBlock * publicBlock;
+ HierarchicalCodeBlock * privateBlock;
+ HierarchicalCodeBlock * protectedBlock;
+
+ HierarchicalCodeBlock * namespaceBlock;
+
+ HierarchicalCodeBlock * pubConstructorBlock;
+ HierarchicalCodeBlock * protConstructorBlock;
+ HierarchicalCodeBlock * privConstructorBlock;
+
+ HierarchicalCodeBlock * pubOperationsBlock;
+ HierarchicalCodeBlock * privOperationsBlock;
+ HierarchicalCodeBlock * protOperationsBlock;
+
+ /**
+ *
+ */
+ CPPHeaderClassDeclarationBlock * getClassDecl();
+
+};
+
+#endif // CPPHEADERCODEDOCUMENT_H
diff --git a/umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp b/umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp
new file mode 100644
index 00000000..ca8ad727
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp
@@ -0,0 +1,175 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#include "cppheadercodeoperation.h"
+
+#include "cppcodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppheadercodedocument.h"
+#include "cppcodedocumentation.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+CPPHeaderCodeOperation::CPPHeaderCodeOperation
+ ( CPPHeaderCodeDocument * doc, UMLOperation *parent, const QString & body, const QString & comment )
+ : CodeOperation (doc, parent, body, comment)
+{
+ // lets not go with the default comment and instead use
+ // full-blown cpp documentation object instead
+ setComment(new CPPCodeDocumentation(doc));
+
+ // these things never change..
+ setOverallIndentationLevel(1);
+
+ setText("");
+ setStartMethodText("");
+ setEndMethodText("");
+
+ updateMethodDeclaration();
+ updateContent();
+
+}
+
+CPPHeaderCodeOperation::~CPPHeaderCodeOperation ( ) { }
+
+// Other methods
+//
+
+// we basically just want to know whether or not to print out
+// the body of the operation.
+// In C++ if the operations are inline, then we DO print out
+// the body text.
+void CPPHeaderCodeOperation::updateContent( )
+{
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ bool isInlineMethod = policy->getOperationsAreInline( );
+
+ if(isInlineMethod)
+ setText(""); // change whatever it is to "";
+}
+
+// we basically want to update the doc and start text of this method
+void CPPHeaderCodeOperation::updateMethodDeclaration()
+{
+ ClassifierCodeDocument *ccd = dynamic_cast<ClassifierCodeDocument*>(getParentDocument());
+ bool isInterface = ccd->parentIsInterface();
+ UMLOperation * o = getParentOperation();
+
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ bool isInlineMethod = policy->getOperationsAreInline( );
+
+ QString endLine = getNewLineEndingChars();
+
+ // first, the comment on the operation, IF its autogenerated/empty
+ QString comment = o->getDoc();
+ if(comment.isEmpty() && getContentType() == CodeBlock::AutoGenerated)
+ {
+ UMLAttributeList parameters = o->getParmList();
+ for(UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) {
+ comment += endLine + "@param " + iterator.current()->getName() + ' ';
+ comment += iterator.current()->getDoc();
+ }
+ getComment()->setText(comment);
+ }
+
+ // no return type for constructors
+ QString methodReturnType = o->getTypeName();
+ QString methodName = o->getName();
+ QString paramStr = QString("");
+
+ // assemble parameters
+ UMLAttributeList list = getParentOperation()->getParmList();
+ int nrofParam = list.count();
+ int paramNum = 0;
+ for(UMLAttribute* parm = list.first(); parm; parm=list.next())
+ {
+ QString rType = parm->getTypeName();
+ QString paramName = parm->getName();
+ QString initialValue = parm->getInitialValue();
+ paramStr += rType + ' ' + paramName;
+ if(!initialValue.isEmpty())
+ paramStr += '=' + initialValue;
+
+ paramNum++;
+
+ if (paramNum != nrofParam )
+ paramStr += ", ";
+ }
+
+ // if an operation isn't a constructor or a destructor and it has no return type
+ if (o->isLifeOperation()) // constructor/destructor has no type
+ methodReturnType = "";
+ else if (methodReturnType.isEmpty()) // this operation should be 'void'
+ methodReturnType = QString("void");
+
+ // set start/end method text
+ QString prototype = methodReturnType+' '+methodName+" ("+paramStr+')';
+
+ QString startText;
+ QString endText;
+
+ applyStereotypes (prototype, o, isInlineMethod, isInterface, startText, endText);
+
+ setStartMethodText(prototype+startText);
+ setEndMethodText(endText);
+}
+
+int CPPHeaderCodeOperation::lastEditableLine() {
+ ClassifierCodeDocument * doc = dynamic_cast<ClassifierCodeDocument*>(getParentDocument());
+ UMLOperation * o = getParentOperation();
+ if(doc->parentIsInterface() || o->getAbstract())
+ return -1; // very last line is NOT editable as its a one-line declaration w/ no body in
+ // an interface.
+ return 0;
+}
+
+void CPPHeaderCodeOperation::applyStereotypes (QString& prototype, UMLOperation * pOp,
+ bool inlinePolicy, bool interface,
+ QString& start, QString& end)
+{
+ // if the class is an interface, all methods will be declared as pure
+ // virtual functions
+ start = (inlinePolicy ? " {" : ";");
+ end = (inlinePolicy ? "}" : "");
+ if (pOp->getConst())
+ prototype += " const";
+ if (interface || pOp->getAbstract()) {
+ // constructor can't be virtual or abstract
+ if (!pOp->isLifeOperation()) {
+ prototype = "virtual " + prototype + " = 0";
+ if (inlinePolicy) {
+ start = ";";
+ end = "";
+ }
+ }
+ } // constructors could not be declared as static
+ else if (pOp->getStatic() && !pOp->isLifeOperation()) {
+ prototype = "static " + prototype;
+ }
+ // apply the stereotypes
+ if (!pOp->getStereotype().isEmpty()) {
+ if ((pOp->getStereotype() == "friend") || (pOp->getStereotype(false) == "virtual")) {
+ if (!pOp->isLifeOperation() && !(interface || pOp->getAbstract()) && !pOp->getStatic())
+ prototype = pOp->getStereotype() + ' ' + prototype;
+ }
+ }
+}
+
+#include "cppheadercodeoperation.moc"
diff --git a/umbrello/umbrello/codegenerators/cppheadercodeoperation.h b/umbrello/umbrello/codegenerators/cppheadercodeoperation.h
new file mode 100644
index 00000000..1d4fbca7
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodeoperation.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+
+#ifndef CPPHEADERCODEOPERATION_H
+#define CPPHEADERCODEOPERATION_H
+
+#include <qstring.h>
+#include "../codeoperation.h"
+
+class CPPHeaderCodeDocument;
+
+class CPPHeaderCodeOperation : virtual public CodeOperation
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ CPPHeaderCodeOperation ( CPPHeaderCodeDocument * doc, UMLOperation * op,
+ const QString & body = "", const QString & comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPHeaderCodeOperation ( );
+
+ virtual int lastEditableLine();
+
+protected:
+
+ virtual void updateMethodDeclaration();
+ virtual void updateContent( );
+
+ /**
+ * Check to see if we have a valid stereotype to apply in the operation
+ */
+ virtual void applyStereotypes (QString&, UMLOperation *, bool, bool, QString&, QString&);
+
+};
+
+#endif // CPPHEADERCODEOPERATION_H
diff --git a/umbrello/umbrello/codegenerators/cppmakecodedocument.cpp b/umbrello/umbrello/codegenerators/cppmakecodedocument.cpp
new file mode 100644
index 00000000..d13152b4
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppmakecodedocument.cpp
@@ -0,0 +1,78 @@
+
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Tue Jun 24 2003
+ */
+
+#include "cppcodegenerator.h"
+
+#include <qregexp.h>
+
+const char * CPPMakefileCodeDocument::DOCUMENT_ID_VALUE = "Makefile_DOC";
+
+// Constructors/Destructors
+//
+
+CPPMakefileCodeDocument::CPPMakefileCodeDocument ( )
+{
+ setFileName("Makefile"); // default name
+ setFileExtension("");
+ setID(DOCUMENT_ID_VALUE); // default id tag for this type of document
+}
+
+CPPMakefileCodeDocument::~CPPMakefileCodeDocument ( ) { }
+
+//
+// Methods
+//
+
+// Other methods
+//
+
+// we add in our code blocks that describe how to generate
+// the project here...
+void CPPMakefileCodeDocument::updateContent( ) {
+ // FIX : fill in content
+}
+
+/**
+ * @return QString
+ */
+QString CPPMakefileCodeDocument::toString ( ) {
+ return "# cpp make build document";
+}
+
+// We overwritten by CPP language implementation to get lowercase path
+QString CPPMakefileCodeDocument::getPath ( )
+{
+
+ QString path = getPackage();
+
+ // Replace all white spaces with blanks
+ path.simplifyWhiteSpace();
+
+ // Replace all blanks with underscore
+ path.replace(QRegExp(" "), "_");
+
+ path.replace(QRegExp("\\."),"/");
+ path.replace(QRegExp("::"),"/");
+
+ path.lower();
+
+ return path;
+
+}
+
+
+#include "cppmakecodedocument.moc"
diff --git a/umbrello/umbrello/codegenerators/cppmakecodedocument.h b/umbrello/umbrello/codegenerators/cppmakecodedocument.h
new file mode 100644
index 00000000..98efe272
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppmakecodedocument.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Tue Jun 24 2003
+ */
+
+
+
+#ifndef CPPMAKECODEDOCUMENT_H
+#define CPPMAKECODEDOCUMENT_H
+
+#include "../codedocument.h"
+#include <qstring.h>
+
+/**
+ * class CPPMakefileCodeDocument
+ * Represents
+ */
+
+class CPPMakefileCodeDocument : public CodeDocument
+{
+ Q_OBJECT
+public:
+
+ static const char * DOCUMENT_ID_VALUE;
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ CPPMakefileCodeDocument ( );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPMakefileCodeDocument ( );
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+ QString getPath ( );
+
+ void updateContent();
+
+protected:
+
+private:
+
+
+
+};
+
+#endif // CPPMAKECODEDOCUMENT_H
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.cpp b/umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.cpp
new file mode 100644
index 00000000..da2a86cb
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.cpp
@@ -0,0 +1,169 @@
+/***************************************************************************
+ * *
+ * 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 : Fri Aug 31 2003
+ */
+
+// own header
+#include "cppsourcecodeaccessormethod.h"
+
+// qt/kde includes
+#include <kdebug.h>
+
+// local includes
+#include "../attribute.h"
+#include "../classifiercodedocument.h"
+#include "../umlobject.h"
+#include "../umlrole.h"
+#include "../uml.h"
+
+#include "cppcodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppcodeclassfield.h"
+#include "cppcodedocumentation.h"
+
+// Constructors/Destructors
+//
+
+CPPSourceCodeAccessorMethod::CPPSourceCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type)
+ : CodeAccessorMethod ( field )
+{
+ setType(type);
+ setEndMethodText("}");
+}
+
+void CPPSourceCodeAccessorMethod::update()
+{
+ updateMethodDeclaration();
+ updateContent();
+}
+
+CPPSourceCodeAccessorMethod::~CPPSourceCodeAccessorMethod ( ) { }
+
+// Other
+//
+
+// we basically want to update the body of this method
+void CPPSourceCodeAccessorMethod::updateContent( )
+{
+ CodeClassField * parentField = getParentClassField();
+ CPPCodeClassField * cppfield = dynamic_cast<CPPCodeClassField*>(parentField);
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ bool isInlineMethod = policy->getAccessorsAreInline( );
+
+ QString variableName = cppfield->getFieldName();
+ QString itemClassName = cppfield->getTypeName();
+ QString text;
+
+ if(isInlineMethod) {
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ text = policy->getVectorMethodAppend(variableName, itemClassName);
+ break;
+ case CodeAccessorMethod::REMOVE:
+ text = policy->getVectorMethodRemove(variableName, itemClassName);
+ break;
+ case CodeAccessorMethod::SET:
+ text = variableName+" = value;";
+ break;
+ case CodeAccessorMethod::LIST:
+ case CodeAccessorMethod::GET:
+ default:
+ text = "return "+variableName+';';
+ break;
+ }
+ }
+
+ setText(text);
+}
+
+// we basically want to update the start text of this method
+void CPPSourceCodeAccessorMethod::updateMethodDeclaration()
+{
+
+ CodeClassField * parentField = getParentClassField();
+ ClassifierCodeDocument * doc = parentField->getParentDocument();
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ CPPCodeClassField * cppfield = dynamic_cast<CPPCodeClassField*>(parentField);
+ UMLClassifier * c = doc->getParentClassifier();
+
+ bool isInlineMethod = policy->getAccessorsAreInline( );
+
+ QString vectorClassName = policy->getVectorClassName();
+ QString fieldName = cppfield->getFieldName();
+ QString fieldType = cppfield->getTypeName();
+ QString objectType = cppfield->getListObjectType();
+ if(objectType.isEmpty())
+ objectType = fieldName;
+
+ QString methodReturnType = "void";
+ QString methodName;
+ QString methodParams;
+ QString headerText;
+ QString className = CodeGenerator::cleanName(c->getName());
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ methodName = "add_"+fieldType;
+ methodReturnType = "void";
+ methodParams = objectType+" value ";
+ headerText = "Add a "+fieldName+" object to the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return void";
+ break;
+ case CodeAccessorMethod::REMOVE:
+ methodName = "remove_"+fieldType;
+ methodParams = objectType+" value ";
+ methodReturnType = "void";
+ headerText = "Remove a "+fieldName+" object from the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return void";
+ break;
+ case CodeAccessorMethod::LIST:
+ methodName = "get_"+fieldType+"_list";
+ methodReturnType = vectorClassName;
+ headerText = "Get the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return "+vectorClassName+"with list of objects";
+ break;
+ case CodeAccessorMethod::SET:
+ methodName = "set_"+fieldName;
+ methodParams = fieldType+" value ";
+ methodReturnType = "void";
+ headerText = "Set the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@param value the value of "+fieldName;
+ break;
+ case CodeAccessorMethod::GET:
+ default:
+ methodName = "get_"+fieldName;
+ methodReturnType = fieldType;
+ headerText = "Get the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@return the value of "+fieldName;
+ break;
+ }
+
+ // set header
+ CPPCodeDocumentation * header = new CPPCodeDocumentation(doc);
+ if(!getParentObject()->getDoc().isEmpty())
+ header->setText(headerText);
+ setComment(header);
+
+ // set start method text (EndText never changes)
+ setStartMethodText(methodReturnType+' '+className+"::"+methodName+" ("+methodParams+')' + " {");
+
+ setOverallIndentationLevel(0);
+
+ // these ONLY appear if they arent inline
+ if(isInlineMethod)
+ setWriteOutText(false);
+
+}
+
+
+
+#include "cppsourcecodeaccessormethod.moc"
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.h b/umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.h
new file mode 100644
index 00000000..60d9c369
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodeaccessormethod.h
@@ -0,0 +1,57 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Fri Jun 20 2003
+ */
+
+#ifndef CPPSOURCECODEACCESSORMETHOD_H
+#define CPPSOURCECODEACCESSORMETHOD_H
+
+#include <qstring.h>
+
+#include "../codeaccessormethod.h"
+
+class CodeClassField;
+
+class CPPSourceCodeAccessorMethod : public CodeAccessorMethod
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ CPPSourceCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPSourceCodeAccessorMethod ( );
+
+ /**
+ * Must be called before this object is usable
+ */
+ void update();
+
+protected:
+
+ virtual void updateMethodDeclaration();
+ virtual void updateContent();
+
+private:
+
+};
+
+#endif // CPPSOURCECODEACCESSORMETHOD_H
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.cpp b/umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.cpp
new file mode 100644
index 00000000..7d60b1c3
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.cpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#include "cppsourcecodeclassfielddeclarationblock.h"
+
+#include "cppcodeclassfield.h"
+#include "../model_utils.h"
+
+// Constructors/Destructors
+//
+
+CPPSourceCodeClassFieldDeclarationBlock::CPPSourceCodeClassFieldDeclarationBlock ( CodeClassField * parent )
+ : CodeClassFieldDeclarationBlock ( parent )
+{
+ setOverallIndentationLevel(1);
+ updateContent();
+}
+
+CPPSourceCodeClassFieldDeclarationBlock::~CPPSourceCodeClassFieldDeclarationBlock ( ) { }
+
+//
+// Methods
+//
+
+// Other methods
+//
+
+/**
+ */
+void CPPSourceCodeClassFieldDeclarationBlock::updateContent( )
+{
+
+ /*
+ CodeClassField * cf = getParentClassField();
+ ClassifierCodeDocument * doc = cf->getParentDocument();
+ CPPCodeClassField * jcf = dynamic_cast<CPPCodeClassField*>(cf);
+ CPPClassifierCodeDocument* jdoc = dynamic_cast<CPPClassifierCodeDocument*>(doc);
+
+ // Set the comment
+ QString notes = getParentObject()->getDoc();
+ getComment()->setText(notes);
+
+ // Set the body
+ QString staticValue = getParentObject()->getStatic() ? "static " : "";
+ QString scopeStr = getParentObject()->getVisibility().toString();
+
+ QString typeName = jcf->getTypeName();
+ QString fieldName = jcf->getFieldName();
+ QString initialV = jcf->getInitialValue();
+
+ QString body = staticValue+scopeStr+" "+typeName+" "+fieldName;
+ if (!initialV.isEmpty())
+ body.append(" = " + initialV);
+ setText(body+";");
+ */
+ setText("FIX ME;");
+
+
+}
+
+
+
+#include "cppsourcecodeclassfielddeclarationblock.moc"
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.h b/umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.h
new file mode 100644
index 00000000..e5b908a0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodeclassfielddeclarationblock.h
@@ -0,0 +1,51 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#ifndef CPPSOURCECODECLASSFIELDDECLARATIONBLOCK_H
+#define CPPSOURCECODECLASSFIELDDECLARATIONBLOCK_H
+
+#include <qstring.h>
+
+#include "../codeclassfielddeclarationblock.h"
+
+class CPPSourceCodeClassFieldDeclarationBlock : public CodeClassFieldDeclarationBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ CPPSourceCodeClassFieldDeclarationBlock ( CodeClassField * parent );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPSourceCodeClassFieldDeclarationBlock ( );
+
+protected:
+
+ // this will be called by syncToParent whenever the parent object is "modified"
+ void updateContent ( );
+
+private:
+
+
+};
+
+#endif // CPPSOURCECODECLASSFIELDDECLARATIONBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodedocument.cpp b/umbrello/umbrello/codegenerators/cppsourcecodedocument.cpp
new file mode 100644
index 00000000..be054937
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodedocument.cpp
@@ -0,0 +1,168 @@
+/***************************************************************************
+ * *
+ * 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) 2003-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Aug 28 2003
+ */
+
+/**
+ We carve the CPP document up into 2 documents, "source" and "header".
+ The sections of each are as follows:
+
+ * header
+ * includes
+ * constructor methods
+ * all other methods
+
+*/
+
+// own header
+#include "cppsourcecodedocument.h"
+// qt/kde includes
+#include <kdebug.h>
+#include <qregexp.h>
+// app includes
+#include "cppcodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppcodedocumentation.h"
+#include "cppcodeclassfield.h"
+#include "cppsourcecodeclassfielddeclarationblock.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+CPPSourceCodeDocument::CPPSourceCodeDocument ( UMLClassifier * concept )
+ : ClassifierCodeDocument (concept) {
+ init ( );
+}
+
+CPPSourceCodeDocument::~CPPSourceCodeDocument ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+QString CPPSourceCodeDocument::getCPPClassName (const QString &name) {
+ return CodeGenerator::cleanName(name);
+}
+
+// Initialize this cpp classifier code document
+void CPPSourceCodeDocument::init ( ) {
+
+ setFileExtension(".cpp");
+
+ methodsBlock = 0;
+ constructorBlock = 0;
+
+ //initCodeClassFields(); // this is dubious because it calls down to
+ // CodeGenFactory::newCodeClassField(this)
+ // but "this" is still in construction at that time.
+
+ // this will call updateContent() as well as other things that sync our document.
+ //synchronize();
+}
+
+/**
+ * @param op
+ */
+// in the vannilla version, we just tack all operations on the end
+// of the document
+bool CPPSourceCodeDocument::addCodeOperation (CodeOperation * op ) {
+
+ if(!op->getParentOperation()->isLifeOperation())
+ {
+ return methodsBlock->addTextBlock(op);
+ } else
+ return constructorBlock->addTextBlock(op);
+}
+
+
+void CPPSourceCodeDocument::resetTextBlocks()
+{
+
+ // all special pointers need to be zero'd out.
+ methodsBlock = 0;
+ constructorBlock = 0;
+
+ // now do the traditional release of child text blocks
+ ClassifierCodeDocument::resetTextBlocks();
+
+}
+
+// This method will cause the class to rebuild its text representation.
+// based on the parent classifier object.
+// For any situation in which this is called, we are either building the code
+// document up, or replacing/regenerating the existing auto-generated parts. As
+// such, we will want to insert everything we reasonably will want
+// during creation. We can set various parts of the document (esp. the
+// comments) to appear or not, as needed.
+void CPPSourceCodeDocument::updateContent( )
+{
+
+ // Gather info on the various fields and parent objects of this class...
+ //UMLClassifier * c = getParentClassifier();
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+
+ // first, set the global flag on whether or not to show classfield info
+ CodeClassFieldList * cfList = getCodeClassFieldList();
+ for(CodeClassField * field = cfList->first(); field; field = cfList->next())
+ field->setWriteOutMethods(policy->getAutoGenerateAccessors());
+
+ // attribute-based ClassFields
+ // we do it this way to have the static fields sorted out from regular ones
+ CodeClassFieldList staticAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true);
+ CodeClassFieldList attribClassFields = getSpecificClassFields (CodeClassField::Attribute, false);
+ // association-based ClassFields
+ // don't care if they are static or not..all are lumped together
+ CodeClassFieldList plainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation );
+ CodeClassFieldList aggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation );
+ CodeClassFieldList compositionClassFields = getSpecificClassFields ( CodeClassField::Composition );
+
+ // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
+ //
+
+ // INCLUDE CODEBLOCK
+ QString includeStatement = "";
+ // Include own header file
+ QString myOwnName( getParentClassifier()->getName() );
+ includeStatement.append("#include \""+CodeGenerator::cleanName(myOwnName.lower())+".h\""+endLine);
+ CodeBlockWithComments * iblock = addOrUpdateTaggedCodeBlockWithComments("includes", includeStatement, QString::null, 0, false);
+ iblock->setWriteOutText(true);
+
+ // After the includes we have just 2 big blocks basically, the "constructor" block and the
+ // block for the rest of our methods (operations + accessors)
+
+ constructorBlock = getHierarchicalCodeBlock("constructionMethodsBlock", "Constructors/Destructors", 0);
+ methodsBlock = getHierarchicalCodeBlock("otherMethodsBlock", "Methods", 0);
+
+ // add accessors to the methods block
+ methodsBlock->addCodeClassFieldMethods(staticAttribClassFields);
+ methodsBlock->addCodeClassFieldMethods(attribClassFields);
+ methodsBlock->addCodeClassFieldMethods(plainAssocClassFields);
+ methodsBlock->addCodeClassFieldMethods(aggregationClassFields);
+ methodsBlock->addCodeClassFieldMethods(compositionClassFields);
+
+ // constructors and other operations are handled by the "addCodeOperation" method above.
+
+}
+
+
+#include "cppsourcecodedocument.moc"
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodedocument.h b/umbrello/umbrello/codegenerators/cppsourcecodedocument.h
new file mode 100644
index 00000000..8ca59c95
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodedocument.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Aug 28 2003
+ */
+
+#ifndef CPPSOURCECODEDOCUMENT_H
+#define CPPSOURCECODEDOCUMENT_H
+
+#include <qstring.h>
+
+#include "../classifiercodedocument.h"
+#include "../hierarchicalcodeblock.h"
+#include "classifierinfo.h"
+
+/**
+ * class CPPSourceCodeDocument
+ * A CPP UMLClassifier Source Code Document.
+ */
+
+class CPPSourceCodeDocument : public ClassifierCodeDocument
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ CPPSourceCodeDocument (UMLClassifier * classifier);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPSourceCodeDocument ( );
+
+ /** add a code operation to this cpp classifier code document.
+ * @return bool which is true IF the code operation was added successfully
+ */
+ bool addCodeOperation (CodeOperation * op );
+
+protected:
+
+ // reset/clear our inventory of textblocks in this document
+ void resetTextBlocks();
+
+ // a little utility method to save us some work
+ QString getCPPClassName (const QString &name);
+
+ void updateContent();
+
+private:
+
+ HierarchicalCodeBlock * constructorBlock;
+ HierarchicalCodeBlock * methodsBlock;
+
+ void init ( );
+
+};
+
+#endif // CPPSOURCECODEDOCUMENT_H
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp b/umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp
new file mode 100644
index 00000000..0d8115b6
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp
@@ -0,0 +1,193 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+#include "cppsourcecodeoperation.h"
+
+#include "cppcodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppsourcecodedocument.h"
+#include "cppcodedocumentation.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+CPPSourceCodeOperation::CPPSourceCodeOperation ( CPPSourceCodeDocument * doc, UMLOperation *parent, const QString & body, const QString & comment )
+ : CodeOperation (doc, parent, body, comment)
+{
+ // lets not go with the default comment and instead use
+ // full-blown cpp documentation object instead
+ setComment(new CPPCodeDocumentation(doc));
+
+ // these things never change..
+ setOverallIndentationLevel(0);
+ setEndMethodText("}");
+
+ //updateMethodDeclaration();
+ CodeGenPolicyExt * pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ UMLClassifier * c = doc->getParentClassifier();
+ UMLOperation * o = getParentOperation();
+ bool isInterface = doc->parentIsInterface();
+ bool isInlineMethod = policy->getOperationsAreInline( );
+
+ // first, the comment on the operation
+ QString cmnt = o->getDoc();
+ getComment()->setText(cmnt);
+
+ QString returnType = o->getTypeName();
+ QString methodName = o->getName();
+ QString paramStr = QString("");
+ QString className = CodeGenerator::cleanName(c->getName());
+
+ // assemble parameters
+ UMLAttributeList list = getParentOperation()->getParmList();
+ int nrofParam = list.count();
+ int paramNum = 0;
+ for(UMLAttribute* parm = list.first(); parm; parm=list.next())
+ {
+ QString rType = parm->getTypeName();
+ QString paramName = parm->getName();
+ paramStr += rType + ' ' + paramName;
+ paramNum++;
+
+ if (paramNum != nrofParam )
+ paramStr += ", ";
+ }
+
+ // no return type for constructors/destructors
+ if (o->isLifeOperation())
+ returnType = "";
+ // if an operation isn't a constructor/destructor and it has no return type
+ // this operation should be void
+ else if (returnType.isEmpty())
+ returnType = QString("void");
+
+ QString startText = returnType + ' ';
+
+ // if a property has a friend stereotype, the operation should
+ // not be a class name
+ if (o->getStereotype() != "friend")
+ startText += className + "::";
+ startText += methodName + " (" + paramStr + ')';
+ if (o->getConst())
+ startText += " const";
+ startText += " {";
+
+ setStartMethodText(startText);
+
+ // Only write this out if its a child of an interface OR is abstract.
+ // and its not inline
+ if(isInterface || o->getAbstract() || isInlineMethod)
+ {
+ setWriteOutText(false);
+ } else {
+ setWriteOutText(true);
+ }
+
+
+ updateContent();
+}
+
+CPPSourceCodeOperation::~CPPSourceCodeOperation ( ) { }
+
+// Other methods
+//
+
+// we basically just want to know whether or not to print out
+// the body of the operation.
+// In C++ if the operations are inline, then we DONT print out
+// the body text.
+void CPPSourceCodeOperation::updateContent( )
+{
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ bool isInlineMethod = policy->getOperationsAreInline();
+
+ if(!isInlineMethod)
+ setText(""); // change whatever it is to "";
+
+}
+
+// we basically want to update the doc and start text of this method
+void CPPSourceCodeOperation::updateMethodDeclaration()
+{
+
+ CPPSourceCodeDocument * doc = dynamic_cast<CPPSourceCodeDocument*>(getParentDocument());
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
+ UMLClassifier * c = doc->getParentClassifier();
+ UMLOperation * o = getParentOperation();
+ bool isInterface = doc->parentIsInterface();
+ bool isInlineMethod = policy->getOperationsAreInline( );
+
+ // first, the comment on the operation
+ QString comment = o->getDoc();
+ getComment()->setText(comment);
+
+ QString returnType = o->getTypeName();
+ QString methodName = o->getName();
+ QString paramStr = QString("");
+ QString className = CodeGenerator::cleanName(c->getName());
+
+ // assemble parameters
+ UMLAttributeList list = getParentOperation()->getParmList();
+ int nrofParam = list.count();
+ int paramNum = 0;
+ for(UMLAttribute* parm = list.first(); parm; parm=list.next())
+ {
+ QString rType = parm->getTypeName();
+ QString paramName = parm->getName();
+ paramStr += rType + ' ' + paramName;
+ paramNum++;
+
+ if (paramNum != nrofParam )
+ paramStr += ", ";
+ }
+
+ // no return type for constructors/destructors
+ if (o->isLifeOperation())
+ returnType = "";
+ // if an operation isn't a constructor/destructor and it has no return type
+ // this operation should be void
+ else if (returnType.isEmpty())
+ returnType = QString("void");
+
+ QString startText = returnType + ' ';
+
+ // if a property has a friend stereotype, the operation should
+ // not be a class name
+ if (o->getStereotype() != "friend")
+ startText += className + "::";
+ startText += methodName + " (" + paramStr + ')';
+ if (o->getConst())
+ startText += " const";
+ startText += " {";
+
+ setStartMethodText(startText);
+
+ // Only write this out if its a child of an interface OR is abstract.
+ // and its not inline
+ if(isInterface || o->getAbstract() || isInlineMethod)
+ {
+ setWriteOutText(false);
+ } else {
+ setWriteOutText(true);
+ }
+
+}
+
+#include "cppsourcecodeoperation.moc"
diff --git a/umbrello/umbrello/codegenerators/cppsourcecodeoperation.h b/umbrello/umbrello/codegenerators/cppsourcecodeoperation.h
new file mode 100644
index 00000000..e2112178
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppsourcecodeoperation.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 1 2003
+ */
+
+
+#ifndef CPPSOURCECODEOPERATION_H
+#define CPPSOURCECODEOPERATION_H
+
+#include <qstring.h>
+#include "../codeoperation.h"
+
+class CPPSourceCodeDocument;
+
+class CPPSourceCodeOperation : virtual public CodeOperation
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ CPPSourceCodeOperation ( CPPSourceCodeDocument * doc, UMLOperation * op, const QString & body = "", const QString & comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~CPPSourceCodeOperation ( );
+
+protected:
+
+ virtual void updateMethodDeclaration();
+ virtual void updateContent( );
+
+};
+
+#endif // CPPSOURCECODEOPERATION_H
diff --git a/umbrello/umbrello/codegenerators/cppwriter.cpp b/umbrello/umbrello/codegenerators/cppwriter.cpp
new file mode 100644
index 00000000..b24c12b0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppwriter.cpp
@@ -0,0 +1,1283 @@
+/***************************************************************************
+ * cppwriter.cpp - description *
+ * This is the "old" code generator that does not support code editing *
+ * in the Modeller but uses significantly less file space because the *
+ * source code is not replicated in the XMI file. *
+ * *
+ * copyright : (C) 2003 Brian Thomas brian.thomas@gsfc.nasa.gov *
+ * (C) 2004-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ * *
+ ***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// own header
+#include "cppwriter.h"
+// qt/kde includes
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <kdebug.h>
+// app includes
+#include "classifierinfo.h"
+#include "codegen_utils.h"
+#include "../uml.h"
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../template.h"
+#include "../umltemplatelist.h"
+#include "../umlclassifierlistitemlist.h"
+#include "../classifierlistitem.h"
+#include "../model_utils.h"
+#include "../codegenerationpolicy.h"
+
+// 3-14-2003: this code developed from the javawriter with parts of the
+// original cppwriter by Luis De la Parra Blum
+
+CppWriter::CppWriter()
+{
+ // Probably we could resolve this better through the use of templates,
+ // but its a quick n dirty fix for the timebeing.. until codegeneration
+ // template system is in place.
+ // You can insert code here. 3 general variables exist: "%VARNAME%"
+ // allows you to specify where the vector variable should be in your code,
+ // and "%ITEMCLASS%", if needed, where the class of the item is declared.
+ VECTOR_METHOD_APPEND = "%VARNAME%.push_back(add_object);"; // for std::vector
+ VECTOR_METHOD_REMOVE = "int i, size = %VARNAME%.size();\nfor ( i = 0; i < size; i++) {\n\t%ITEMCLASS% item = %VARNAME%.at(i);\n\tif(item == remove_object) {\n\t\tvector<%ITEMCLASS%>::iterator it = %VARNAME%.begin() + i;\n\t\t%VARNAME%.erase(it);\n\t\treturn;\n\t}\n }"; // for std::vector
+ VECTOR_METHOD_INIT = QString(); // nothing to be done
+ /*
+ VECTOR_METHOD_APPEND = "%VARNAME%.append(&add_object);"; // Qt lib implementation
+ VECTOR_METHOD_REMOVE = "%VARNAME%.removeRef(&remove_object);"; // Qt lib implementation
+ VECTOR_METHOD_INIT = "%VARNAME%.setAutoDelete(false);"; // Qt library
+ */
+
+ OBJECT_METHOD_INIT = "%VARNAME% = new %ITEMCLASS%( );"; // Qt library
+
+ // boolean config params
+ INLINE_ASSOCIATION_METHODS = false;
+
+}
+
+CppWriter::~CppWriter() { }
+
+Uml::Programming_Language CppWriter::getLanguage() {
+ return Uml::pl_Cpp;
+}
+
+CPPCodeGenerationPolicy *CppWriter::policyExt() {
+ return static_cast<CPPCodeGenerationPolicy*>(UMLApp::app()->getPolicyExt());
+}
+
+void CppWriter::writeClass(UMLClassifier *c)
+{
+
+ if (!c) {
+ kDebug() << "Cannot write class of NULL concept!\n";
+ return;
+ }
+
+ QFile fileh, filecpp;
+
+ // find an appropriate name for our file
+ QString fileName = findFileName(c, ".h");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // preparations
+ m_classifierInfo = new ClassifierInfo(c);
+ m_classifierInfo->fileName = fileName;
+ m_classifierInfo->className = cleanName(c->getName());
+
+ if (c->getVisibility() != Uml::Visibility::Implementation) {
+ if( !openFile(fileh, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ // write Header file
+ writeHeaderFile(c, fileh);
+ fileh.close();
+ }
+
+ // Determine whether the implementation file is required.
+ // (It is not required if the class is an enumeration.)
+ bool need_impl = true;
+ if (c->getBaseType() == Uml::ot_Enum) {
+ need_impl = false;
+ }
+ if (need_impl) {
+ fileName.replace( QRegExp(".h$"), ".cpp");
+ if( !openFile(filecpp, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ // write Source file
+ writeSourceFile(c, filecpp);
+ filecpp.close();
+ }
+
+ // Wrap up: free m_classifierInfo, emit done code
+ m_classifierInfo = 0;
+
+ emit codeGenerated(c, true);
+
+}
+
+void CppWriter::writeHeaderFile (UMLClassifier *c, QFile &fileh) {
+
+ // open stream for writing
+ QTextStream h (&fileh);
+
+ // up the indent level to one
+ m_indentLevel = 1;
+
+ // write header blurb
+ QString str = getHeadingFile(".h");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),m_classifierInfo->fileName + ".h");
+ str.replace(QRegExp("%filepath%"),fileh.name());
+ h << str<< m_endl;
+ }
+
+ // Write the hash define stuff to prevent multiple parsing/inclusion of header
+ QString hashDefine = m_classifierInfo->className.upper().simplifyWhiteSpace().replace(QRegExp(" "), "_");
+ writeBlankLine(h);
+ h << "#ifndef "<< hashDefine + "_H" << m_endl;
+ h << "#define "<< hashDefine + "_H" << m_endl;
+
+ writeClassDecl(c, h);
+
+ // last thing..close our hashdefine
+ h << m_endl << "#endif // " << hashDefine + "_H" << m_endl;
+
+}
+
+void CppWriter::writeHeaderAccessorMethodDecl(UMLClassifier *c, Uml::Visibility permitScope, QTextStream &stream)
+{
+
+ // attributes
+ writeHeaderAttributeAccessorMethods(permitScope, true, stream); // write static attributes first
+ writeHeaderAttributeAccessorMethods(permitScope, false, stream);
+
+ // associations
+ writeAssociationMethods(m_classifierInfo->plainAssociations, permitScope,
+ true, INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
+ writeAssociationMethods(m_classifierInfo->uniAssociations, permitScope,
+ true, INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
+ writeAssociationMethods(m_classifierInfo->aggregations, permitScope,
+ true, INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
+ writeAssociationMethods(m_classifierInfo->compositions, permitScope,
+ true, INLINE_ASSOCIATION_METHODS, false, c->getID(), stream);
+
+ writeBlankLine(stream);
+
+}
+
+void CppWriter::writeHeaderFieldDecl(UMLClassifier *c, Uml::Visibility permitScope, QTextStream &stream)
+{
+ // attributes
+ writeAttributeDecls(permitScope, true, stream); // write static attributes first
+ writeAttributeDecls(permitScope, false, stream);
+
+ // associations
+ writeAssociationDecls(m_classifierInfo->plainAssociations, permitScope, c->getID(), stream);
+ writeAssociationDecls(m_classifierInfo->uniAssociations, permitScope, c->getID(), stream);
+ writeAssociationDecls(m_classifierInfo->aggregations, permitScope, c->getID(), stream);
+ writeAssociationDecls(m_classifierInfo->compositions, permitScope, c->getID(), stream);
+
+}
+
+void CppWriter::writeSourceFile (UMLClassifier *c, QFile &filecpp ) {
+
+ // open stream for writing
+ QTextStream cpp (&filecpp);
+
+ // set the starting indentation at zero
+ m_indentLevel = 0;
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".cpp");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),m_classifierInfo->fileName + ".cpp");
+ str.replace(QRegExp("%filepath%"),filecpp.name());
+ cpp << str << m_endl;
+ }
+
+ // IMPORT statements
+ // Q: Why all utils? Isnt just List and Vector the only classes we are using?
+ // Our import *should* also look at operations, and check that objects being
+ // used arent in another package (and thus need to be explicitly imported here).
+ cpp << "#include \"" << m_classifierInfo->className << ".h\"" << m_endl;
+ writeBlankLine(cpp);
+
+ if (c->getVisibility() == Uml::Visibility::Implementation) {
+ writeClassDecl(c, cpp);
+ }
+
+ // Start body of class
+
+ // Constructors: anything we more we need to do here ?
+ //
+ if(!m_classifierInfo->isInterface)
+ writeConstructorMethods(cpp);
+
+ // METHODS
+ //
+
+ // write comment for section IF needed
+ QString indent = getIndent();
+ if (forceDoc() || m_classifierInfo->hasAccessorMethods || m_classifierInfo->hasOperationMethods)
+ {
+
+ writeComment(" ", indent, cpp);
+ writeComment("Methods", indent, cpp);
+ writeComment(" ", indent, cpp);
+ writeBlankLine(cpp);
+ writeBlankLine(cpp);
+ }
+
+ // write comment for sub-section IF needed
+ if (forceDoc() || m_classifierInfo->hasAccessorMethods )
+ {
+ writeComment("Accessor methods", indent, cpp);
+ writeComment(" ", indent, cpp);
+ writeBlankLine(cpp);
+ }
+
+ // Accessor methods for attributes
+ const bool bInlineAccessors = policyExt()->getAccessorsAreInline();
+ if (!bInlineAccessors && m_classifierInfo->hasAttributes)
+ {
+ writeAttributeMethods(&(m_classifierInfo->static_atpub), Uml::Visibility::Public, false, true, !bInlineAccessors, cpp);
+ writeAttributeMethods(&(m_classifierInfo->atpub), Uml::Visibility::Public, false, false, !bInlineAccessors, cpp);
+ writeAttributeMethods(&(m_classifierInfo->static_atprot), Uml::Visibility::Protected, false, true, !bInlineAccessors, cpp);
+ writeAttributeMethods(&(m_classifierInfo->atprot), Uml::Visibility::Protected, false, false, !bInlineAccessors, cpp);
+ writeAttributeMethods(&(m_classifierInfo->static_atpriv), Uml::Visibility::Private, false, true, !bInlineAccessors, cpp);
+ writeAttributeMethods(&(m_classifierInfo->atpriv), Uml::Visibility::Private, false, false, !bInlineAccessors, cpp);
+ }
+
+ // accessor methods for associations
+
+ // public
+ writeAssociationMethods(m_classifierInfo->plainAssociations, Uml::Visibility::Public, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->uniAssociations, Uml::Visibility::Public, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->aggregations, Uml::Visibility::Public, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->compositions, Uml::Visibility::Public, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+
+ // protected
+ writeAssociationMethods(m_classifierInfo->plainAssociations, Uml::Visibility::Protected, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->uniAssociations, Uml::Visibility::Protected, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->aggregations, Uml::Visibility::Protected, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->compositions, Uml::Visibility::Protected, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+
+
+ // private
+ writeAssociationMethods(m_classifierInfo->plainAssociations, Uml::Visibility::Private, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->uniAssociations, Uml::Visibility::Private, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->aggregations, Uml::Visibility::Private, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeAssociationMethods(m_classifierInfo->compositions, Uml::Visibility::Private, false,
+ !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
+ writeBlankLine(cpp);
+
+ // Other operation methods -- all other operations are now written
+ //
+
+ // write comment for sub-section IF needed
+ if (forceDoc() || m_classifierInfo->hasOperationMethods)
+ {
+ writeComment("Other methods", indent, cpp);
+ writeComment(" ", indent, cpp);
+ writeBlankLine(cpp);
+ }
+
+ if(!policyExt()->getOperationsAreInline())
+ {
+ writeOperations(c,false,Uml::Visibility::Public,cpp);
+ writeOperations(c,false,Uml::Visibility::Protected,cpp);
+ writeOperations(c,false,Uml::Visibility::Private,cpp);
+ }
+
+ // Yep, bringing up the back of the bus, our initialization method for attributes
+ writeInitAttibuteMethod (cpp);
+
+ writeBlankLine(cpp);
+
+}
+
+void CppWriter::writeClassDecl(UMLClassifier *c, QTextStream &cpp)
+{
+ UMLClassifierList superclasses = m_classifierInfo->superclasses;
+ for(UMLClassifier *classifier = superclasses.first(); classifier ;classifier = superclasses.next()) {
+ QString headerName = findFileName(classifier, ".h");
+ if (!headerName.isEmpty()) {
+ cpp << "#include \"" << headerName << "\"" << m_endl;
+ }
+ }
+
+ writeBlankLine(cpp);
+ cpp << "#include " << policyExt()->getStringClassNameInclude() << m_endl;
+ if(m_classifierInfo->hasVectorFields)
+ {
+ cpp << "#include " << policyExt()->getVectorClassNameInclude() << m_endl;
+ writeBlankLine(cpp);
+ }
+
+ if(m_classifierInfo->hasAssociations)
+ {
+ // write all includes we need to include other classes, that arent us.
+ printAssociationIncludeDecl (m_classifierInfo->plainAssociations, c->getID(), cpp);
+ printAssociationIncludeDecl (m_classifierInfo->uniAssociations, c->getID(), cpp);
+ printAssociationIncludeDecl (m_classifierInfo->aggregations, c->getID(), cpp);
+ printAssociationIncludeDecl (m_classifierInfo->compositions, c->getID(), cpp);
+
+ writeBlankLine(cpp);
+ }
+
+
+ for(UMLClassifier *classifier = superclasses.first(); classifier ; classifier = superclasses.next()) {
+ if(classifier->getPackage()!=c->getPackage() && !classifier->getPackage().isEmpty()) {
+ cpp << "using " << cleanName(classifier->getPackage()) << "::" << cleanName(classifier->getName()) << ";" << m_endl;
+ }
+ }
+
+ if(!c->getPackage().isEmpty() && policyExt()->getPackageIsNamespace())
+ cpp << m_endl << "namespace " << cleanName(c->getPackage()) << " {" << m_endl << m_endl;
+
+ //Write class Documentation if there is somthing or if force option
+ if(forceDoc() || !c->getDoc().isEmpty()) {
+ cpp << m_endl << "/**" << m_endl;
+ cpp << " * class " << m_classifierInfo->className << m_endl;
+ cpp << formatDoc(c->getDoc()," * ");
+ cpp << " */";
+ writeBlankLine(cpp);
+ writeBlankLine(cpp);
+ }
+
+ //check if class is abstract and / or has abstract methods
+ if((c->getAbstract() || m_classifierInfo->isInterface )
+ && !hasAbstractOps(c))
+ cpp << "/******************************* Abstract Class ****************************" << m_endl
+ <<m_classifierInfo->className << " does not have any pure virtual methods, but its author" << m_endl
+ <<" defined it as an abstract class, so you should not use it directly." << m_endl
+ <<" Inherit from it instead and create only objects from the derived classes" << m_endl
+ <<"*****************************************************************************/" << m_endl << m_endl;
+
+ if (c->getBaseType() == Uml::ot_Enum) {
+ UMLClassifierListItemList litList = c->getFilteredList(Uml::ot_EnumLiteral);
+ uint i = 0;
+ cpp << "enum " << m_classifierInfo->className << " {" << m_endl;
+ for (UMLClassifierListItem *lit = litList.first(); lit; lit = litList.next()) {
+ QString enumLiteral = cleanName(lit->getName());
+ cpp << getIndent() << enumLiteral;
+ if (++i < litList.count())
+ cpp << ",";
+ cpp << m_endl;
+ }
+ cpp << m_endl << "};" << m_endl; // end of class header
+ if(!c->getPackage().isEmpty() && policyExt()->getPackageIsNamespace())
+ cpp << "} // end of package namespace" << m_endl;
+ return;
+ }
+
+ // Generate template parameters.
+ UMLTemplateList template_params = c->getTemplateList();
+ if (template_params.count()) {
+ cpp << "template<";
+ for (UMLTemplate *t = template_params.first(); t; ) {
+ QString formalName = t->getName();
+ QString typeName = t->getTypeName();
+ cpp << typeName << " " << formalName;
+ if ((t = template_params.next()) != NULL)
+ cpp << ", ";
+ }
+ cpp << ">" << m_endl;
+ }
+
+ cpp << "class " << m_classifierInfo->className;
+ if (m_classifierInfo->superclasses.count() > 0)
+ cpp << " : ";
+ uint numOfSuperClasses = m_classifierInfo->superclasses.count();
+ uint i = 0;
+ for (UMLClassifier *superClass = m_classifierInfo->superclasses.first();
+ superClass ; superClass = m_classifierInfo->superclasses.next())
+ {
+ i++;
+ if (superClass->getAbstract() || superClass->isInterface())
+ cpp << "virtual ";
+ cpp << "public " << cleanName(superClass->getName());
+ if (i < numOfSuperClasses)
+ cpp << ", ";
+ }
+
+ cpp << m_endl << "{" << m_endl; // begin the body of the class
+
+
+ //declarations of operations
+ //
+
+ //
+ // write out field and operations decl grouped by visibility
+ //
+
+ // PUBLIC attribs/methods
+ cpp << "public:" << m_endl << m_endl; // print visibility decl.
+ // for public: constructors are first ops we print out
+ if(!m_classifierInfo->isInterface)
+ writeConstructorDecls(cpp);
+ writeHeaderFieldDecl(c,Uml::Visibility::Public, cpp);
+ writeHeaderAccessorMethodDecl(c, Uml::Visibility::Public, cpp);
+ writeOperations(c,true,Uml::Visibility::Public,cpp);
+
+ // PROTECTED attribs/methods
+ //
+ cpp << "protected" << ":" << m_endl << m_endl; // print visibility decl.
+ writeHeaderFieldDecl(c,Uml::Visibility::Protected, cpp);
+ writeHeaderAccessorMethodDecl(c, Uml::Visibility::Protected, cpp);
+ writeOperations(c,true,Uml::Visibility::Protected,cpp);
+
+ // PRIVATE attribs/methods
+ //
+ cpp << "private" << ":" << m_endl << m_endl; // print visibility decl.
+ writeHeaderFieldDecl(c,Uml::Visibility::Private, cpp);
+ writeHeaderAccessorMethodDecl(c, Uml::Visibility::Private, cpp);
+ writeOperations(c,true,Uml::Visibility::Private,cpp);
+ writeInitAttibuteDecl(cpp); // this is always private, used by constructors to initialize class
+
+ // end of class header
+ cpp << m_endl << "};" << m_endl;
+
+ // end of class namespace, if any
+ if(!c->getPackage().isEmpty() && policyExt()->getPackageIsNamespace())
+ cpp << "}; // end of package namespace" << m_endl;
+
+}
+
+void CppWriter::writeAttributeDecls (Uml::Visibility visibility, bool writeStatic, QTextStream &stream )
+{
+
+ if(m_classifierInfo->isInterface)
+ return;
+
+ UMLAttributeList * list;
+ switch (visibility)
+ {
+ case Uml::Visibility::Private:
+ if(writeStatic)
+ list = &(m_classifierInfo->static_atpriv);
+ else
+ list = &(m_classifierInfo->atpriv);
+ break;
+
+ case Uml::Visibility::Protected:
+ if(writeStatic)
+ list = &(m_classifierInfo->static_atprot);
+ else
+ list = &(m_classifierInfo->atprot);
+ break;
+
+ case Uml::Visibility::Public:
+ default:
+ if(writeStatic)
+ list = &(m_classifierInfo->static_atpub);
+ else
+ list = &(m_classifierInfo->atpub);
+ break;
+ }
+
+ //write documentation
+ if(forceDoc() || list->count() > 0)
+ {
+ QString strVis = Codegen_Utils::capitalizeFirstLetter(visibility.toString());
+ QString strStatic = writeStatic ? "Static ":"";
+ writeComment(strStatic + strVis + " attributes",getIndent(), stream);
+ writeComment(" ",getIndent(), stream);
+ writeBlankLine(stream);
+ }
+
+ if (list->count() > 0) {
+
+ // write attrib declarations now
+ bool isFirstAttrib = true;
+ QString documentation;
+ for(UMLAttribute *at=list->first(); at; at=list->next())
+ {
+
+ // bool noPriorDocExists = documentation.isEmpty();
+ documentation = at->getDoc();
+
+ // add a line for code clarity IF PRIOR attrib has comment on it
+ // OR this line has documentation
+ // if(!isFirstAttrib && (!documentation.isEmpty()||!noPriorDocExists))
+ // writeBlankLine(stream);
+
+ isFirstAttrib = false;
+
+ QString varName = getAttributeVariableName(at);
+
+ QString staticValue = at->getStatic() ? "static " : "";
+ QString typeName = fixTypeName(at->getTypeName());
+ if(!documentation.isEmpty())
+ writeComment(documentation, getIndent(), stream);
+ stream << getIndent() << staticValue << typeName << " " << varName << ";" << m_endl;
+
+ }
+
+ /*
+ if(list->count() > 0)
+ writeBlankLine(stream);
+ */
+
+ }
+
+}
+
+void CppWriter::writeHeaderAttributeAccessorMethods (Uml::Visibility visibility, bool writeStatic, QTextStream &stream )
+{
+ // check the current policy about generate accessors as public
+ UMLAttributeList * list;
+ switch (visibility)
+ {
+ case Uml::Visibility::Private:
+ if(writeStatic)
+ list = &(m_classifierInfo->static_atpriv);
+ else
+ list = &(m_classifierInfo->atpriv);
+ break;
+
+ case Uml::Visibility::Protected:
+ if(writeStatic)
+ list = &(m_classifierInfo->static_atprot);
+ else
+ list = &(m_classifierInfo->atprot);
+ break;
+
+ case Uml::Visibility::Public:
+ default:
+ if(writeStatic)
+ list = &(m_classifierInfo->static_atpub);
+ else
+ list = &(m_classifierInfo->atpub);
+ break;
+ }
+
+ // switch to public
+ if (visibility != Uml::Visibility::Public)
+ stream << "public:" << m_endl << m_endl;
+
+ // write accessor methods for attribs we found
+ writeAttributeMethods(list, visibility, true, false, policyExt()->getAccessorsAreInline(), stream);
+
+ // switch back to previous vis.
+ if (visibility != Uml::Visibility::Public)
+ stream << visibility.toString() << ":" << m_endl << m_endl;
+}
+
+// this is for writing *source* or *header* file attribute methods
+//
+void CppWriter::writeAttributeMethods(UMLAttributeList *attribs,
+ Uml::Visibility visibility, bool isHeaderMethod,
+ bool isStatic,
+ bool writeMethodBody, QTextStream &stream)
+{
+
+ if (!policyExt()->getAutoGenerateAccessors())
+ return;
+
+ if (forceDoc() || attribs->count() > 0)
+ {
+ QString strVis = Codegen_Utils::capitalizeFirstLetter(visibility.toString());
+ QString strStatic = (isStatic ? " static" : "");
+ writeBlankLine(stream);
+ writeComment(strVis + strStatic + " attribute accessor methods",getIndent(),stream);
+ writeComment(" ",getIndent(), stream);
+ writeBlankLine(stream);
+ }
+
+ // return now if NO attributes to work on
+ if (attribs->count() == 0)
+ return;
+
+ UMLAttribute *at;
+ for(at=attribs->first(); at; at=attribs->next())
+ {
+
+ QString varName = getAttributeVariableName(at);
+ QString methodBaseName = cleanName(at->getName());
+
+ // force capitalizing the field name, this is silly,
+ // from what I can tell, this IS the default behavior for
+ // cleanName. I dunno why its not working -b.t.
+ methodBaseName = methodBaseName.stripWhiteSpace();
+ methodBaseName.replace(0,1,methodBaseName.at(0).upper());
+
+ writeSingleAttributeAccessorMethods(at->getTypeName(), varName,
+ methodBaseName, at->getDoc(), Uml::chg_Changeable, isHeaderMethod,
+ at->getStatic(), writeMethodBody, stream);
+ }
+
+}
+
+void CppWriter::writeComment(const QString &comment, const QString &myIndent, QTextStream &cpp)
+{
+ // in the case we have several line comment..
+ // NOTE: this part of the method has the problem of adopting UNIX newline,
+ // need to resolve for using with MAC/WinDoze eventually I assume
+ if (comment.contains(QRegExp("\n"))) {
+
+ QStringList lines = QStringList::split( "\n", comment);
+ for(uint i= 0; i < lines.count(); i++)
+ {
+ cpp << myIndent << "// " << lines[i] << m_endl;
+ }
+ } else {
+ // this should be more fancy in the future, breaking it up into 80 char
+ // lines so that it doesn't look too bad
+ cpp << myIndent << "// "<< comment << m_endl;
+ }
+}
+
+void CppWriter::writeDocumentation(QString header, QString body, QString end, QTextStream &cpp)
+{
+ writeBlankLine(cpp);
+ QString indent = getIndent();
+
+ cpp << indent << "/**" << m_endl;
+ if (!header.isEmpty())
+ cpp << formatDoc(header, indent + " * ");
+ if (!body.isEmpty())
+ cpp << formatDoc(body, indent + " * ");
+ if (!end.isEmpty())
+ {
+ QStringList lines = QStringList::split( "\n", end);
+ for(uint i= 0; i < lines.count(); i++)
+ cpp << formatDoc(lines[i], indent + " * ");
+ }
+ cpp << indent << " */" << m_endl;
+}
+
+void CppWriter::writeAssociationDecls(UMLAssociationList associations, Uml::Visibility permitScope, Uml::IDType id, QTextStream &h)
+{
+
+ if( forceSections() || !associations.isEmpty() )
+ {
+ bool printRoleA = false, printRoleB = false;
+ for(UMLAssociation *a = associations.first(); a; a = associations.next())
+ {
+
+ // it may seem counter intuitive, but you want to insert the role of the
+ // *other* class into *this* class.
+ if (a->getObjectId(Uml::A) == id && !a->getRoleName(Uml::B).isEmpty())
+ printRoleB = true;
+
+ if (a->getObjectId(Uml::B) == id && !a->getRoleName(Uml::A).isEmpty())
+ printRoleA = true;
+
+ // First: we insert documentaion for association IF it has either role AND some documentation (!)
+ if ((printRoleA || printRoleB) && !(a->getDoc().isEmpty()))
+ writeComment(a->getDoc(), getIndent(), h);
+
+ // print RoleB decl
+ if (printRoleB && a->getVisibility(Uml::B) == permitScope)
+ {
+
+ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::B)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::B), a->getMulti(Uml::B), a->getRoleDoc(Uml::B), h);
+ }
+
+ // print RoleA decl
+ if (printRoleA && a->getVisibility(Uml::A) == permitScope)
+ {
+ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::A)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::A), a->getMulti(Uml::A), a->getRoleDoc(Uml::A), h);
+ }
+
+ // reset for next association in our loop
+ printRoleA = false;
+ printRoleB = false;
+ }
+ }
+}
+
+void CppWriter::writeAssociationRoleDecl(QString fieldClassName, QString roleName, QString multi,
+ QString doc, QTextStream &stream)
+{
+ // ONLY write out IF there is a rolename given
+ // otherwise its not meant to be declared in the code
+ if (roleName.isEmpty())
+ return;
+
+ QString indent = getIndent();
+
+ // always put space between this and prior decl, if any
+ writeBlankLine(stream);
+
+ if (!doc.isEmpty())
+ writeComment(doc, indent, stream);
+
+ // declare the association based on whether it is this a single variable
+ // or a List (Vector). One day this will be done correctly with special
+ // multiplicity object that we don't have to figure out what it means via regex.
+ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
+ {
+ QString fieldVarName = "m_" + roleName.lower();
+
+ // record this for later consideration of initialization IF the
+ // multi value requires 1 of these objects
+ if(ObjectFieldVariables.findIndex(fieldVarName) == -1 &&
+ multi.contains(QRegExp("^1$"))
+ )
+ {
+ // ugh. UGLY. Storing variable name and its class in pairs.
+ ObjectFieldVariables.append(fieldVarName);
+ ObjectFieldVariables.append(fieldClassName);
+ }
+
+ stream << indent << fieldClassName << " * " << fieldVarName << ";" << m_endl;
+ }
+ else
+ {
+ QString fieldVarName = "m_" + roleName.lower() + "Vector";
+
+ // record unique occurrences for later when we want to check
+ // for initialization of this vector
+ if(VectorFieldVariables.findIndex(fieldVarName) == -1)
+ VectorFieldVariables.append(fieldVarName);
+
+ stream << indent << policyExt()->getVectorClassName() <<"<" << fieldClassName << "*";
+ stream << "> " << fieldVarName << ";" << m_endl;
+ }
+}
+
+// for either source or header files
+void CppWriter::writeAssociationMethods (UMLAssociationList associations,
+ Uml::Visibility permitVisib,
+ bool isHeaderMethod,
+ bool writeMethodBody,
+ bool writePointerVar,
+ Uml::IDType myID, QTextStream &stream)
+{
+ if( forceSections() || !associations.isEmpty() )
+ {
+ for(UMLAssociation *a = associations.first(); a; a = associations.next())
+ {
+
+ // insert the methods to access the role of the other
+ // class in the code of this one
+ if (a->getObjectId(Uml::A) == myID && a->getVisibility(Uml::B) == permitVisib)
+ {
+ // only write out IF there is a rolename given
+ if(!a->getRoleName(Uml::B).isEmpty()) {
+ QString fieldClassName = getUMLObjectName(a->getObject(Uml::B)) + (writePointerVar ? " *":"");
+ writeAssociationRoleMethod(fieldClassName,
+ isHeaderMethod,
+ writeMethodBody,
+ a->getRoleName(Uml::B),
+ a->getMulti(Uml::B), a->getRoleDoc(Uml::B),
+ a->getChangeability(Uml::B), stream);
+ }
+ }
+
+ if (a->getObjectId(Uml::B) == myID && a->getVisibility(Uml::A) == permitVisib)
+ {
+ // only write out IF there is a rolename given
+ if(!a->getRoleName(Uml::A).isEmpty()) {
+ QString fieldClassName = getUMLObjectName(a->getObject(Uml::A)) + (writePointerVar ? " *":"");
+ writeAssociationRoleMethod(fieldClassName,
+ isHeaderMethod,
+ writeMethodBody,
+ a->getRoleName(Uml::A),
+ a->getMulti(Uml::A),
+ a->getRoleDoc(Uml::A),
+ a->getChangeability(Uml::A),
+ stream);
+ }
+ }
+
+ }
+ }
+}
+
+void CppWriter::writeAssociationRoleMethod (const QString &fieldClassName,
+ bool isHeaderMethod,
+ bool writeMethodBody,
+ const QString &roleName, const QString &multi,
+ const QString &description, Uml::Changeability_Type change,
+ QTextStream &stream)
+{
+ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
+ {
+ QString fieldVarName = "m_" + roleName.lower();
+ writeSingleAttributeAccessorMethods(fieldClassName, fieldVarName, roleName,
+ description, change, isHeaderMethod, false, writeMethodBody, stream);
+ }
+ else
+ {
+ QString fieldVarName = "m_" + roleName.lower() + "Vector";
+ writeVectorAttributeAccessorMethods(fieldClassName, fieldVarName, roleName,
+ description, change, isHeaderMethod, writeMethodBody, stream);
+ }
+}
+
+void CppWriter::writeVectorAttributeAccessorMethods (
+ const QString &fieldClassName, const QString &fieldVarName,
+ const QString &fieldName, const QString &description,
+ Uml::Changeability_Type changeType,
+ bool isHeaderMethod,
+ bool writeMethodBody,
+ QTextStream &stream)
+{
+
+ QString className = fixTypeName(fieldClassName);
+ QString fldName = Codegen_Utils::capitalizeFirstLetter(fieldName);
+ QString indent = getIndent();
+
+ // ONLY IF changeability is NOT Frozen
+ if (changeType != Uml::chg_Frozen)
+ {
+ writeDocumentation("Add a " + fldName + " object to the " + fieldVarName + " List",description,"",stream);
+ stream << indent << "void ";
+ if(!isHeaderMethod)
+ stream << m_classifierInfo->className << "::";
+ stream << "add" << fldName << " ( " << className << " add_object )";
+ if (writeMethodBody) {
+ QString method = VECTOR_METHOD_APPEND;
+ method.replace(QRegExp("%VARNAME%"),fieldVarName);
+ method.replace(QRegExp("%VECTORTYPENAME%"), policyExt()->getVectorClassName());
+ method.replace(QRegExp("%ITEMCLASS%"),className);
+ stream << indent << " {" << m_endl;
+ m_indentLevel++;
+ printTextAsSeparateLinesWithIndent(method,getIndent(),stream);
+ m_indentLevel--;
+ stream << indent << "}" << m_endl;
+ } else
+ stream << ";" << m_endl;
+ }
+
+ // ONLY IF changeability is Changeable
+ if (changeType == Uml::chg_Changeable)
+ {
+ writeDocumentation("Remove a " + fldName + " object from " + fieldVarName + " List",
+ description, "", stream);
+ stream << indent << "void ";
+ if(!isHeaderMethod)
+ stream << m_classifierInfo->className << "::";
+ stream << "remove" << fldName << " ( " << className << " remove_object )";
+ if (writeMethodBody) {
+ QString method = VECTOR_METHOD_REMOVE;
+ method.replace(QRegExp("%VARNAME%"),fieldVarName);
+ method.replace(QRegExp("%VECTORTYPENAME%"), policyExt()->getVectorClassName());
+ method.replace(QRegExp("%ITEMCLASS%"),className);
+ stream << indent << " {" << m_endl;
+ m_indentLevel++;
+ printTextAsSeparateLinesWithIndent(method,getIndent(),stream);
+ m_indentLevel--;
+ stream << indent << "}" << m_endl;
+ } else
+ stream << ";" << m_endl;
+ }
+
+ // always allow getting the list of stuff
+ QString returnVarName = policyExt()->getVectorClassName() + '<' + className + '>';
+ writeDocumentation("Get the list of " + fldName + " objects held by " + fieldVarName,
+ description,
+ "@return " + returnVarName + " list of " + fldName + " objects held by " + fieldVarName,
+ stream);
+ stream << indent << returnVarName << " ";
+ if(!isHeaderMethod)
+ stream << m_classifierInfo->className << "::";
+ stream << "get" << fldName << "List ( )";
+ if(writeMethodBody) {
+ stream << indent << " {" << m_endl;
+ m_indentLevel++;
+ stream << getIndent() << "return " << fieldVarName << ";" << m_endl;
+ m_indentLevel--;
+ stream << indent << "}" << m_endl;
+ } else
+ stream << ";" << m_endl;
+
+}
+
+
+void CppWriter::writeSingleAttributeAccessorMethods(
+ const QString& fieldClassName, const QString& fieldVarName,
+ const QString& fieldName, const QString &description,
+ Uml::Changeability_Type change,
+ bool isHeaderMethod,
+ bool isStatic,
+ bool writeMethodBody,
+ QTextStream &stream)
+{
+
+ // DON'T write this IF its a source method AND writeMethodBody is "false"
+ if(!isHeaderMethod && !writeMethodBody)
+ return;
+
+ QString className = fixTypeName(fieldClassName);
+ QString fldName = Codegen_Utils::capitalizeFirstLetter(fieldName);
+ QString indent = getIndent();
+
+ // set method
+ if (change == Uml::chg_Changeable && !isStatic) {
+ writeDocumentation("Set the value of " + fieldVarName,description,"@param new_var the new value of " + fieldVarName,stream);
+ stream << indent << "void ";
+ if(!isHeaderMethod)
+ stream << m_classifierInfo->className << "::";
+ stream << "set" << fldName << " ( " << className << " new_var )";
+
+ if(writeMethodBody) {
+ stream << indent << " {" << m_endl;
+ m_indentLevel++;
+ stream << getIndent() << indent;
+ m_indentLevel--;
+ if(isStatic)
+ stream << m_classifierInfo->className << "::";
+ stream << fieldVarName << " = new_var;" << m_endl;
+ stream << indent << "}" << m_endl;
+ } else
+ stream << ";" << m_endl;
+ }
+
+ // get method
+ writeDocumentation("Get the value of " + fieldVarName,description,"@return the value of " + fieldVarName,stream);
+ stream << indent << className << " ";
+ if(!isHeaderMethod)
+ stream << m_classifierInfo->className << "::";
+ stream << "get" << fldName << " ( )";
+
+ if(writeMethodBody) {
+ stream << indent << " {" << m_endl;
+ m_indentLevel++;
+ stream << getIndent() << "return ";
+ m_indentLevel--;
+ if(isStatic)
+ stream << m_classifierInfo->className << "::";
+ stream << fieldVarName << ";" << m_endl;
+ stream << indent << "}";
+ } else
+ stream << ";" << m_endl;
+
+ writeBlankLine(stream);
+}
+
+// one day, this should print out non-empty constructor operations too.
+void CppWriter::writeConstructorDecls(QTextStream &stream)
+{
+ const bool generateEmptyConstructors =
+ UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors();
+ if (forceDoc() || generateEmptyConstructors)
+ {
+ writeComment("Constructors/Destructors", getIndent(), stream);
+ writeComment(" ", getIndent(), stream);
+ writeBlankLine(stream);
+ }
+ if (!generateEmptyConstructors)
+ return;
+
+ writeDocumentation("", "Empty Constructor", "", stream);
+ stream << getIndent() << m_classifierInfo->className << " ( );" << m_endl;
+ writeDocumentation("", "Empty Destructor", "", stream);
+ stream << getIndent();
+ stream << "virtual ~" << m_classifierInfo->className << " ( );" << m_endl;
+ writeBlankLine(stream);
+}
+
+void CppWriter::writeInitAttibuteDecl (QTextStream &stream)
+{
+ if (UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors() &&
+ m_classifierInfo->hasAttributes)
+ stream << getIndent() << "void initAttributes ( ) ;" << m_endl;
+}
+
+void CppWriter::writeInitAttibuteMethod (QTextStream &stream)
+{
+ // only need to do this under certain conditions
+ if (!UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors() ||
+ !m_classifierInfo->hasAttributes)
+ return;
+
+ QString className = m_classifierInfo->className;
+ QString indent = getIndent();
+
+ stream << indent << "void " << className << "::" << "initAttributes ( ) {" << m_endl;
+
+ m_indentLevel++;
+ // first, initiation of fields derived from attributes
+ UMLAttributeList atl = m_classifierInfo->getAttList();
+ for(UMLAttribute *at = atl.first(); at ; at = atl.next()) {
+ if(!at->getInitialValue().isEmpty()) {
+ QString varName = getAttributeVariableName(at);
+ stream << getIndent() << varName << " = " << at->getInitialValue() << ";" << m_endl;
+ }
+ }
+ // Now initialize the association related fields (e.g. vectors)
+ if (!VECTOR_METHOD_INIT.isEmpty()) {
+ QStringList::Iterator it;
+ for( it = VectorFieldVariables.begin(); it != VectorFieldVariables.end(); ++it ) {
+ QString fieldVarName = *it;
+ QString method = VECTOR_METHOD_INIT;
+ method.replace(QRegExp("%VARNAME%"),fieldVarName);
+ method.replace(QRegExp("%VECTORTYPENAME%"), policyExt()->getVectorClassName());
+ stream << getIndent() << method << m_endl;
+ }
+ }
+
+ if (!OBJECT_METHOD_INIT.isEmpty()) {
+ QStringList::Iterator it;
+ for( it = ObjectFieldVariables.begin(); it != ObjectFieldVariables.end(); ++it ) {
+ QString fieldVarName = *it;
+ it++;
+ QString fieldClassName = *it;
+ QString method = OBJECT_METHOD_INIT;
+ method.replace(QRegExp("%VARNAME%"),fieldVarName);
+ method.replace(QRegExp("%ITEMCLASS%"),fieldClassName);
+ stream << getIndent() << method << m_endl;
+ }
+ }
+
+ // clean up
+ ObjectFieldVariables.clear(); // shouldn't be needed?
+ VectorFieldVariables.clear(); // shouldn't be needed?
+
+ m_indentLevel--;
+
+ stream << indent << "}" << m_endl;
+}
+
+// one day, this should print out non-empty constructor operations too.
+void CppWriter::writeConstructorMethods(QTextStream &stream)
+{
+ const bool generateEmptyConstructors =
+ UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors();
+
+ if (forceDoc() || generateEmptyConstructors) {
+ writeComment("Constructors/Destructors", getIndent(), stream);
+ writeComment(" ", getIndent(), stream);
+ writeBlankLine(stream);
+ }
+ if (!generateEmptyConstructors)
+ return;
+
+ QString className = m_classifierInfo->className;
+ // empty constructor
+ QString indent = getIndent();
+ stream << indent << className << "::" << className << " ( ) {" << m_endl;
+ if(m_classifierInfo->hasAttributes)
+ stream << indent << indent << "initAttributes();" << m_endl;
+ stream << indent << "}" << m_endl;
+ writeBlankLine(stream);
+
+ // empty destructor
+ stream << getIndent() << className << "::~" << className << " ( ) { }" << m_endl;
+ writeBlankLine(stream);
+}
+
+// IF the type is "string" we need to declare it as
+// the Java Object "String" (there is no string primative in Java).
+QString CppWriter::fixTypeName(const QString &string)
+{
+ if (string.isEmpty())
+ return "void";
+ if (string == "string")
+ return policyExt()->getStringClassName();
+ return string;
+}
+
+void CppWriter::writeOperations(UMLClassifier *c, bool isHeaderMethod,
+ Uml::Visibility permitScope, QTextStream &cpp) {
+
+ UMLOperationList oplist;
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList inputlist = c->getOpList();
+ for (UMLOperation *op = inputlist.first(); op; op = inputlist.next()) {
+ if (op->getVisibility() == permitScope) {
+ oplist.append(op);
+ }
+ }
+
+ // do people REALLY want these comments? Hmm.
+ /*
+ if(forceSections() || oppub.count())
+ {
+ writeComment("public operations",getIndent(),cpp);
+ writeBlankLine(cpp);
+ }
+ */
+ writeOperations(oplist,isHeaderMethod, cpp);
+
+}
+
+// write operation in either header or
+// a source file
+void CppWriter::writeOperations(UMLOperationList &oplist, bool isHeaderMethod, QTextStream &cpp) {
+ QString className = m_classifierInfo->className;
+ const bool generateEmptyConstructors =
+ UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors();
+
+ // generate method decl for each operation given
+ for (UMLOperation *op = oplist.first(); op; op = oplist.next()) {
+
+ QString returnStr; // buffer for documentation
+ QString methodReturnType;
+ UMLAttributeList atl = op->getParmList(); // method parameters
+
+ if (op->isConstructorOperation()) {
+ if (generateEmptyConstructors && atl.count() == 0)
+ continue; // it's already been written, see writeConstructor{Decls,Methods}
+ } else if (op->isDestructorOperation()) {
+ if (generateEmptyConstructors)
+ continue; // it's already been written, see writeConstructor{Decls,Methods}
+ } else {
+ methodReturnType = fixTypeName(op->getTypeName());
+ if(methodReturnType != "void")
+ returnStr += "@return " + methodReturnType + '\n';
+ }
+
+ QString str;
+ if (op->getAbstract() || m_classifierInfo->isInterface) {
+ if (isHeaderMethod) {
+ // declare abstract method as 'virtual'
+ str += "virtual ";
+ }
+ }
+
+ // static declaration for header file
+ if (isHeaderMethod && op->getStatic())
+ str += "static ";
+
+ // returntype of method
+ str += methodReturnType + ' ';
+
+ if (!isHeaderMethod)
+ str += className + "::";
+
+ str += cleanName(op->getName()) + " (";
+
+ // generate parameters
+ uint j = 0;
+ for (UMLAttribute *at = atl.first(); at; at = atl.next(), j++) {
+ QString typeName = fixTypeName(at->getTypeName());
+ QString atName = cleanName(at->getName());
+ str += typeName + ' ' + atName;
+ const QString initVal = at->getInitialValue();
+ if (! initVal.isEmpty())
+ str += " = " + initVal;
+ if (j < atl.count() - 1)
+ str += ", ";
+ returnStr += "@param " + atName + ' ' + at->getDoc() + '\n';
+ }
+ str += " )";
+
+ if (op->getConst())
+ str += " const";
+
+ // method body : only gets IF its not in a header
+ if (isHeaderMethod && !policyExt()->getOperationsAreInline())
+ str += ';'; // terminate now
+ else
+ str +=getIndent() + " {\n\n" + getIndent() + '}'; // empty method body
+
+ // write it out
+ writeDocumentation("", op->getDoc(), returnStr, cpp);
+ cpp << getIndent() << str << m_endl;
+ writeBlankLine(cpp);
+ }
+}
+
+// To prevent circular including when both classifiers on either end
+// of an association have roles we need to have forward declaration of
+// the other class...but only IF its not THIS class (as could happen
+// in self-association relationship).
+void CppWriter::printAssociationIncludeDecl (UMLAssociationList list, Uml::IDType myId, QTextStream &stream)
+{
+
+ for (UMLAssociation *a = list.first(); a; a = list.next()) {
+ UMLClassifier *current = NULL;
+ bool isFirstClass = true;
+
+ // only use OTHER classes (e.g. we don't need to write includes for ourselves!!
+ // AND only IF the roleName is defined, otherwise, its not meant to be noticed.
+ if (a->getObjectId(Uml::A) == myId && !a->getRoleName(Uml::B).isEmpty()) {
+ current = dynamic_cast<UMLClassifier*>(a->getObject(Uml::B));
+ } else if (a->getObjectId(Uml::B) == myId && !a->getRoleName(Uml::A).isEmpty()) {
+ current = dynamic_cast<UMLClassifier*>(a->getObject(Uml::A));
+ isFirstClass = false;
+ }
+
+ // as header doc for this method indicates, we need to be a bit sophisticated on
+ // how to declare some associations.
+ if( current )
+ if( !isFirstClass && !a->getRoleName(Uml::A).isEmpty() && !a->getRoleName(Uml::B).isEmpty())
+ stream << "class " << current->getName() << ";" << m_endl; // special case: use forward declaration
+ else
+ stream << "#include \"" << current->getName() << ".h\"" << m_endl; // just the include statement
+ }
+}
+
+QString CppWriter::fixInitialStringDeclValue(const QString &value, const QString &type)
+{
+ QString val = value;
+ // check for strings only
+ if (!val.isEmpty() && type == policyExt()->getStringClassName()) {
+ if (!val.startsWith("\""))
+ val.prepend("\"");
+ if (!val.endsWith("\""))
+ val.append("\"");
+ }
+ return val;
+}
+
+// methods like this _shouldn't_ be needed IF we properly did things thruought the code.
+QString CppWriter::getUMLObjectName(UMLObject *obj)
+{
+ return(obj!=0)?obj->getName():QString("NULL");
+}
+
+void CppWriter::writeBlankLine(QTextStream &stream)
+{
+ stream << m_endl;
+}
+
+void CppWriter::printTextAsSeparateLinesWithIndent (const QString &text, const QString &indent, QTextStream &stream)
+{
+ if(text.isEmpty())
+ return;
+
+ QStringList lines = QStringList::split( "\n", text);
+ for(uint i= 0; i < lines.count(); i++)
+ stream << indent << lines[i] << m_endl;
+}
+
+QString CppWriter::getAttributeVariableName (UMLAttribute *at)
+{
+ QString fieldName = "m_" + cleanName(at->getName());
+ return fieldName;
+}
+
+QStringList CppWriter::defaultDatatypes() {
+ return Codegen_Utils::cppDatatypes();
+}
+
+const QStringList CppWriter::reservedKeywords() const {
+ return Codegen_Utils::reservedCppKeywords();
+}
+
diff --git a/umbrello/umbrello/codegenerators/cppwriter.h b/umbrello/umbrello/codegenerators/cppwriter.h
new file mode 100644
index 00000000..8ae58226
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppwriter.h
@@ -0,0 +1,293 @@
+/***************************************************************************
+ cppwriter.h - description
+ This is the "old" code generator that does not support code editing
+ in the Modeller but uses significantly less file space because the
+ source code is not replicated in the XMI file.
+ -------------------
+ copyright : (C) 2003 Brian Thomas
+ (C) 2004 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef CPPWRITER_H
+#define CPPWRITER_H
+
+#include "simplecodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "../umloperationlist.h"
+#include "../umlattributelist.h"
+#include "../umlassociationlist.h"
+
+class QFile;
+class ClassifierInfo;
+
+/**
+ * class CppWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate both a header (.h) and
+ * source (.cpp) file for that classifier.
+ */
+class CppWriter : public SimpleCodeGenerator {
+public:
+
+ /**
+ * Constructor, initialises a couple of variables
+ */
+ CppWriter();
+
+ /**
+ * Destructor, empty
+ */
+ virtual ~CppWriter();
+
+ /**
+ * call this method to generate cpp code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "C++"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * Add C++ primitives as datatypes
+ */
+ QStringList defaultDatatypes();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * Writes class's documentation to the class header
+ * public abstract class Foo extents {
+ */
+ void writeClassDecl(UMLClassifier *c, QTextStream &cpp);
+
+ /**
+ * Writes the comment and class constructor declaration or methods
+ */
+ void writeConstructorDecls(QTextStream &h);
+ void writeConstructorMethods(QTextStream &cpp);
+
+ /**
+ * write all field declarations, for both attributes and associations for the
+ * given permitted scope.
+ */
+ void writeFieldDecl(UMLClassifier *c, Uml::Visibility permitScope, QTextStream &stream);
+
+ /**
+ * write all method declarations, for attributes and associations
+ * for the given permitted scope.
+ */
+ void writeAccessorMethodDecl(UMLClassifier *c, Uml::Visibility permitScope, QTextStream &stream);
+
+ /**
+ * write all operations for a given class
+ * @param c the class for which we are generating code
+ * @param isHeaderMethod true when writing to a header file, false for body file
+ * @param permitScope what type of method to write (by Scope)
+ * @param j the stream associated with the output file
+ */
+ void writeOperations(UMLClassifier *c, bool isHeaderMethod, Uml::Visibility permitScope, QTextStream &j);
+
+ /**
+ * write a list of operations for a given class
+ * @param list the list of operations you want to write
+ * @param isHeaderMethod true when writing to a header file, false for body file
+ * @param j the stream associated with the output file
+ */
+ void writeOperations(UMLOperationList &list, bool isHeaderMethod, QTextStream &j);
+
+ /**
+ * write all attributes for a given class
+ * @param c the class for which we are generating code
+ * @param j the stream associated with the output file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &j);
+
+ /**
+ * writes the Attribute declarations
+ * @param visibility the visibility of the attribs to print out
+ * @param writeStatic whether to write static or non-static attributes out
+ * @param stream text stream
+ */
+ void writeAttributeDecls (Uml::Visibility visibility, bool writeStatic, QTextStream &stream );
+
+ /**
+ * Write out fields and operations for this class selected on a particular
+ * visibility.
+ */
+ void writeHeaderFieldDecl(UMLClassifier *c, Uml::Visibility permitVisibility, QTextStream &stream);
+
+ void writeHeaderAttributeAccessorMethods (Uml::Visibility visibility, bool writeStatic, QTextStream &stream );
+
+ void writeHeaderAttributeAccessorMethodDecls(UMLClassifier *c, Uml::Visibility permitVisibility, QTextStream &stream);
+ void writeHeaderAccessorMethodDecl(UMLClassifier *c, Uml::Visibility permitScope, QTextStream &stream);
+
+
+ /**
+ * Searches a list of associations for appropriate ones to write out as attributes
+ */
+ void writeAssociationDecls(UMLAssociationList associations, Uml::Visibility permit, Uml::IDType id, QTextStream &stream);
+
+ /**
+ * Writes out an association as an attribute using Vector
+ */
+ void writeAssociationRoleDecl(QString fieldClassName, QString roleName, QString multi,
+ QString doc, QTextStream &stream);
+
+ /**
+ * calls @ref writeSingleAttributeAccessorMethods() on each of the attributes in attribs list.
+ */
+ void writeAttributeMethods(UMLAttributeList *attribs, Uml::Visibility visib, bool isHeaderMethod,
+ bool isStatic,
+ bool writeMethodBody, QTextStream &stream);
+
+ /**
+ * calls @ref writeAssociationRoleMethod() on each of the associations in the given list
+ */
+ void writeAssociationMethods(UMLAssociationList associations, Uml::Visibility permitVisib,
+ bool isHeaderMethod,
+ bool writeMethodBody, bool writePointerVar, Uml::IDType id, QTextStream &stream);
+
+ /**
+ * calls @ref writeSingleAttributeAccessorMethods() or @ref
+ * writeVectorAttributeAccessorMethods() on the association
+ * role
+ */
+ void writeAssociationRoleMethod(const QString &fieldClassName, bool isHeaderMethod, bool writeMethodBody,
+ const QString &roleName, const QString &multi,
+ const QString &description, Uml::Changeability_Type change,
+ QTextStream &stream);
+
+ /**
+ * Writes getFoo() and setFoo() accessor methods for the attribute
+ */
+ void writeSingleAttributeAccessorMethods(
+ const QString &fieldClassName, const QString &Name,
+ const QString &fieldName, const QString &description,
+ Uml::Changeability_Type change,
+ bool isHeaderMethod,
+ bool isStatic, bool writeMethodBody, QTextStream &cpp);
+
+ /**
+ * Writes addFoo() and removeFoo() accessor methods for the Vector attribute
+ */
+ void writeVectorAttributeAccessorMethods(
+ const QString &fieldClassName, const QString &fieldVarName,
+ const QString &fieldName, const QString &description,
+ Uml::Changeability_Type change,
+ bool isHeaderMethod,
+ bool writeMethodBody,
+ QTextStream &cpp);
+
+ /**
+ * Writes a // style comment
+ */
+ void writeComment(const QString &text, const QString &indent, QTextStream &cpp);
+
+ /**
+ * Writes a documentation comment
+ */
+ void writeDocumentation(QString header, QString body, QString end, QTextStream &cpp);
+
+
+ /**
+ * write the header file for this classifier.
+ */
+ void writeHeaderFile (UMLClassifier *c, QFile &file);
+
+ /**
+ * write the source code body file for this classifier.
+ */
+ void writeSourceFile (UMLClassifier *c, QFile &file);
+
+ /**
+ * utility method to break up a block of text, which has embedded newline chars,
+ * and print them to a stream as separate lines of text, indented as directed.
+ */
+ void printTextAsSeparateLinesWithIndent (const QString &text, const QString &indent,
+ QTextStream &stream);
+
+ /**
+ * Intellegently print out header include/forward decl. for associated classes.
+ */
+ void printAssociationIncludeDecl (UMLAssociationList list, Uml::IDType this_id, QTextStream &stream);
+
+ /**
+ * If needed, write out the method to initialize attributes of our class.
+ */
+ void writeInitAttibuteMethod (QTextStream &stream);
+
+ /**
+ * If needed, write out the declaration for the method to initialize attributes of our class.
+ */
+ void writeInitAttibuteDecl (QTextStream &stream);
+
+ /**
+ * Returns the name of the given object (if it exists)
+ */
+ QString getUMLObjectName(UMLObject *obj);
+
+ /**
+ * Replaces `string' with STRING_TYPENAME.
+ */
+ QString fixTypeName(const QString &string);
+
+ /**
+ * check that initial values of strings have quotes around them
+ */
+ QString fixInitialStringDeclValue(const QString &value, const QString &type);
+
+ /**
+ * Determine what the variable name of this attribute should be.
+ */
+ QString getAttributeVariableName (UMLAttribute *at);
+
+ /**
+ * Write a blank line
+ */
+ void writeBlankLine(QTextStream &stream);
+
+ /**
+ * Return the policy object
+ */
+ CPPCodeGenerationPolicy *policyExt();
+
+ /**
+ * Summary information about current classifier.
+ */
+ ClassifierInfo * m_classifierInfo;
+
+ QString VECTOR_METHOD_APPEND;
+ QString VECTOR_METHOD_REMOVE;
+ QString VECTOR_METHOD_INIT;
+ QString OBJECT_METHOD_INIT;
+
+ /**
+ * Create association methods for class attributes/associations/operations as inline decl in header.
+ */
+ bool INLINE_ASSOCIATION_METHODS;
+
+ QStringList ObjectFieldVariables;
+ QStringList VectorFieldVariables;
+
+};
+
+
+
+#endif // CPPWRITER_H
diff --git a/umbrello/umbrello/codegenerators/csharpwriter.cpp b/umbrello/umbrello/codegenerators/csharpwriter.cpp
new file mode 100644
index 00000000..73975b48
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/csharpwriter.cpp
@@ -0,0 +1,725 @@
+/***************************************************************************
+ * *
+ * 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) 2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+//
+// C++ Implementation: csharpwriter
+//
+#include "csharpwriter.h"
+
+#include <kdebug.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include "../uml.h"
+#include "../umldoc.h"
+#include "../folder.h"
+#include "../classifier.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+
+static const char *reserved_words[] = {
+ "abstract",
+ "as",
+ "base",
+ "bool",
+ "break",
+ "byte",
+ "case",
+ "catch",
+ "char",
+ "checked",
+ "class",
+ "const",
+ "continue",
+ "decimal",
+ "default",
+ "delegate",
+ "do",
+ "double",
+ "else",
+ "enum",
+ "event",
+ "explicit",
+ "extern",
+ "false",
+ "finally",
+ "for",
+ "foreach",
+ "goto",
+ "if",
+ "implicit",
+ "in",
+ "int",
+ "interface",
+ "internal",
+ "is",
+ "lock",
+ "long",
+ "namespace",
+ "new",
+ "null",
+ "object",
+ "operator",
+ "out",
+ "override",
+ "params",
+ "private",
+ "protected",
+ "public",
+ "readonly",
+ "ref",
+ "return",
+ "sbyte",
+ "sealed",
+ "short",
+ "sizeof",
+ "stackalloc",
+ "static",
+ "string",
+ "struct",
+ "switch",
+ "this",
+ "throw",
+ "true",
+ "try",
+ "typeof",
+ "uint",
+ "ulong",
+ "unchecked",
+ "unsafe",
+ "ushort",
+ "using",
+ "virtual",
+ "void",
+ "volatile",
+ "while",
+ 0
+};
+
+CSharpWriter::CSharpWriter()
+ : SimpleCodeGenerator()
+{
+}
+
+
+CSharpWriter::~CSharpWriter()
+{
+}
+
+QStringList CSharpWriter::defaultDatatypes() {
+ QStringList l;
+ l.append("bool");
+ l.append("byte");
+ l.append("char");
+ l.append("decimal");
+ l.append("double");
+ l.append("fixed");
+ l.append("float");
+ l.append("fixed");
+ l.append("float");
+ l.append("int");
+ l.append("long");
+ l.append("object");
+ l.append("sbyte");
+ l.append("short");
+ l.append("string");
+ l.append("uint");
+ l.append("ulong");
+ l.append("ushort");
+ return l;
+}
+
+void CSharpWriter::writeClass(UMLClassifier *c) {
+ if (!c) {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ QString classname = cleanName(c->getName());
+ //find an appropriate name for our file
+ QString fileName = findFileName(c, ".cs");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile filecs;
+ if (!openFile(filecs, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream cs(&filecs);
+
+ //////////////////////////////
+ //Start generating the code!!
+ /////////////////////////////
+
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".cs");
+ if (!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),filecs.name());
+ cs<<str<<m_endl;
+ }
+
+ UMLDoc *umldoc = UMLApp::app()->getDocument();
+ UMLFolder *logicalView = umldoc->getRootFolder(Uml::mt_Logical);
+
+ // write generic includes
+ cs << "using System;" << m_endl;
+ cs << "using System.Text;" << m_endl;
+ cs << "using System.Collections;" << m_endl;
+ cs << "using System.Collections.Generic;" << m_endl << m_endl;
+
+ //write includes and namespace
+
+ UMLPackage *container = c->getUMLPackage();
+ if (container == logicalView)
+ container = NULL;
+
+ UMLPackageList includes;
+ findObjectsRelated(c, includes);
+ m_seenIncludes.clear();
+ //m_seenIncludes.append(logicalView);
+ if (includes.count()) {
+ UMLPackage *p;
+ for (UMLPackageListIt it(includes); (p = it.current()) != NULL; ++it) {
+ UMLClassifier *cl = dynamic_cast<UMLClassifier*>(p);
+ if (cl)
+ p = cl->getUMLPackage();
+ if (p != logicalView && m_seenIncludes.findRef(p) == -1 && p != container) {
+ cs << "using " << p->getFullyQualifiedName(".") << ";" << m_endl;
+ m_seenIncludes.append(p);
+ }
+ }
+ cs << m_endl;
+ }
+
+ m_container_indent = "";
+
+ if (container) {
+ cs << "namespace " << container->getFullyQualifiedName(".") << m_endl;
+ cs << "{" << m_endl << m_endl;
+ m_container_indent = m_indentation;
+ m_seenIncludes.append(container);
+ }
+
+ //Write class Documentation if there is somthing or if force option
+ if (forceDoc() || !c->getDoc().isEmpty()) {
+ cs << m_container_indent << "/// <summary>" << m_endl;
+ cs << formatDoc(c->getDoc(), m_container_indent + "/// " );
+ cs << m_container_indent << "/// </summary>" << m_endl ;
+ }
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+ UMLAssociationList realizations = c->getRealizations();
+ bool isInterface = c->isInterface();
+ m_unnamedRoles = 1;
+
+ cs << m_container_indent << "public ";
+
+ //check if it is an interface or regular class
+ if (isInterface) {
+ cs << "interface " << classname;
+ } else {
+ //check if class is abstract and / or has abstract methods
+ if (c->getAbstract() || c->hasAbstractOps())
+ cs << "abstract ";
+
+ cs << "class " << classname << (superclasses.count() > 0 ? " : ":"");
+
+ // write baseclass, ignore interfaces, write error on multiple inheritance
+ if (superclasses.count() > 0) {
+ UMLClassifier *obj;
+ int supers = 0;
+ for (obj = superclasses.first(); obj; obj = superclasses.next()) {
+ if (!obj->isInterface()) {
+ if (supers > 0) {
+ cs << " // AND ";
+ }
+ cs << cleanName(obj->getName());
+ supers++;
+ }
+ }
+ if (supers > 1) {
+ cs << m_endl << "//WARNING: C# does not support multiple inheritance but there is more than 1 superclass defined in your UML model!" << m_endl;
+ }
+ }
+ //check for realizations
+ UMLAssociationList realizations = c->getRealizations();
+ UMLAssociation *a;
+
+ if (!realizations.isEmpty()) {
+ for (a = realizations.first(); a; a = realizations.next()) {
+ UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B);
+ if(real != c) {
+ // write list of realizations
+ cs << ", " << real->getName();
+ }
+
+ }
+ }
+ }
+ cs << m_endl << m_container_indent << '{' << m_endl;
+
+ //associations
+ if (forceSections() || !aggregations.isEmpty()) {
+ cs << m_endl << m_container_indent << m_indentation << "#region Aggregations" << m_endl << m_endl;
+ writeAssociatedAttributes(aggregations, c, cs);
+ cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl;
+ }
+
+ //compositions
+ if (forceSections() || !compositions.isEmpty()) {
+ cs << m_endl << m_container_indent << m_indentation << "#region Compositions" << m_endl << m_endl;
+ writeAssociatedAttributes(compositions, c, cs);
+ cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl;
+ }
+
+ //attributes
+ // FIXME: C# allows Properties in interface!
+ if (!isInterface)
+ writeAttributes(c, cs);
+
+ //operations
+ writeOperations(c, cs);
+
+ //finish file
+ cs << m_endl << m_container_indent << "}" << m_endl << m_endl; // close class
+
+ if (container) {
+ cs << "} // end of namespace "
+ << container->getFullyQualifiedName(".") << m_endl << m_endl;
+ }
+
+ //close files and notfiy we are done
+ filecs.close();
+ emit codeGenerated(c, true);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+void CSharpWriter::writeOperations(UMLClassifier *c, QTextStream &cs) {
+
+ //Lists to store operations sorted by scope
+ UMLOperationList oppub,opprot,oppriv;
+
+ bool isInterface = c->isInterface();
+ bool generateErrorStub = true;
+
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList opl(c->getOpList());
+ for (UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ switch (op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // write realizations (recursive)
+ UMLAssociationList realizations = c->getRealizations();
+
+ if (!isInterface && !realizations.isEmpty()) {
+ writeRealizationsRecursive(c, &realizations, cs);
+ }
+
+ // write public operations
+ if (forceSections() || !oppub.isEmpty()) {
+ cs << m_endl << m_container_indent << m_indentation << "#region Public methods" << m_endl << m_endl;
+ writeOperations(oppub,cs,isInterface,false,generateErrorStub);
+ cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
+ }
+
+ // write protected operations
+ if (forceSections() || !opprot.isEmpty()) {
+ cs << m_endl << m_container_indent << m_indentation << "#region Protected methods" << m_endl << m_endl;
+ writeOperations(opprot,cs,isInterface,false,generateErrorStub);
+ cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
+ }
+
+ // write private operations
+ if (forceSections() || !oppriv.isEmpty()) {
+ cs << m_endl << m_container_indent << m_indentation << "#region Private methods" << m_endl << m_endl;
+ writeOperations(oppriv,cs,isInterface,false,generateErrorStub);
+ cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
+ }
+
+ // write superclasses abstract methods
+ UMLClassifierList superclasses = c->getSuperClasses();
+
+ if (!isInterface && !c->getAbstract() && !c->hasAbstractOps()
+ && superclasses.count() > 0) {
+ writeOverridesRecursive(&superclasses, cs);
+ }
+
+}
+
+void CSharpWriter::writeOverridesRecursive(UMLClassifierList *superclasses, QTextStream &cs) {
+ // oplist for implemented abstract operations
+ UMLOperationList opabstract;
+ opabstract.setAutoDelete(false);
+ UMLClassifier *obj;
+
+ for (obj = superclasses->first(); obj; obj = superclasses->next()) {
+ if (!obj->isInterface() && obj->hasAbstractOps()) {
+ // collect abstract ops
+ UMLOperationList opl(obj->getOpList());
+ for (UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ if (op->getAbstract()) {
+ opabstract.append(op);
+ }
+ }
+
+ // write abstract implementations
+ cs << m_endl << m_container_indent << m_indentation << "#region " << obj->getName() << " members" << m_endl << m_endl;
+ writeOperations(opabstract,cs,false,true,true);
+ cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
+
+ opabstract.clear();
+ }
+ // Recurse to parent superclasses
+ UMLClassifierList superRecursive = obj->getSuperClasses();
+ UMLClassifierList *superRecursivePtr =& superRecursive;
+ if (superRecursivePtr->count() > 0) {
+ writeOverridesRecursive(superRecursivePtr, cs);
+ }
+ }
+}
+void CSharpWriter::writeRealizationsRecursive(UMLClassifier *currentClass, UMLAssociationList *realizations, QTextStream &cs) {
+
+ UMLAssociation *a;
+ for (a = realizations->first(); a; a = realizations->next()) {
+
+ // we know its a classifier if its in the list
+ UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B);
+
+ //FIXME: Interfaces realize themselves without this condition!?
+ if (real == currentClass)
+ continue;
+
+ // collect operations of one realization
+ UMLOperationList opreal = real->getOpList();
+
+ // write realizations
+ cs << m_endl << m_container_indent << m_indentation << "#region " << real->getName() << " members" << m_endl << m_endl;
+ writeOperations(opreal,cs,false,false,true);
+ cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
+
+ // Recurse to parent realizations
+ UMLAssociationList parentReal = real->getRealizations();
+ if (!parentReal.isEmpty()) {
+ writeRealizationsRecursive(real, &parentReal, cs);
+ }
+ }
+}
+
+void CSharpWriter::writeOperations(UMLOperationList opList,
+ QTextStream &cs, bool isInterface /* = false */,
+ bool isOverride /* = false */,
+ bool generateErrorStub /* = false */) {
+
+ for (UMLOperation *op=opList.first(); op ; op=opList.next()) {
+ UMLAttributeList atl = op->getParmList();
+ UMLAttribute *at;
+
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+
+ for (at = atl.first(); at; at = atl.next()) {
+ writeDoc |= !at->getDoc().isEmpty();
+ }
+
+ //write method documentation
+ if (writeDoc && !isOverride)
+ {
+ cs << m_container_indent << m_indentation << "/// <summary>" << m_endl;
+ cs << formatDoc(op->getDoc(), m_container_indent + m_indentation + "/// ");
+ cs << m_container_indent << m_indentation << "/// </summary>" << m_endl;
+
+ //write parameter documentation
+ for (at = atl.first(); at; at = atl.next())
+ {
+ if (forceDoc() || !at->getDoc().isEmpty()) {
+ cs << m_container_indent << m_indentation << "/// <param name=\"" << cleanName(at->getName()) << "\">";
+ //removing newlines from parameter doc
+ cs << formatDoc(at->getDoc(), "").replace("\n", " ").remove('\r').replace(QRegExp(" $"), "");
+ cs << "</param>" << m_endl;
+ }
+ }
+
+ // FIXME: "returns" should contain documentation, not type.
+ cs << m_container_indent << m_indentation << "/// <returns>";
+ if (! op->getTypeName().isEmpty()) {
+ cs << makeLocalTypeName(op);
+ }
+ cs << "</returns>" << m_endl;
+
+ }
+
+ // method visibility
+ cs << m_container_indent << m_indentation;
+ if (!isInterface) {
+ if (!isOverride) {
+ if (op->getAbstract()) cs << "abstract ";
+ cs << op->getVisibility().toString() << " ";
+ if (op->getStatic()) cs << "static ";
+ }
+ else {
+ // method overriding an abstract parent
+ cs << op->getVisibility().toString() << " override ";
+ if (op->getStatic()) cs << "static ";
+ }
+ }
+
+ // return type (unless constructor, destructor)
+ if (!op->isLifeOperation()) {
+ if (op->getTypeName().isEmpty()) {
+ cs << "void ";
+ }
+ else {
+ cs << makeLocalTypeName(op) << " ";
+ }
+ }
+
+ // method name
+ cs << cleanName(op->getName()) << "(";
+
+ // method parameters
+ int i= atl.count();
+ int j=0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+
+ cs << makeLocalTypeName(at) << " " << cleanName(at->getName());
+
+ // no initial values in C#
+ //<< (!(at->getInitialValue().isEmpty()) ?
+ // (QString(" = ")+at->getInitialValue()) :
+ // QString(""))
+ cs << ((j < i-1)?", ":"");
+ }
+ cs << ")";
+
+ //FIXME: how to control generation of error stub?
+ if (!isInterface && (!op->getAbstract() || isOverride)) {
+ cs << m_endl << m_container_indent << m_indentation << "{" << m_endl;
+ if (generateErrorStub) {
+ cs << m_container_indent << m_indentation << m_indentation;
+ cs << "throw new Exception(\"The method or operation is not implemented.\");" << m_endl;
+ }
+ cs << m_container_indent << m_indentation << "}" << m_endl;
+ }
+ else {
+ cs << ';' << m_endl;
+ }
+ cs << m_endl;
+ }
+}
+
+void CSharpWriter::writeAttributes(UMLClassifier *c, QTextStream &cs) {
+
+ UMLAttributeList atpub, atprot, atpriv, atdefval;
+ atpub.setAutoDelete(false);
+ atprot.setAutoDelete(false);
+ atpriv.setAutoDelete(false);
+ atdefval.setAutoDelete(false);
+
+ //sort attributes by scope and see if they have a default value
+ UMLAttributeList atl = c->getAttributeList();
+ UMLAttribute *at;
+
+ for (at = atl.first(); at ; at = atl.next()) {
+ if (!at->getInitialValue().isEmpty())
+ atdefval.append(at);
+ switch (at->getVisibility()) {
+ case Uml::Visibility::Public:
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ atpriv.append(at);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (forceSections() || atl.count())
+ cs << m_endl << m_container_indent << m_indentation << "#region Attributes" << m_endl << m_endl;
+
+ // write public attributes
+ if (forceSections() || atpub.count()) {
+ writeAttributes(atpub,cs);
+ }
+
+ // write protected attributes
+ if (forceSections() || atprot.count()) {
+ writeAttributes(atprot,cs);
+ }
+
+ // write private attributes
+ if (forceSections() || atpriv.count()) {
+ writeAttributes(atpriv,cs);
+ }
+
+ if (forceSections() || atl.count())
+ cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
+
+}
+
+
+void CSharpWriter::writeAttributes(UMLAttributeList &atList, QTextStream &cs) {
+
+ for (UMLAttribute *at = atList.first(); at ; at = atList.next()) {
+
+ bool asProperty = true;
+ if (at->getVisibility() == Uml::Visibility::Private) {
+ asProperty = false;
+ }
+ writeAttribute(at->getDoc(), at->getVisibility(), at->getStatic(),
+ makeLocalTypeName(at), at->getName(), at->getInitialValue(), asProperty, cs);
+
+ cs << m_endl;
+ } // end for
+ return;
+}
+
+void CSharpWriter::writeAssociatedAttributes(UMLAssociationList &associated, UMLClassifier *c, QTextStream &cs) {
+
+ UMLAssociation *a;
+ for (a = associated.first(); a ; a = associated.next()) {
+ if (c != a->getObject(Uml::A)) // we need to be at the A side
+ continue;
+
+ UMLObject *o = a->getObject(Uml::B);
+ if (o == NULL) {
+ kError() << "composition role B object is NULL" << endl;
+ continue;
+ }
+ // Take name and documentaton from Role, take type name from the referenced object
+ QString roleName = cleanName(a->getRoleName(Uml::B));
+ QString typeName = cleanName(o->getName());
+ if (roleName.isEmpty()) {
+ roleName = QString("UnnamedRoleB_%1").arg(m_unnamedRoles++);
+ }
+ QString roleDoc = a->getRoleDoc(Uml::B);
+
+ //FIXME:is this simple condition enough?
+ if (a->getMulti(Uml::B).isEmpty() || a->getMulti(Uml::B) == "1") {
+ // normal attribute
+ writeAttribute(roleDoc, a->getVisibility(Uml::B), false, typeName, roleName, "", ( a->getVisibility(Uml::B) != Uml::Visibility::Private), cs);
+ } else {
+ // array
+ roleDoc += "\n(Array of " + typeName + ')';
+ writeAttribute(roleDoc, a->getVisibility(Uml::B), false, "ArrayList", roleName, "", ( a->getVisibility(Uml::B) != Uml::Visibility::Private), cs);
+ }
+ }
+}
+
+void CSharpWriter::writeAttribute(QString doc, Uml::Visibility visibility, bool isStatic, QString typeName, QString name, QString initialValue, bool asProperty, QTextStream &cs) {
+
+ if (forceDoc() || !doc.isEmpty()) {
+
+ cs << m_container_indent << m_indentation << "/// <summary>" << m_endl;
+ cs << formatDoc(doc, m_container_indent + m_indentation + "/// ");
+ cs << m_container_indent << m_indentation << "/// </summary>" << m_endl;
+
+ }
+ cs << m_container_indent << m_indentation;
+ cs << visibility.toString() << " ";
+ if (isStatic) cs << "static ";
+
+ //Variable type with/without namespace path
+ cs << typeName << " ";
+
+ cs << cleanName(name);
+
+ // FIXME: may need a GUI switch to not generate as Property?
+
+ // Generate as Property if not private
+ if (asProperty)
+ {
+ cs << m_endl;
+ cs << m_container_indent << m_indentation << "{" << m_endl;
+ cs << m_container_indent << m_indentation << m_indentation << "get" << m_endl;
+ cs << m_container_indent << m_indentation << m_indentation << "{" << m_endl;
+ cs << m_container_indent << m_indentation << m_indentation << m_indentation << "return m_" << cleanName(name) << ";" << m_endl;
+ cs << m_container_indent << m_indentation << m_indentation << "}" << m_endl;
+
+ cs << m_container_indent << m_indentation << m_indentation << "set" << m_endl;
+ cs << m_container_indent << m_indentation << m_indentation << "{" << m_endl;
+ cs << m_container_indent << m_indentation << m_indentation << m_indentation << "m_" << cleanName(name) << " = value;" << m_endl;
+ cs << m_container_indent << m_indentation << m_indentation << "}" << m_endl;
+ cs << m_container_indent << m_indentation << "}" << m_endl;
+ cs << m_container_indent << m_indentation << "private ";
+ if (isStatic) cs << "static ";
+ cs << typeName << " m_" << cleanName(name);
+ }
+
+ if (!initialValue.isEmpty())
+ cs << " = " << initialValue;
+
+ cs << ";" << m_endl << m_endl;
+}
+
+QString CSharpWriter::makeLocalTypeName(UMLClassifierListItem *cl) {
+ UMLPackage *p = cl->getType()->getUMLPackage();
+ if (m_seenIncludes.findRef(p) != -1) {
+ return cl->getType()->getName();
+ }
+ else {
+ return cl->getTypeName();
+ }
+
+}
+
+/**
+ * returns "C#"
+ */
+Uml::Programming_Language CSharpWriter::getLanguage() {
+ return Uml::pl_CSharp;
+}
+
+const QStringList CSharpWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ for (int i = 0; reserved_words[i]; i++)
+ keywords.append(reserved_words[i]);
+ }
+
+ return keywords;
+}
+
+#include "csharpwriter.moc"
+
diff --git a/umbrello/umbrello/codegenerators/csharpwriter.h b/umbrello/umbrello/codegenerators/csharpwriter.h
new file mode 100644
index 00000000..a6d20f2d
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/csharpwriter.h
@@ -0,0 +1,163 @@
+/***************************************************************************
+ * *
+ * 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) 2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+//
+// C++ Interface: csharpwriter
+//
+// @author Ferenc Veres
+//
+#ifndef CSHARPWRITER_H
+#define CSHARPWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umlattributelist.h"
+#include "../umloperationlist.h"
+#include "../classifierlistitem.h"
+#include "../umlassociationlist.h"
+
+
+/**
+ * class CSharpWriter is a C# code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class CSharpWriter : public SimpleCodeGenerator
+{
+ Q_OBJECT
+public:
+ CSharpWriter();
+
+ virtual ~CSharpWriter();
+ /**
+ * call this method to generate Php code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "C#"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+ /**
+ * get list of predefined data types
+ */
+ QStringList defaultDatatypes();
+
+private:
+
+ /**
+ * we do not want to write the comment "Private methods" twice
+ */
+ bool bPrivateSectionCommentIsWritten;
+
+ /**
+ * Adds extra indenting if the class is in a container (namespace)
+ */
+ QString m_container_indent;
+
+ /**
+ * Collection of included namespaces, to skip them from variable types.
+ */
+ UMLPackageList m_seenIncludes;
+
+ /**
+ * Counts associations without a role name for giving a default name.
+ */
+ int m_unnamedRoles;
+
+ /**
+ * write realizations of a class and recurse to parent classes
+
+ * @param currentClass class to start with
+ * @param realizations realizations of this class
+ * @param cs output stream
+ */
+ void writeRealizationsRecursive(UMLClassifier *currentClass,
+ UMLAssociationList *realizations,
+ QTextStream &cs);
+
+ /**
+ * write all operations for a given class
+ *
+ * @param c the concept we are generating code for
+ * @param cs output stream
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &cs);
+
+ /**
+ * write a list of class operations
+ *
+ * @param opList the list of operations
+ * @param cs output stream
+ * @param interface indicates if the operation is an interface member
+ * @param isOverride implementation of an inherited abstract function
+ */
+ void writeOperations(UMLOperationList opList,
+ QTextStream &cs,
+ bool interface = false,
+ bool isOverride = false,
+ bool generateErrorStub = false);
+
+ /**
+ * write superclasses' abstract methods
+ *
+ * @param superclasses List of superclasses to start recursing on
+ * @param cs output stream
+ */
+ void writeOverridesRecursive(UMLClassifierList *superclasses, QTextStream &cs);
+
+ /** write all the attributes of a class
+ * @param c the class we are generating code for
+ * @param cs output stream
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &cs);
+
+ /** write a list of class attributes
+ * @param atList the list of attributes
+ * @param cs output stream
+ */
+ void writeAttributes(UMLAttributeList &atList, QTextStream &cs);
+
+ /**
+ * write attributes from associated objects (compositions, aggregations)
+ * @param associated list of associated objects
+ * @param c currently written class, to see association direction
+ * @param cs output stream
+ */
+ void writeAssociatedAttributes(UMLAssociationList &associated, UMLClassifier *c, QTextStream &cs);
+
+ /**
+ * write a single attribute to the output stream
+ * @param doc attribute documentation
+ * @param visibility attribute visibility
+ * @param isStatic static attribute
+ * @param typeName class/type of the attribute
+ * @param name name of the attribute
+ * @param initialValue initial value given to the attribute at declaration
+ * @param asProperty true writes as property (get/set), false writes single line variable
+ * @param cs output stream
+ */
+ void writeAttribute(QString doc, Uml::Visibility visibility, bool isStatic, QString typeName, QString name, QString initialValue, bool asProperty, QTextStream &cs);
+
+ /** find the type in used namespaces, if namespace found return short name, complete otherwise.
+ *
+ * @param at Operation or Attribute to check type
+ */
+ QString makeLocalTypeName(UMLClassifierListItem *cl);
+
+};
+
+#endif
diff --git a/umbrello/umbrello/codegenerators/dwriter.cpp b/umbrello/umbrello/codegenerators/dwriter.cpp
new file mode 100644
index 00000000..3e16b136
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/dwriter.cpp
@@ -0,0 +1,970 @@
+
+/***************************************************************************
+ * *
+ * 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) 2007 Jari-Matti Mäkelä <jmjm@iki.fi> *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/***************************************************************************
+ This is the "old" code generator that does not support code editing
+ in the Modeller but uses significantly less file space because the
+ source code is not replicated in the XMI file.
+ ***************************************************************************/
+
+// own header
+#include "dwriter.h"
+// qt includes
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+// kde includes
+#include <kdebug.h>
+// app includes
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../attribute.h"
+#include "../association.h"
+#include "../template.h"
+#include "../umltemplatelist.h"
+#include "codegen_utils.h"
+
+DWriter::DWriter() {
+ startline = m_endl + m_indentation;
+}
+
+DWriter::~DWriter() {}
+
+Uml::Programming_Language DWriter::getLanguage() {
+ return Uml::pl_D;
+}
+
+// FIXME: doesn't work yet
+void DWriter::writeModuleDecl(UMLClassifier *c, QTextStream &d) {
+ if(!c->getPackage().isEmpty())
+ d << "module " << c->getPackage() << ";" << m_endl;
+
+ writeBlankLine(d);
+}
+
+void DWriter::writeModuleImports(UMLClassifier *c, QTextStream &d) {
+ // another preparation, determine what we have
+ UMLAssociationList associations = c->getSpecificAssocs(Uml::at_Association); // BAD! only way to get "general" associations.
+ UMLAssociationList uniAssociations = c->getUniAssociationToBeImplemented();
+
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ bool hasAssociations = aggregations.count() + associations.count() +
+ compositions.count() + uniAssociations.count() > 0;
+
+ if (hasAssociations) {
+ // import tango, if that mode is set
+ writeBlankLine(d);
+ }
+
+ //only import classes in a different package as this class
+ UMLPackageList imports;
+ findObjectsRelated(c, imports);
+ for (UMLPackage *con = imports.first(); con; con = imports.next()) {
+ if (con->getBaseType() == Uml::ot_Datatype)
+ continue;
+ QString pkg = con->getPackage();
+ if (!pkg.isEmpty() && pkg != c->getPackage())
+ d << "import " << pkg << "." << cleanName(con->getName()) << ";"
+ << m_endl;
+ }
+
+ writeBlankLine(d);
+}
+
+void DWriter::writeClass(UMLClassifier *c) {
+ if (!c) {
+ kDebug()<<"Cannot write class of NULL concept!\n";
+ return;
+ }
+
+ isInterface = c->isInterface();
+
+ QString fileName = cleanName(c->getName().lower());
+
+ //find an appropriate name for our file
+ fileName = findFileName(c, ".d");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // check that we may open that file for writing
+ QFile file;
+ if ( !openFile(file, fileName) ) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // open text stream to file
+ QTextStream d(&file);
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".d");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),file.name());
+ d<<str<<m_endl;
+ }
+
+ // source file begins with the module declaration
+ writeModuleDecl(c, d);
+
+ // imports
+ writeModuleImports(c, d);
+
+ // write the opening declaration for the class incl any documentation,
+ // interfaces and/or inheritence issues we have
+ writeClassDecl(c, d);
+
+ // start body of class
+ d << " {" << m_endl;
+
+
+ // Preparations
+ //
+
+ // sort attributes by Scope
+ UMLAttributeList atl;
+ UMLAttributeList atpub, atprot, atpriv, atpkg, atexport;
+ UMLAttributeList final_atpub, final_atprot, final_atpriv, final_atpkg, final_atexport;
+
+ atpub.setAutoDelete(false);
+ final_atpub.setAutoDelete(false);
+ atprot.setAutoDelete(false);
+ final_atprot.setAutoDelete(false);
+ atpriv.setAutoDelete(false);
+ final_atpriv.setAutoDelete(false);
+ atpkg.setAutoDelete(false);
+ final_atpkg.setAutoDelete(false);
+ atexport.setAutoDelete(false);
+ final_atexport.setAutoDelete(false);
+
+ if (!isInterface) {
+ UMLAttributeList atl = c->getAttributeList();
+ for (UMLAttribute *at = atl.first(); at ; at = atl.next()) {
+ switch(at->getVisibility())
+ {
+ case Uml::Visibility::Public:
+ if(at->getStatic())
+ final_atpub.append(at);
+ else
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ if(at->getStatic())
+ final_atprot.append(at);
+ else
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ if(at->getStatic())
+ final_atpriv.append(at);
+ else
+ atpriv.append(at);
+ break;/* TODO: requires support from the gui & other structures
+ case Uml::Visibility::Package:
+ if(at->getStatic())
+ final_atpkg.append(at);
+ else
+ atpkg.append(at);
+ break;
+ case Uml::Visibility::Export:
+ if(at->getStatic())
+ final_atexport.append(at);
+ else
+ atexport.append(at);
+ break;*/
+ default:
+ break;
+ }
+ }
+ }
+
+ // another preparation, determine what we have
+ UMLAssociationList associations = c->getSpecificAssocs(Uml::at_Association); // BAD! only way to get "general" associations.
+ UMLAssociationList uniAssociations = c->getUniAssociationToBeImplemented();
+
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ bool hasAssociations = aggregations.count() + associations.count() + compositions.count() + uniAssociations.count() > 0;
+ bool hasAttributes = atl.count() > 0;
+ bool hasAccessorMethods = hasAttributes || hasAssociations;
+ bool hasOperationMethods = c->getOpList().count() > 0;
+
+ // ATTRIBUTES
+ //
+
+ // write comment for section IF needed
+ if (forceDoc() || hasAccessorMethods)
+ {
+ writeComment("", m_indentation, d);
+ writeComment("Fields", m_indentation, d);
+ writeComment("", m_indentation, d);
+ writeBlankLine(d);
+ }
+
+ writeAttributeDecls(final_atpub, final_atprot, final_atpriv, d);
+ writeAttributeDecls(atpub, atprot, atpriv, d);
+
+ writeAssociationDecls(associations, c->getID(), d);
+ writeAssociationDecls(uniAssociations, c->getID(), d);
+ writeAssociationDecls(aggregations, c->getID(), d);
+ writeAssociationDecls(compositions, c->getID(), d);
+
+ //FIXME: find constructors and write them here
+
+ // write constructors
+ if(!isInterface) writeConstructor(c, d);
+
+
+ // METHODS
+ //
+
+ // write comment for sub-section IF needed
+ if (forceDoc() || hasAccessorMethods ) {
+ writeComment("", m_indentation, d);
+ writeComment("Accessors", m_indentation, d);
+ writeComment("", m_indentation, d);
+ writeBlankLine(d);
+ }
+
+
+ // Accessors for attributes
+ writeAttributeMethods(final_atpub, Uml::Visibility::Public, d);
+ writeAttributeMethods(final_atprot, Uml::Visibility::Protected, d);
+ writeAttributeMethods(final_atpriv, Uml::Visibility::Private, d);
+ writeAttributeMethods(atpub, Uml::Visibility::Public, d);
+ writeAttributeMethods(atprot, Uml::Visibility::Protected, d);
+ writeAttributeMethods(atpriv, Uml::Visibility::Private, d);
+
+ // accessor methods for associations
+
+ // first: determine the name of the other class
+ writeAssociationMethods(associations, c, d);
+ writeAssociationMethods(uniAssociations, c, d);
+ writeAssociationMethods(aggregations, c, d);
+ writeAssociationMethods(compositions, c, d);
+
+ // Other operation methods
+ // all other operations are now written
+
+ // write comment for sub-section IF needed
+ if (forceDoc() || hasOperationMethods) {
+ writeComment("", m_indentation, d);
+ writeComment("Other methods", m_indentation, d);
+ writeComment("", m_indentation, d);
+ writeBlankLine(d);
+ }
+
+ writeOperations(c, d);
+
+ d << "}" << m_endl; // end class
+
+ file.close();
+ emit codeGenerated(c, true);
+}
+
+void DWriter::writeClassDecl(UMLClassifier *c, QTextStream &d) {
+
+ // class documentation
+ if (!c->getDoc().isEmpty()) {
+ writeDocumentation("", c->getDoc(), "", "", d);
+ }
+
+ /*
+ * Class declaration
+ *
+ * (private) class foo(T, ..., Z) : class1, ..., classN, interface1, ..., interfaceN
+ * a b c d e f g
+ */
+
+ // (a) visibility modifier
+ switch(c->getVisibility()) {
+ case Uml::Visibility::Private: d << "private "; break;
+ default: break;
+ }
+
+ // (b) keyword
+ // TODO what about structs?
+ if (isInterface) {
+ d << "interface ";
+ } else {
+ if (c->getAbstract()) {
+ d << "abstract ";
+ }
+
+ d << "class ";
+ }
+
+ // (c) class name
+ QString classname = cleanName(c->getName()); // our class name
+ d << classname;
+
+ // (d) template parameters
+ UMLTemplateList template_params = c->getTemplateList();
+ if (template_params.count()) {
+ d << "(";
+
+ for (UMLTemplate *t = template_params.first(); t; ) {
+ // TODO: hm, leaving the type blank results in "class"
+ // so we omit it (also because "class" in this context is illegal)
+ if (t->getTypeName() != "class") {
+ d << t->getTypeName();
+ d << " ";
+ }
+
+ d << t->getName();
+
+ if ((t = template_params.next()) != NULL)
+ d << ", ";
+ }
+
+ d << ")";
+ }
+
+ // (e) inheritances
+ UMLClassifierList superclasses =
+ c->findSuperClassConcepts(UMLClassifier::CLASS);
+ UMLClassifierList superinterfaces =
+ c->findSuperClassConcepts(UMLClassifier::INTERFACE);
+
+ int count = superclasses.count() + superinterfaces.count();
+
+ if (count > 0) {
+ d << " : ";
+
+ // (f) base classes
+ for (UMLClassifier * concept= superclasses.first(); concept; concept = superclasses.next()) {
+ d << cleanName(concept->getName());
+
+ count--;
+
+ if (count>0) d << ", ";
+ }
+
+ // (g) interfaces
+ for (UMLClassifier * concept= superinterfaces.first(); concept; concept = superinterfaces.next()) {
+ d << cleanName(concept->getName());
+
+ count--;
+
+ if (count>0) d << ", ";
+ }
+ }
+}
+
+void DWriter::writeProtectionMod(Uml::Visibility visibility, QTextStream &d) {
+ d << m_indentation << scopeToDDecl(visibility) << ":" << m_endl << m_endl;
+}
+
+void DWriter::writeAttributeDecl(Uml::Visibility visibility, UMLAttributeList &atlist, QTextStream &d) {
+ if (atlist.count()==0) return;
+
+ writeProtectionMod(visibility, d);
+
+ for(UMLAttribute *at=atlist.first(); at; at=atlist.next()) {
+ // documentation
+ if (!at->getDoc().isEmpty()) {
+ writeComment(at->getDoc(), m_indentation, d, true);
+ }
+
+ d << m_indentation;
+
+ // static attribute?
+ if (at->getStatic()) d << "static ";
+
+ // method return type
+ d << fixTypeName(at->getTypeName()) << " ";
+
+ // TODO: find out whether this class has accessors or not
+ bool hasAccessorMethods = true;
+
+ // attribute name
+ if (hasAccessorMethods) {
+ d << "m_";
+ }
+ d << cleanName(at->getName());
+
+ // initial value
+ QString initVal = fixInitialStringDeclValue(at->getInitialValue(), at->getTypeName());
+ if (!initVal.isEmpty()) d << " = " << initVal;
+ d << ";" << m_endl << m_endl;
+ }
+}
+
+void DWriter::writeAttributeDecls(UMLAttributeList &atpub, UMLAttributeList &atprot,
+ UMLAttributeList &atpriv, QTextStream &d ) {
+
+ writeAttributeDecl(Uml::Visibility::Public, atpub, d);
+ writeAttributeDecl(Uml::Visibility::Protected, atprot, d);
+ writeAttributeDecl(Uml::Visibility::Private, atpriv, d);
+ //TODO: export and package
+}
+
+void DWriter::writeAttributeMethods(UMLAttributeList &atpub, Uml::Visibility visibility, QTextStream &d) {
+ if (atpub.count()==0) return;
+
+ writeProtectionMod(visibility, d);
+
+ for(UMLAttribute *at=atpub.first(); at; at=atpub.next()) {
+ QString fieldName = cleanName(at->getName());
+ writeSingleAttributeAccessorMethods(
+ at->getTypeName(), "m_" + fieldName, fieldName, at->getDoc(),
+ visibility, Uml::chg_Changeable, at->getStatic(), d);
+ }
+}
+
+void DWriter::writeComment(const QString &comment, const QString &myIndent,
+ QTextStream &d, bool dDocStyle) {
+ if(dDocStyle) {
+ d << myIndent << "/**" << m_endl;
+ }
+
+ QStringList lines = QStringList::split("\n", comment);
+
+ if (lines.count() == 0) lines << comment;
+
+ for (uint i = 0; i < lines.count(); ++i) {
+ QString tmp = lines[i];
+
+ while (tmp.length() > 77) {
+ uint l = tmp.left(77).findRev(' ');
+ if (l < 1) l = tmp.find(' ', 77);
+ if (l < 1 || l > tmp.length()) {
+ d << myIndent << (dDocStyle ? " * " : "// ") << tmp << m_endl;
+ break;
+ }
+ d << myIndent << (dDocStyle ? " * " : "// ") << tmp.left(l) << m_endl;
+ tmp = tmp.right(tmp.length() - l);
+ }
+
+ d << myIndent << (dDocStyle ? " * " : "// ") << tmp << m_endl;
+ }
+
+ if(dDocStyle) {
+ d << myIndent << " */" << m_endl;
+ }
+}
+
+void DWriter::writeDocumentation(QString header, QString body, QString end, QString indent, QTextStream &d) {
+ d << indent << "/**" << m_endl;
+ if (!header.isEmpty())
+ d << formatDoc(header, indent+" * ");
+ if (!body.isEmpty())
+ d << formatDoc(body, indent+" * ");
+ if (!end.isEmpty())
+ {
+ QStringList lines = QStringList::split( "\n", end);
+ for (uint i= 0; i < lines.count(); i++)
+ d << formatDoc(lines[i], indent + " * ");
+ }
+ d<<indent<< " */" << m_endl;
+}
+
+void DWriter::writeAssociationDecls(UMLAssociationList associations, Uml::IDType id, QTextStream &d) {
+
+ if( forceSections() || !associations.isEmpty() )
+ {
+ bool printRoleA = false, printRoleB = false;
+ for(UMLAssociation *a = associations.first(); a; a = associations.next())
+ {
+ // it may seem counter intuitive, but you want to insert the role of the
+ // *other* class into *this* class.
+ if (a->getObjectId(Uml::A) == id)
+ printRoleB = true;
+
+ if (a->getObjectId(Uml::B) == id)
+ printRoleA = true;
+
+ // First: we insert documentaion for association IF it has either role AND some documentation (!)
+ if ((printRoleA || printRoleB) && !(a->getDoc().isEmpty()))
+ writeComment(a->getDoc(), m_indentation, d);
+
+ // print RoleB decl
+ if (printRoleB)
+ {
+ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::B)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::B), a->getMulti(Uml::B), a->getRoleDoc(Uml::B), a->getVisibility(Uml::B), d);
+ }
+
+ // print RoleA decl
+ if (printRoleA)
+ {
+ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::A)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::A), a->getMulti(Uml::A), a->getRoleDoc(Uml::A), a->getVisibility(Uml::A), d);
+ }
+ }
+ }
+}
+
+void DWriter::writeAssociationRoleDecl(QString fieldClassName,
+ QString roleName, QString multi,
+ QString doc, Uml::Visibility /*visib*/, QTextStream &d) {
+ // ONLY write out IF there is a rolename given
+ // otherwise its not meant to be declared in the code
+ if (roleName.isEmpty()) return;
+
+ if (!doc.isEmpty()) {
+ writeComment(doc, m_indentation, d);
+ }
+
+ bool hasAccessors = true;
+
+ // declare the association based on whether it is this a single variable
+ // or a List (Vector). One day this will be done correctly with special
+ // multiplicity object that we don't have to figure out what it means via regex.
+ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$"))) {
+ d << m_indentation << fieldClassName << " ";
+
+ if (hasAccessors) d << "m_";
+
+ d << deCapitaliseFirstLetter(roleName) << ";";
+ } else {
+ d << m_indentation << fieldClassName << "[] ";
+ //TODO: templated containers
+
+ if (hasAccessors) d << "m_";
+
+ d << pluralize(deCapitaliseFirstLetter(roleName)) << ";";
+ // from here we could initialize default values, or put in an init() section
+ // of the constructors
+ }
+
+ // always put space between this and following decl, if any
+ writeBlankLine(d);
+}
+
+void DWriter::writeAssociationMethods (UMLAssociationList associations, UMLClassifier *thisClass, QTextStream &d) {
+ if( forceSections() || !associations.isEmpty() ) {
+ for(UMLAssociation *a = associations.first(); a; a = associations.next()) {
+ // insert the methods to access the role of the other
+ // class in the code of this one
+ if (a->getObjectId(Uml::A) == thisClass->getID()) {
+ // only write out IF there is a rolename given
+ if(!a->getRoleName(Uml::B).isEmpty()) {
+ QString fieldClassName = getUMLObjectName(a->getObject(Uml::B));
+ writeAssociationRoleMethod(fieldClassName,
+ a->getRoleName(Uml::B),
+ a->getMulti(Uml::B), a->getRoleDoc(Uml::B),
+ a->getVisibility(Uml::B),
+ a->getChangeability(Uml::B), d);
+ }
+ }
+
+ if (a->getObjectId(Uml::B) == thisClass->getID()) {
+ // only write out IF there is a rolename given
+ if(!a->getRoleName(Uml::A).isEmpty()) {
+ QString fieldClassName = getUMLObjectName(a->getObject(Uml::A));
+ writeAssociationRoleMethod(fieldClassName, a->getRoleName(Uml::A),
+ a->getMulti(Uml::A),
+ a->getRoleDoc(Uml::A),
+ a->getVisibility(Uml::A),
+ a->getChangeability(Uml::A),
+ d);
+ }
+ }
+ }
+ }
+}
+
+void DWriter::writeAssociationRoleMethod (QString fieldClassName, QString roleName, QString multi,
+ QString description, Uml::Visibility visib, Uml::Changeability_Type change,
+ QTextStream &d) {
+ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$"))) {
+ QString fieldVarName = "m_" + deCapitaliseFirstLetter(roleName);
+
+ writeSingleAttributeAccessorMethods(
+ fieldClassName, fieldVarName, roleName, description, visib, change, false, d);
+ } else {
+ QString fieldVarName = "m_" + pluralize(deCapitaliseFirstLetter(roleName));
+
+ writeVectorAttributeAccessorMethods(
+ fieldClassName, fieldVarName, pluralize(roleName), description, visib, change, d);
+ }
+}
+
+void DWriter::writeVectorAttributeAccessorMethods (QString fieldClassName, QString fieldVarName,
+ QString fieldName, QString description,
+ Uml::Visibility /*visibility*/, Uml::Changeability_Type changeType,
+ QTextStream &d) {
+
+ fieldClassName = fixTypeName(fieldClassName);
+ QString fieldNameUP = unPluralize(fieldName);
+ QString fieldNameUC = Codegen_Utils::capitalizeFirstLetter(fieldNameUP);
+
+ // ONLY IF changeability is NOT Frozen
+ if (changeType != Uml::chg_Frozen) {
+ writeDocumentation("Adds a " + fieldNameUP + " to the list of " +
+ fieldName + '.', description, "", m_indentation, d);
+
+ d << m_indentation << "void add" << fieldNameUC << "(";
+ d << fieldClassName << " new" << fieldNameUC << ") {";
+ d << startline << m_indentation << fieldVarName << " ~= new" << fieldNameUC << ";";
+ d << startline << "}" << m_endl << m_endl;
+ }
+
+ // ONLY IF changeability is Changeable
+ if (changeType == Uml::chg_Changeable) {
+ writeDocumentation("Removes a " + fieldNameUP + " from the list of " +
+ fieldName + '.', description, "", m_indentation, d);
+
+ d << m_indentation << "void remove" << fieldNameUC << "(";
+ d << fieldClassName << " " << fieldNameUP << ") {" << startline;
+ d << m_indentation << "int idx = " << fieldVarName << ".length;" << startline;
+ d << m_indentation << "foreach(i, o; " << fieldVarName << ")" << startline;
+ d << m_indentation << m_indentation << "if (o && o == " << fieldNameUP << ") {" << startline;
+ d << m_indentation << m_indentation << m_indentation << "idx = i;" << startline;
+ d << m_indentation << m_indentation << m_indentation << "break;" << startline;
+ d << m_indentation << m_indentation << "}" << m_endl << startline;
+ d << m_indentation << fieldVarName << " = " << fieldVarName;
+ d << "[0..idx] ~ " << fieldVarName << "[idx..$];" << startline;
+ d << "}" << m_endl << m_endl;
+ }
+
+ // always allow getting the list of stuff
+ writeDocumentation("Returns the list of " + fieldName + '.',
+ description, "@return List of " + fieldName + '.',
+ m_indentation, d);
+
+ d << m_indentation << fieldClassName << "[] get" << fieldName << "() {";
+ d << startline << m_indentation << "return " << fieldVarName << ";";
+ d << startline << "}" << m_endl << m_endl;
+}
+
+
+void DWriter::writeSingleAttributeAccessorMethods(QString fieldClassName,
+ QString fieldVarName, QString fieldName, QString description, Uml::Visibility /*visibility*/,
+ Uml::Changeability_Type change, bool isFinal, QTextStream &d) {
+
+ fieldClassName = fixTypeName(fieldClassName);
+ QString fieldNameUC = Codegen_Utils::capitalizeFirstLetter(fieldName);
+ if (fieldName.left(2) == "m_") fieldName = fieldName.right(fieldName.length()-2);
+
+ // set method
+ if (change == Uml::chg_Changeable && !isFinal) {
+ writeDocumentation("Sets the value of " + fieldName + '.', description,
+ "@param new" + fieldNameUC + " The new value of " + fieldName + '.',
+ m_indentation, d);
+
+ d << m_indentation << fieldClassName << " " << fieldName << "(";
+ d << fieldClassName << " new" << fieldNameUC << ") {";
+ d << startline << m_indentation << "return " << fieldVarName << " = new" << fieldNameUC << ";";
+ d << startline << "}" << m_endl << m_endl;
+ }
+
+ // get method
+ writeDocumentation("Returns the value of " + fieldName + '.', description,
+ "@return The value of " + fieldName + '.',
+ m_indentation, d);
+
+ d << m_indentation << fieldClassName << " " << fieldName << "() {";
+ d << startline << m_indentation << "return " << fieldVarName << ";";
+ d << startline << "}" << m_endl << m_endl;
+}
+
+void DWriter::writeConstructor(UMLClassifier *c, QTextStream &d) {
+
+ if (forceDoc())
+ {
+ d<<startline;
+ writeComment("", m_indentation, d);
+ writeComment("Constructors", m_indentation, d);
+ writeComment("", m_indentation, d);
+ writeBlankLine(d);
+ }
+
+ // write the first constructor
+ QString className = cleanName(c->getName());
+ d << m_indentation << "public this("<<") { }";
+
+}
+
+// IF the type is "string" we need to declare it as
+// the D Object "String" (there is no string primative in D).
+// Same thing again for "bool" to "boolean"
+QString DWriter::fixTypeName(const QString& string) {
+ if (string.isEmpty())
+ return "void";
+ if (string == "string")
+ return "char[]";
+ if (string == "unsigned short")
+ return "ushort";
+ if (string == "unsigned int")
+ return "uint";
+ if (string == "unsigned long")
+ return "ulong";
+ return string;
+}
+
+QStringList DWriter::defaultDatatypes() {
+ QStringList l;
+ l << "void"
+ << "bool"
+ << "byte"
+ << "ubyte"
+ << "short"
+ << "ushort"
+ << "int"
+ << "uint"
+ << "long"
+ << "ulong"
+ << "cent"
+ << "ucent"
+ << "float"
+ << "double"
+ << "real"
+ << "ifloat"
+ << "idouble"
+ << "ireal"
+ << "cfloat"
+ << "cdouble"
+ << "creal"
+ << "char"
+ << "wchar"
+ << "dchar";
+ return l;
+}
+
+
+bool DWriter::compareDMethod(UMLOperation *op1, UMLOperation *op2) {
+ if (op1 == NULL || op2 == NULL)
+ return false;
+ if (op1 == op2)
+ return true;
+ if (op1->getName() != op2->getName())
+ return false;
+ UMLAttributeList atl1 = op1->getParmList();
+ UMLAttributeList atl2 = op2->getParmList();
+ if (atl1.count() != atl2.count())
+ return false;
+ UMLAttribute *at1;
+ UMLAttribute *at2;
+ for (at1 = atl1.first(), at2 = atl2.first(); at1 && at2 ; at1 = atl1.next(),at2 = atl2.next())
+ {
+ if (at1->getTypeName() != at2->getTypeName())
+ return false;
+ }
+ return true;
+
+}
+
+bool DWriter::dMethodInList(UMLOperation *umlOp, UMLOperationList &opl) {
+ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
+ if (DWriter::compareDMethod(op, umlOp)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void DWriter::getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath) {
+ UMLClassifierList superClasses = c->findSuperClassConcepts();
+
+ for (UMLClassifier *concept= superClasses.first(); concept; concept = superClasses.next())
+ {
+ getSuperImplementedOperations(concept, yetImplementedOpList, toBeImplementedOpList, (concept->isInterface() && noClassInPath));
+ UMLOperationList opl = concept->getOpList();
+ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
+ if (concept->isInterface() && noClassInPath) {
+ if (!DWriter::dMethodInList(op,toBeImplementedOpList))
+ toBeImplementedOpList.append(op);
+ }
+ else
+ {
+ if (!DWriter::dMethodInList(op, yetImplementedOpList))
+ yetImplementedOpList.append(op);
+ }
+ }
+ }
+
+}
+
+void DWriter::getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opList ) {
+ UMLOperationList yetImplementedOpList;
+ UMLOperationList toBeImplementedOpList;
+
+ getSuperImplementedOperations(c,yetImplementedOpList, toBeImplementedOpList);
+ for (UMLOperation *op = toBeImplementedOpList.first(); op; op = toBeImplementedOpList.next())
+ {
+ if ( ! DWriter::dMethodInList(op, yetImplementedOpList) && ! DWriter::dMethodInList(op, opList) )
+ opList.append(op);
+ }
+}
+
+void DWriter::writeOperations(UMLClassifier *c, QTextStream &d) {
+ UMLOperationList opl;
+ UMLOperationList oppub,opprot,oppriv;
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ opl = c->getOpList();
+ if (! c->isInterface()) {
+ getInterfacesOperationsToBeImplemented(c, opl);
+ }
+ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default: //TODO: package, export
+ break;
+ }
+ }
+
+ // do people REALLY want these comments? Hmm.
+ /*
+ if(forceSections() || oppub.count())
+ {
+ writeComment("public operations",m_indentation,d);
+ writeBlankLine(d);
+ }
+ */
+
+ if (oppub.count() > 0) {
+ writeProtectionMod(Uml::Visibility::Public, d);
+
+ writeOperations(oppub,d);
+ }
+
+ if (opprot.count() > 0) {
+ writeProtectionMod(Uml::Visibility::Protected, d);
+
+ writeOperations(opprot, d);
+ }
+
+ if (oppriv.count() > 0) {
+ writeProtectionMod(Uml::Visibility::Private, d);
+
+ writeOperations(oppriv, d);
+ }
+
+}
+
+void DWriter::writeOperations(UMLOperationList &oplist, QTextStream &d) {
+ UMLAttributeList atl;
+ QString str;
+
+ // generate method decl for each operation given
+ for(UMLOperation *op=oplist.first(); op; op=oplist.next()) {
+ QString returnStr = "";
+ // write documentation
+
+ QString methodReturnType = fixTypeName(op->getTypeName());
+
+ //TODO: return type comment
+ if(methodReturnType != "void") {
+ returnStr += "@return " + methodReturnType + m_endl;
+ }
+
+ str = ""; // reset for next method
+ if (op->getAbstract() && !isInterface) str += "abstract ";
+ if (op->getStatic()) str += "static ";
+
+ str += methodReturnType + ' ' +cleanName(op->getName()) + '(';
+
+ atl = op->getParmList();
+ int i = atl.count();
+ int j = 0;
+ for (UMLAttribute *at = atl.first(); at; at = atl.next(), j++) {
+ QString typeName = fixTypeName(at->getTypeName());
+ QString atName = cleanName(at->getName());
+ str += typeName + ' ' + atName +
+ (!(at->getInitialValue().isEmpty()) ?
+ (QString(" = ")+at->getInitialValue()) :
+ QString(""))
+ + ((j < i-1)?", ":"");
+ returnStr += "@param " + atName+' '+at->getDoc() + m_endl;
+ }
+
+ str+= ')';
+
+ // method only gets a body IF its not abstract
+ if (op->getAbstract() || isInterface)
+ str += ';'; // terminate now
+ else
+ str += startline + '{' + startline + '}'; // empty method body
+
+ // write it out
+ writeDocumentation("", op->getDoc(), returnStr, m_indentation, d);
+ d << m_indentation << str << m_endl << m_endl;
+ }
+}
+
+QString DWriter::fixInitialStringDeclValue(QString value, QString type) {
+ // check for strings only
+ if (!value.isEmpty() && type == "String") {
+ if (!value.startsWith("\""))
+ value.prepend("\"");
+ if (!value.endsWith("\""))
+ value.append("\"");
+ }
+ return value;
+}
+
+QString DWriter::scopeToDDecl(Uml::Visibility scope) {
+ QString scopeString;
+
+ switch(scope) {
+ case Uml::Visibility::Public: scopeString = "public"; break;
+ case Uml::Visibility::Protected: scopeString = "protected"; break;
+ case Uml::Visibility::Private: scopeString = "private"; break;
+ default: break; //TODO: package and export
+ }
+
+ return scopeString;
+}
+
+// methods like this _shouldn't_ be needed IF we properly did things thruought the code.
+QString DWriter::getUMLObjectName(UMLObject *obj) {
+ return(obj!=0)?obj->getName():QString("NULL");
+}
+
+QString DWriter::deCapitaliseFirstLetter(QString string) {
+ string.replace( 0, 1, string[0].lower());
+ return string;
+}
+
+QString DWriter::pluralize(QString string) {
+ return string + (string.right(1) == "s" ? "es" : "s");
+}
+
+QString DWriter::unPluralize(QString string) {
+ // does not handle special cases liek datum -> data, etc.
+
+ if (string.length() > 2 && string.right(3) == "ses") {
+ return string.left(string.length() - 2);
+ }
+
+ if (string.right(1) == "s") {
+ return string.left(string.length() - 1);
+ }
+
+ return string;
+}
+
+void DWriter::writeBlankLine(QTextStream &d) {
+ d << m_endl;
+}
+
diff --git a/umbrello/umbrello/codegenerators/dwriter.h b/umbrello/umbrello/codegenerators/dwriter.h
new file mode 100644
index 00000000..38828359
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/dwriter.h
@@ -0,0 +1,276 @@
+
+/***************************************************************************
+ * *
+ * 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) 2007 Jari-Matti Mäkelä <jmjm@iki.fi> *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/***************************************************************************
+ This is the "old" code generator that does not support code editing
+ in the Modeller but uses significantly less file space because the
+ source code is not replicated in the XMI file.
+ ***************************************************************************/
+
+#ifndef DWRITER_H
+#define DWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umloperationlist.h"
+#include "../umlattributelist.h"
+#include "../umlassociationlist.h"
+
+class UMLOperation;
+
+/**
+ * class DWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate a d source file for
+ * that concept
+ */
+class DWriter : public SimpleCodeGenerator {
+public:
+
+ /**
+ * Constructor, initialises a couple of variables
+ */
+ DWriter();
+
+ /**
+ * Destructor, empty
+ */
+ virtual ~DWriter();
+
+ /**
+ * call this method to generate d code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "D"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * Overrides method from class CodeGenerator
+ */
+ QStringList defaultDatatypes();
+
+private:
+
+ /**
+ * Writes the module declaration.
+ */
+ void writeModuleDecl(UMLClassifier *c, QTextStream &d);
+
+ /**
+ * Writes the module imports.
+ */
+ void writeModuleImports(UMLClassifier *c, QTextStream &d);
+
+ /**
+ * Writes class's documentation then the class header
+ * public abstract class Foo extents {
+ */
+ void writeClassDecl(UMLClassifier *c, QTextStream &d);
+
+ /**
+ * Writes the comment and class constructor
+ */
+ void writeConstructor(UMLClassifier *c, QTextStream &d);
+
+ /**
+ * return true if the two operations have the same name and the same parameters
+ * @param op1 first operation to be compared
+ * @param op2 second operation to be compared
+ */
+ static bool compareDMethod(UMLOperation *op1, UMLOperation *op2);
+
+ /**
+ * return true if the operation is in the list
+ * @param umlOp operation to be searched
+ * @param opl list of operations
+ */
+ static bool dMethodInList(UMLOperation *umlOp, UMLOperationList &opl);
+
+ /**
+ * get all operations which a given class inherit from all its super interfaces and get all operations
+ * which this given class inherit from all its super classes
+ * @param c the class for which we are generating code
+ * @param yetImplementedOpList the list of yet implemented operations
+ * @param toBeImplementedOpList the list of to be implemented operations
+ * @param noClassInPath tells if there is a class between the base class and the current interface
+ */
+ void getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath = true);
+
+ /**
+ * get all operations which a given class inherit from all its super interfaces and that should be implemented
+ * @param c the class for which we are generating code
+ * @param opl the list of operations used to append the operations
+ */
+ void getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opl);
+
+ /**
+ * write all operations for a given class
+ * @param c the class for which we are generating code
+ * @param j the stream associated with the output file
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &j);
+
+ /**
+ * write a list of operations for a given class
+ * @param list the list of operations you want to write
+ * @param j the stream associated with the output file
+ */
+ void writeOperations(UMLOperationList &list, QTextStream &j);
+
+ /**
+ * write all attributes for a given class
+ * @param c the class for which we are generating code
+ * @param j the stream associated with the output file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &j);
+
+ /**
+ * Writes the protection modifier line.
+ * @param visibility protection modifier
+ * @param d text stream
+ */
+ void writeProtectionMod(Uml::Visibility visibility, QTextStream &d);
+
+ /**
+ * Writes attribute declarations with a specific
+ * protection modifier.
+ * @param prot the protection modifier
+ * @param atlist attribute list
+ * @param d text stream
+ */
+ void writeAttributeDecl(Uml::Visibility visibility, UMLAttributeList &atlist, QTextStream &d);
+
+ /**
+ * writes the Attribute declarations
+ * @param atpub List of public attributes
+ * @param atprot list of protected attributes
+ * @param atpriv list of private attributes
+ * @param d text stream
+ */
+ void writeAttributeDecls(UMLAttributeList &atpub, UMLAttributeList &atprot,
+ UMLAttributeList &atpriv, QTextStream &d );
+
+ /**
+ * Searches a list of associations for appropriate ones to write out as attributes
+ */
+ void writeAssociationDecls(UMLAssociationList associations, Uml::IDType id, QTextStream &d);
+
+ /**
+ * Writes out an association as an attribute using Vector
+ */
+ void writeAssociationRoleDecl(QString fieldClassName, QString roleName, QString multi,
+ QString doc, Uml::Visibility visib, QTextStream &d);
+
+ /**
+ * calls @ref writeSingleAttributeAccessorMethods() on each of the attributes in atpub
+ */
+ void writeAttributeMethods(UMLAttributeList &atpub, Uml::Visibility visibility, QTextStream &d);
+
+ /**
+ * calls @ref writeAssociationRoleMethod() on each of the associations in the given list
+ */
+ void writeAssociationMethods(UMLAssociationList associations, UMLClassifier *thisClass,
+ QTextStream &d);
+
+ /**
+ * calls @ref writeSingleAttributeAccessorMethods() or @ref
+ * writeVectorAttributeAccessorMethods() on the assocaition
+ * role
+ */
+ void writeAssociationRoleMethod(QString fieldClassName, QString roleName, QString multi,
+ QString description, Uml::Visibility visib, Uml::Changeability_Type change,
+ QTextStream &d);
+
+ /**
+ * Writes getFoo() and setFoo() accessor methods for the attribute
+ */
+ void writeSingleAttributeAccessorMethods(QString fieldClassName, QString fieldVarName,
+ QString fieldName, QString description,
+ Uml::Visibility visibility, Uml::Changeability_Type change,
+ bool isFinal, QTextStream &d);
+
+ /**
+ * Writes addFoo() and removeFoo() accessor methods for the Vector attribute
+ */
+ void writeVectorAttributeAccessorMethods(QString fieldClassName, QString fieldVarName,
+ QString fieldName, QString description,
+ Uml::Visibility visibility, Uml::Changeability_Type change,
+ QTextStream &d);
+
+ /**
+ * Writes a // style comment
+ */
+ void writeComment(const QString &text, const QString &indent, QTextStream &d, bool dDocStyle=false);
+
+ /**
+ * Writes a documentation comment
+ */
+ void writeDocumentation(QString header, QString body, QString end, QString indent, QTextStream &d);
+
+ /**
+ * Returns the name of the given object (if it exists)
+ */
+ QString getUMLObjectName(UMLObject *obj);
+
+ /**
+ * Lowers the case of the first letter in the given string
+ */
+ QString deCapitaliseFirstLetter(QString string);
+
+ /**
+ * Returns the plural form of a subject.
+ */
+ QString pluralize(QString string);
+
+ /**
+ * Returns the non-plural form of a subject.
+ */
+ QString unPluralize(QString string);
+
+ /**
+ * Replaces `string' with `String' and `bool' with `boolean'
+ */
+ QString fixTypeName(const QString& string);
+
+ /**
+ * check that initial values of strings have quotes around them
+ */
+ QString fixInitialStringDeclValue(QString value, QString type);
+
+ /**
+ * Write a blank line
+ */
+ void writeBlankLine(QTextStream& d);
+
+ /**
+ * a little method for converting scope to string value
+ */
+ QString scopeToDDecl(Uml::Visibility scope);
+
+ /**
+ * A \n, used at the end of each line
+ */
+ QString startline;
+
+ /**
+ * Whether or not this concept is an interface.
+ */
+ bool isInterface;
+
+};
+
+
+#endif // DWRITER_H
+
diff --git a/umbrello/umbrello/codegenerators/idlwriter.cpp b/umbrello/umbrello/codegenerators/idlwriter.cpp
new file mode 100644
index 00000000..a893acc3
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/idlwriter.cpp
@@ -0,0 +1,482 @@
+/***************************************************************************
+ * copyright (C) 2003-2005 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "idlwriter.h"
+
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../enum.h"
+#include "../classifierlistitem.h"
+#include "../umlclassifierlistitemlist.h"
+#include "../package.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+
+IDLWriter::IDLWriter() : SimpleCodeGenerator(false) {
+}
+
+IDLWriter::~IDLWriter() {}
+
+bool IDLWriter::isOOClass(UMLClassifier *c) {
+ QString stype = c->getStereotype();
+ if (stype == "CORBAConstant" || stype == "CORBAEnum" ||
+ stype == "CORBAStruct" || stype == "CORBAUnion" ||
+ stype == "CORBASequence" || stype == "CORBAArray" ||
+ stype == "CORBATypedef")
+ return false;
+
+ // CORBAValue, CORBAInterface, and all empty/unknown stereotypes are
+ // assumed to be OO classes.
+ return true;
+}
+
+bool IDLWriter::assocTypeIsMappableToAttribute(Uml::Association_Type at) {
+ return (at == Uml::at_Aggregation || at == Uml::at_Association ||
+ at == Uml::at_Composition || at == Uml::at_UniAssociation);
+}
+
+/**
+ * returns "IDL"
+ */
+Uml::Programming_Language IDLWriter::getLanguage() {
+ return Uml::pl_IDL;
+}
+
+void IDLWriter::computeAssocTypeAndRole
+(UMLAssociation *a, UMLClassifier *c, QString& typeName, QString& roleName)
+{
+ // Determine which is the "remote" end of the association:
+ bool IAmRoleA = true;
+ UMLObject *other = a->getObject(Uml::B);
+ Uml::Association_Type at = a->getAssocType();
+ if (c->getName() == other->getName()) {
+ if (at == Uml::at_Aggregation || at == Uml::at_Composition ||
+ at == Uml::at_UniAssociation) {
+ // Assuming unidirectional association, and we are
+ // at the "wrong" side.
+ // Returning roleName = QString::null tells caller to
+ // skip this association at this side.
+ roleName = QString();
+ return;
+ }
+ IAmRoleA = false;
+ other = a->getObject(Uml::A);
+ }
+ // Construct the type name:
+ typeName = cleanName(other->getName());
+ QString multiplicity;
+ if (IAmRoleA)
+ multiplicity = a->getMulti(Uml::B);
+ else
+ multiplicity = a->getMulti(Uml::A);
+ if (!multiplicity.isEmpty() && multiplicity != "1")
+ typeName.append("Vector");
+ // Construct the member name:
+ if (IAmRoleA)
+ roleName = a->getRoleName(Uml::B);
+ else
+ roleName = a->getRoleName(Uml::A);
+ if (roleName.isEmpty()) {
+ roleName = a->getName();
+ if (roleName.isEmpty()) {
+ roleName = "m_" + typeName;
+ }
+ }
+}
+
+void IDLWriter::writeClass(UMLClassifier *c) {
+ if (!c) {
+ kDebug() << "Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ const bool isClass = !c->isInterface();
+ QString classname = cleanName(c->getName());
+
+ //find an appropriate name for our file
+ QString fileName = findFileName(c, ".idl");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile file;
+ if (!openFile(file, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // Start generating the code.
+
+ QTextStream idl(&file);
+ //try to find a heading file(license, comments, etc)
+ QString str;
+ str = getHeadingFile(".idl");
+ if (!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"), fileName);
+ str.replace(QRegExp("%filepath%"), file.name());
+ idl << str << m_endl;
+ }
+
+ // Write includes.
+ UMLPackageList includes;
+ findObjectsRelated(c, includes);
+ if (includes.count()) {
+ for (UMLPackage *conc = includes.first(); conc; conc = includes.next()) {
+ if (conc->getBaseType() == Uml::ot_Datatype)
+ continue;
+ QString incName = findFileName(conc, ".idl");
+ if (!incName.isEmpty())
+ idl << "#include \"" << incName << "\"" << m_endl;
+ }
+ idl << m_endl;
+ }
+
+ // Generate the module declaration(s) for the package(s) in which
+ // we are embedded.
+ UMLPackageList pkgList = c->getPackages();
+ UMLPackage *pkg;
+ for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
+ idl << getIndent() << "module " << pkg->getName() << " {" << m_endl << m_endl;
+ m_indentLevel++;
+ }
+
+ // Write class Documentation if non-empty or if force option set.
+ if (forceDoc() || !c->getDoc().isEmpty()) {
+ idl << "//" << m_endl;
+ idl << "// class " << classname << m_endl;
+ idl << formatDoc(c->getDoc(), "// ");
+ idl << m_endl;
+ }
+
+ if (c->getBaseType() == Uml::ot_Enum) {
+ UMLClassifierListItemList litList = c->getFilteredList(Uml::ot_EnumLiteral);
+ uint i = 0;
+ idl << getIndent() << "enum " << classname << " {" << m_endl;
+ m_indentLevel++;
+ for (UMLClassifierListItem *lit = litList.first(); lit; lit = litList.next()) {
+ QString enumLiteral = cleanName(lit->getName());
+ idl << getIndent() << enumLiteral;
+ if (++i < litList.count())
+ idl << ",";
+ idl << m_endl;
+ }
+ m_indentLevel--;
+ idl << getIndent() << "};" << m_endl << m_endl;
+ // Close the modules inside which we might be nested.
+ for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
+ m_indentLevel--;
+ idl << getIndent() << "};" << m_endl << m_endl;
+ }
+ return;
+ }
+ if (! isOOClass(c)) {
+ QString stype = c->getStereotype();
+ if (stype == "CORBAConstant") {
+ kError() << "The stereotype " << stype << " cannot be applied to "
+ << c->getName() << ", but only to attributes." << endl;
+ return;
+ }
+ if (!isClass) {
+ kError() << "The stereotype " << stype
+ << " cannot be applied to " << c->getName()
+ << ", but only to classes." << endl;
+ return;
+ }
+ if (stype == "CORBAEnum") {
+ UMLAttributeList atl = c->getAttributeList();
+ UMLAttribute *at;
+ idl << getIndent() << "enum " << classname << " {" << m_endl;
+ m_indentLevel++;
+ uint i = 0;
+ for (at = atl.first(); at; at = atl.next()) {
+ QString enumLiteral = cleanName(at->getName());
+ idl << getIndent() << enumLiteral;
+ if (++i < atl.count())
+ idl << ",";
+ idl << m_endl;
+ }
+ m_indentLevel--;
+ idl << getIndent() << "};" << m_endl << m_endl;
+ } else if (stype == "CORBAStruct") {
+ UMLAttributeList atl = c->getAttributeList();
+ UMLAttribute *at;
+ idl << getIndent() << "struct " << classname << " {" << m_endl;
+ m_indentLevel++;
+ for (at = atl.first(); at; at = atl.next()) {
+ QString name = cleanName(at->getName());
+ idl << getIndent() << at->getTypeName() << " " << name << ";" << m_endl;
+ // Initial value not possible in IDL.
+ }
+ UMLAssociationList compositions = c->getCompositions();
+ if (!compositions.isEmpty()) {
+ idl << getIndent() << "// Compositions." << m_endl;
+ for (UMLAssociation *a = compositions.first(); a; a = compositions.next()) {
+ QString memberType, memberName;
+ computeAssocTypeAndRole(a, c, memberType, memberName);
+ idl << getIndent() << memberType << " " << memberName << ";" << m_endl;
+ }
+ }
+ UMLAssociationList aggregations = c->getAggregations();
+ if (!aggregations.isEmpty()) {
+ idl << getIndent() << "// Aggregations." << m_endl;
+ for (UMLAssociation *a = aggregations.first(); a; a = aggregations.next()) {
+ QString memberType, memberName;
+ computeAssocTypeAndRole(a, c, memberType, memberName);
+ idl << getIndent() << memberType << " " << memberName << ";" << m_endl;
+ }
+ }
+ m_indentLevel--;
+ idl << getIndent() << "};" << m_endl << m_endl;
+ } else if (stype == "CORBAUnion") {
+ idl << getIndent() << "// " << stype << " " << c->getName()
+ << " is Not Yet Implemented" << m_endl << m_endl;
+ } else if (stype == "CORBATypedef") {
+ UMLClassifierList superclasses = c->getSuperClasses();
+ UMLClassifier* firstParent = superclasses.first();
+ idl << getIndent() << "typedef " << firstParent->getName() << " "
+ << c->getName() << ";" << m_endl << m_endl;
+ } else {
+ idl << getIndent() << "// " << stype << ": Unknown stereotype" << m_endl << m_endl;
+ }
+ // Close the modules inside which we might be nested.
+ for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
+ m_indentLevel--;
+ idl << getIndent() << "};" << m_endl << m_endl;
+ }
+ return;
+ }
+
+ idl << getIndent();
+ if (c->getAbstract())
+ idl << "abstract ";
+ bool isValuetype = (c->getStereotype() == "CORBAValue");
+ if (isValuetype)
+ idl << "valuetype ";
+ else
+ idl << "interface ";
+ idl << c->getName();
+ UMLClassifierList superclasses = c->getSuperClasses();
+ if (! superclasses.isEmpty()) {
+ idl << " : ";
+ UMLClassifier *parent = superclasses.first();
+ int n_parents = superclasses.count();
+ while (n_parents--) {
+ idl << parent->getFullyQualifiedName("::");
+ if (n_parents)
+ idl << ", ";
+ parent = superclasses.next();
+ }
+ }
+ idl << " {" << m_endl << m_endl;
+ m_indentLevel++;
+
+ // Generate auxiliary declarations for multiplicity of associations
+ UMLAssociation *a;
+ bool didComment = false;
+ UMLAssociationList assocs = c->getAssociations();
+ for (a = assocs.first(); a; a = assocs.next()) {
+ if (! assocTypeIsMappableToAttribute(a->getAssocType()))
+ continue;
+ QString multiplicity = a->getMulti(Uml::A);
+ if (multiplicity.isEmpty() || multiplicity == "1")
+ continue;
+ if (!didComment) {
+ idl << getIndent() << "// Types for association multiplicities" << m_endl << m_endl;
+ didComment = true;
+ }
+ UMLClassifier* other = (UMLClassifier*)a->getObject(Uml::A);
+ QString bareName = cleanName(other->getName());
+ idl << getIndent() << "typedef sequence<" << other->getFullyQualifiedName("::")
+ << "> " << bareName << "Vector;" << m_endl << m_endl;
+ }
+
+ // Generate public attributes.
+ if (isClass) {
+ UMLAttributeList atl = c->getAttributeList();
+ if (forceSections() || atl.count()) {
+ idl << getIndent() << "// Attributes:" << m_endl << m_endl;
+ for (UMLAttribute *at = atl.first(); at; at = atl.next()) {
+ QString attName = cleanName(at->getName());
+ Uml::Visibility scope = at->getVisibility();
+ idl << getIndent();
+ if (isValuetype) {
+ if (scope == Uml::Visibility::Public)
+ idl << "public ";
+ else
+ idl << "private ";
+ } else {
+ if (scope != Uml::Visibility::Public) {
+ idl << "// visibility should be: "
+ << scope.toString()
+ << m_endl;
+ idl << getIndent();
+ }
+ idl << "attribute ";
+ }
+ idl << at->getTypeName() << " " << attName << ";"
+ << m_endl << m_endl;
+ }
+ }
+ }
+
+ // Generate public operations.
+ UMLOperationList opl(c->getOpList());
+ UMLOperationList oppub;
+ UMLOperation *op;
+ for (op = opl.first(); op; op = opl.next()) {
+ if (op->getVisibility() == Uml::Visibility::Public)
+ oppub.append(op);
+ }
+ if (forceSections() || oppub.count()) {
+ idl << getIndent() << "// Public methods:" << m_endl << m_endl;
+ for (op = oppub.first(); op; op = oppub.next())
+ writeOperation(op, idl);
+ idl << m_endl;
+ }
+
+
+ if (forceSections() || !assocs.isEmpty()) {
+ idl << getIndent() << "// Associations:" << m_endl << m_endl;
+ for (a = assocs.first(); a; a = assocs.next()) {
+ Uml::Association_Type at = a->getAssocType();
+ if (! assocTypeIsMappableToAttribute(at))
+ continue;
+ QString typeName, roleName;
+ computeAssocTypeAndRole(a, c, typeName, roleName);
+ if (roleName.isEmpty()) // presumably because we are at the "wrong" end
+ continue;
+ idl << getIndent() << "// " << UMLAssociation::typeAsString(at) << m_endl;
+ idl << getIndent();
+ if (isValuetype)
+ idl << "public ";
+ else
+ idl << "attribute ";
+ idl << typeName << " " << roleName << ";" << m_endl;
+ }
+ idl << m_endl;
+ }
+
+ m_indentLevel--;
+ idl << getIndent() << "};" << m_endl << m_endl;
+
+ // Close the modules inside which we might be nested.
+ for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
+ m_indentLevel--;
+ idl << getIndent() << "};" << m_endl << m_endl;
+ }
+ file.close();
+ emit codeGenerated(c, true);
+}
+
+
+void IDLWriter::writeOperation(UMLOperation *op, QTextStream &idl, bool is_comment) {
+ UMLAttributeList atl = op->getParmList();
+ QString rettype = op->getTypeName();
+
+ if (rettype.isEmpty())
+ rettype = "void";
+ idl << getIndent();
+ if (is_comment)
+ idl << "// ";
+ idl << rettype << " " << cleanName(op->getName()) << " (";
+ if (atl.count()) {
+ idl << m_endl;
+ m_indentLevel++;
+ uint i = 0;
+ for (UMLAttribute *at = atl.first(); at; at = atl.next()) {
+ idl << getIndent();
+ if (is_comment)
+ idl << "// ";
+ Uml::Parameter_Direction pk = at->getParmKind();
+ if (pk == Uml::pd_Out)
+ idl << "out ";
+ else if (pk == Uml::pd_InOut)
+ idl << "inout ";
+ else
+ idl << "in ";
+ idl << at->getTypeName() << " " << cleanName(at->getName());
+ if (++i < atl.count())
+ idl << "," << m_endl;
+ }
+ m_indentLevel--;
+ }
+ idl << ");" << m_endl << m_endl;
+}
+
+QStringList IDLWriter::defaultDatatypes() {
+ QStringList l;
+ l.append("boolean");
+ l.append("char");
+ l.append("octet");
+ l.append("short");
+ l.append("unsigned short");
+ l.append("long");
+ l.append("unsigned long");
+ l.append("float");
+ l.append("double");
+ l.append("string");
+ l.append("any");
+ return l;
+}
+
+const QStringList IDLWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "any"
+ << "attribute"
+ << "boolean"
+ << "case"
+ << "char"
+ << "const"
+ << "context"
+ << "default"
+ << "double"
+ << "enum"
+ << "exception"
+ << "FALSE"
+ << "float"
+ << "in"
+ << "inout"
+ << "interface"
+ << "long"
+ << "module"
+ << "octet"
+ << "oneway"
+ << "out"
+ << "raises"
+ << "readonly"
+ << "sequence"
+ << "short"
+ << "string"
+ << "struct"
+ << "switch"
+ << "TRUE"
+ << "typedef"
+ << "union"
+ << "unsigned"
+ << "void";
+ }
+
+ return keywords;
+}
+
+
diff --git a/umbrello/umbrello/codegenerators/idlwriter.h b/umbrello/umbrello/codegenerators/idlwriter.h
new file mode 100644
index 00000000..c44cabd6
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/idlwriter.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ idlwriter.h - description
+ -------------------
+ begin : Sat Jan 4 2003
+ copyright : (C) 2003 by Oliver Kellogg
+ email : okellogg@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef IDLWRITER_H
+#define IDLWRITER_H
+
+#include "simplecodegenerator.h"
+
+class UMLAssociation;
+class UMLOperation;
+
+/**
+ * Class IDLWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate an IDL interface for that
+ * concept.
+ */
+class IDLWriter : public SimpleCodeGenerator {
+public:
+
+ IDLWriter ();
+ virtual ~IDLWriter ();
+
+ /**
+ * call this method to generate IDL code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass (UMLClassifier *c);
+
+ /**
+ * returns "IDL"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ QStringList defaultDatatypes();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * write one operation
+ * @param op the class for which we are generating code
+ * @param idl the stream associated with the output file
+ */
+ void writeOperation(UMLOperation* op, QTextStream& idl, bool is_comment = false);
+
+ void computeAssocTypeAndRole(UMLAssociation* a, UMLClassifier *c,
+ QString& typeName, QString& roleName);
+
+ static bool isOOClass(UMLClassifier* c);
+
+ static bool assocTypeIsMappableToAttribute(Uml::Association_Type at);
+
+};
+
+#endif // IDLWRITER_H
diff --git a/umbrello/umbrello/codegenerators/javaantcodedocument.cpp b/umbrello/umbrello/codegenerators/javaantcodedocument.cpp
new file mode 100644
index 00000000..a3a174a3
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javaantcodedocument.cpp
@@ -0,0 +1,312 @@
+/***************************************************************************
+ * *
+ * 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 : Tue Jun 24 2003
+ */
+
+// own header
+#include "javaantcodedocument.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "javacodegenerator.h"
+#include "xmlcodecomment.h"
+#include "xmlelementcodeblock.h"
+#include "codegenfactory.h"
+#include "../umldoc.h"
+#include "../uml.h"
+
+
+// Constructors/Destructors
+//
+
+JavaANTCodeDocument::JavaANTCodeDocument ( )
+{
+ setFileName("build"); // default name
+ setFileExtension(".xml");
+ setID("ANTDOC"); // default id tag for this type of document
+}
+
+JavaANTCodeDocument::~JavaANTCodeDocument ( ) { }
+
+//
+// Methods
+//
+
+// Other methods
+//
+
+/**
+ * create a new CodeBlockWithComments object belonging to this CodeDocument.
+ * @return CodeBlockWithComments
+ */
+/*
+CodeBlockWithComments * JavaANTCodeDocument::newCodeBlockWithComments ( ) {
+ return new XMLElementCodeBlock(this,"empty");
+}
+*/
+
+HierarchicalCodeBlock * JavaANTCodeDocument::newHierarchicalCodeBlock ( ) {
+ return new XMLElementCodeBlock(this,"empty");
+}
+
+// Sigh. NOT optimal. The only reason that we need to have this
+// is so we can create the XMLNodes, if needed.
+// would be better if we could create a handler interface that each
+// codeblock used so all we have to do here is add the handler
+void JavaANTCodeDocument::loadChildTextBlocksFromNode ( QDomElement & root)
+{
+
+ QDomNode tnode = root.firstChild();
+ QDomElement telement = tnode.toElement();
+ bool loadCheckForChildrenOK = false;
+ while( !telement.isNull() ) {
+ QString nodeName = telement.tagName();
+
+ if( nodeName == "textblocks" ) {
+
+ QDomNode node = telement.firstChild();
+ QDomElement element = node.toElement();
+
+ // if there is nothing to begin with, then we don't worry about it
+ loadCheckForChildrenOK = element.isNull() ? true : false;
+
+ while( !element.isNull() ) {
+ QString name = element.tagName();
+
+ if( name == "codecomment" ) {
+ CodeComment * block = new XMLCodeComment(this);
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeComment to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeaccessormethod" ||
+ name == "ccfdeclarationcodeblock"
+ ) {
+ QString acctag = element.attribute("tag","");
+ // search for our method in the
+ TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
+ if(!tb || !addTextBlock(tb))
+ {
+ kError()<<"Unable to add codeclassfield child method to:"<<this<<endl;
+ // DON'T delete
+ } else
+ loadCheckForChildrenOK= true;
+
+ } else
+ if( name == "codeblock" ) {
+ CodeBlock * block = newCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeBlock to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeblockwithcomments" ) {
+ CodeBlockWithComments * block = newCodeBlockWithComments();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeBlockwithcomments to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "header" ) {
+ // do nothing.. this is treated elsewhere
+ } else
+ if( name == "hierarchicalcodeblock" ) {
+ HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeoperation" ) {
+ // find the code operation by id
+ QString id = element.attribute("parent_id","-1");
+ UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
+ UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
+ if(op) {
+ CodeOperation * block = 0;
+ kError() << "TODO: implement CodeGenFactory::newCodeOperation() for JavaANTCodeDocument" << endl;
+ break; // remove when above is implemented
+ block->loadFromXMI(element);
+ if(addTextBlock(block))
+ loadCheckForChildrenOK= true;
+ else
+ {
+ kError()<<"Unable to add codeoperation to:"<<this<<endl;
+ block->deleteLater();
+ }
+ } else
+ kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
+ } else
+ if( name == "xmlelementblock" ) {
+ QString xmltag = element.attribute("nodeName","UNKNOWN");
+ XMLElementCodeBlock * block = new XMLElementCodeBlock(this,xmltag);
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add XMLelement to Java ANT document:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ }
+ /*
+ // only needed for extreme debugging conditions (E.g. making new codeclassdocument loader)
+ else
+ kDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"<<endl;
+ */
+
+ node = element.nextSibling();
+ element = node.toElement();
+ }
+ break;
+ }
+
+ tnode = telement.nextSibling();
+ telement = tnode.toElement();
+ }
+
+ if(!loadCheckForChildrenOK)
+ {
+ CodeDocument * test = dynamic_cast<CodeDocument*>(this);
+ if(test)
+ {
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
+ } else {
+ HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
+ if(hb)
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
+ else
+ kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
+ }
+ }
+
+}
+
+/** set the class attributes of this object from
+ * the passed element node.
+ */
+void JavaANTCodeDocument::setAttributesFromNode ( QDomElement & root)
+{
+
+ // superclass save
+ CodeDocument::setAttributesFromNode(root);
+
+ // now set local attributes
+ // setPackage(root.attribute("package",""));
+
+}
+
+/**
+ * load params from the appropriate XMI element node.
+ */
+void JavaANTCodeDocument::loadFromXMI ( QDomElement & root ) {
+ setAttributesFromNode(root);
+}
+
+/** set attributes of the node that represents this class
+ * in the XMI document.
+ */
+void JavaANTCodeDocument::setAttributesOnNode ( QDomDocument & doc, QDomElement & docElement)
+{
+
+ // superclass call
+ CodeDocument::setAttributesOnNode(doc,docElement);
+
+ // now set local attributes/fields
+ //FIX
+}
+
+/**
+ * Save the XMI representation of this object
+ */
+void JavaANTCodeDocument::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement docElement = doc.createElement( "codedocument" );
+
+ setAttributesOnNode(doc, docElement);
+
+ root.appendChild( docElement );
+}
+
+// we add in our code blocks that describe how to generate
+// the project here...
+void JavaANTCodeDocument::updateContent( ) {
+ // FIX : fill in more content based on classes
+ // which exist
+ CodeBlockWithComments * xmlDecl = getCodeBlockWithComments("xmlDecl","",0);
+ xmlDecl->setText("<?xml version=\"1.0\"?>");
+ addTextBlock(xmlDecl);
+
+ XMLElementCodeBlock * rootNode = new XMLElementCodeBlock(this, "project", "Java ANT build document");
+ rootNode->setTag("projectDecl");
+ addTextBlock(rootNode);
+
+ // <project name="XDF" default="help" basedir=".">
+ //HierarchicalCodeBlock * projDecl = xmlDecl->getHierarchicalCodeBlock("projectDecl", "Java ANT build document", 1);
+
+ // set some global properties for the build
+ /*
+ <!-- set global properties for this build -->
+ <!-- paths -->
+ <property name="docApi.dir" value="docs/api"/>
+ <property name="path" value="gov/nasa/gsfc/adc/xdf"/>
+ <property name="src" value="src/${path}/"/>
+ <property name="top" value="."/>
+ <property name="build" value="${top}/gov"/>
+ <property name="buildDir" value="${path}"/>
+ <!-- compiler directives -->
+ <property name="build.compiler" value="modern"/>
+ <property name="useDeprecation" value="no"/>
+ <property name="jarname" value="${project}.jar"/>
+ */
+
+}
+
+// We overwritten by Java language implementation to get lowercase path
+QString JavaANTCodeDocument::getPath ( )
+{
+
+ QString path = getPackage();
+
+ // Replace all white spaces with blanks
+ path.simplifyWhiteSpace();
+
+ // Replace all blanks with underscore
+ path.replace(QRegExp(" "), "_");
+
+ path.replace(QRegExp("\\."),"/");
+ path.replace(QRegExp("::"), "/");
+
+ path.lower();
+
+ return path;
+
+}
+
+
+#include "javaantcodedocument.moc"
diff --git a/umbrello/umbrello/codegenerators/javaantcodedocument.h b/umbrello/umbrello/codegenerators/javaantcodedocument.h
new file mode 100644
index 00000000..9d7372f3
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javaantcodedocument.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Tue Jun 24 2003
+ */
+
+
+
+#ifndef JAVAANTCODEDOCUMENT_H
+#define JAVAANTCODEDOCUMENT_H
+
+#include <qstring.h>
+#include <qdom.h>
+
+#include "../codedocument.h"
+
+/**
+ * class JavaANTCodeDocument
+ * Represents
+ */
+
+class JavaANTCodeDocument : public CodeDocument
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ JavaANTCodeDocument ( );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaANTCodeDocument ( );
+
+ QString getPath ( );
+
+ void updateContent();
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * load params from the appropriate XMI element node.
+ */
+ virtual void loadFromXMI ( QDomElement & root );
+
+ /**
+ * create a new HierarchicalCodeBlock object belonging to this CodeDocument.
+ * @return HierarchicalCodeBlock
+ */
+ virtual HierarchicalCodeBlock * newHierarchicalCodeBlock ( );
+
+ /**
+ * create a new CodeBlockWithComments object belonging to this CodeDocument.
+ * @return CodeBlockWithComments
+ */
+ // virtual CodeBlockWithComments * newCodeBlockWithComments ( );
+
+protected:
+
+ /** set attributes of the node that represents this class
+ * in the XMI document.
+ */
+ virtual void setAttributesOnNode ( QDomDocument & doc, QDomElement & blockElement);
+
+ /** set the class attributes of this object from
+ * the passed element node.
+ */
+ virtual void setAttributesFromNode ( QDomElement & element);
+
+ /**
+ * need to overwrite this for java since we need to pick up the
+ * xml declaration blocks.
+ */
+ virtual void loadChildTextBlocksFromNode ( QDomElement & root);
+
+private:
+
+
+
+};
+
+#endif // JAVAANTCODEDOCUMENT_H
diff --git a/umbrello/umbrello/codegenerators/javaclassdeclarationblock.cpp b/umbrello/umbrello/codegenerators/javaclassdeclarationblock.cpp
new file mode 100644
index 00000000..0e4ccdbf
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javaclassdeclarationblock.cpp
@@ -0,0 +1,169 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 16 2003
+ */
+#include "javaclassdeclarationblock.h"
+#include "javacodedocumentation.h"
+#include "../codegenerator.h"
+#include "../codegenerationpolicy.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+JavaClassDeclarationBlock::JavaClassDeclarationBlock
+ ( JavaClassifierCodeDocument * parentDoc, const QString &startText, const QString &endText, const QString &comment)
+ : OwnedHierarchicalCodeBlock(parentDoc->getParentClassifier(), parentDoc, startText, endText, comment)
+{
+ init(parentDoc, comment);
+}
+
+JavaClassDeclarationBlock::~JavaClassDeclarationBlock ( ) { }
+
+//
+// Methods
+//
+
+/**
+ * Save the XMI representation of this object
+ */
+void JavaClassDeclarationBlock::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "javaclassdeclarationblock" );
+
+ setAttributesOnNode(doc, blockElement);
+
+ root.appendChild( blockElement );
+}
+
+/**
+ * load params from the appropriate XMI element node.
+ */
+void JavaClassDeclarationBlock::loadFromXMI ( QDomElement & root )
+{
+ setAttributesFromNode(root);
+}
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * update the start and end text for this ownedhierarchicalcodeblock.
+ */
+void JavaClassDeclarationBlock::updateContent ( )
+{
+
+ JavaClassifierCodeDocument *parentDoc = dynamic_cast<JavaClassifierCodeDocument*>(getParentDocument());
+ UMLClassifier *c = parentDoc->getParentClassifier();
+ CodeGenerationPolicy *commonPolicy = UMLApp::app()->getCommonPolicy();
+ QString endLine = commonPolicy->getNewLineEndingChars();
+ bool isInterface = parentDoc->parentIsInterface(); // a little shortcut
+ QString JavaClassName = parentDoc->getJavaClassName(c->getName());
+
+ // COMMENT
+ if(isInterface)
+ getComment()->setText("Interface "+JavaClassName+endLine+c->getDoc());
+ else
+ getComment()->setText("Class "+JavaClassName+endLine+c->getDoc());
+
+ bool forceDoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
+ if(forceDoc || !c->getDoc().isEmpty())
+ getComment()->setWriteOutText(true);
+ else
+ getComment()->setWriteOutText(false);
+
+
+ // Now set START/ENDING Text
+ QString startText = "";
+ // In Java, we need declare abstract only on classes
+ if (c->getAbstract() && !isInterface)
+ startText.append("abstract ");
+
+ if (c->getVisibility() != Uml::Visibility::Public) {
+ // We should probably emit a warning in here .. java doesn't like to allow
+ // private/protected classes. The best we can do (I believe)
+ // is to let these declarations default to "package visibility"
+ // which is a level between traditional "private" and "protected"
+ // scopes. To get this visibility level we just print nothing..
+ } else
+ startText.append("public ");
+
+ if(parentDoc->parentIsInterface())
+ startText.append("interface ");
+ else
+ startText.append("class ");
+
+ startText.append(JavaClassName);
+
+ // write inheritances out
+ UMLClassifierList superclasses =
+ c->findSuperClassConcepts(UMLClassifier::CLASS);
+ UMLClassifierList superinterfaces =
+ c->findSuperClassConcepts(UMLClassifier::INTERFACE);
+ int nrof_superclasses = superclasses.count();
+ int nrof_superinterfaces = superinterfaces.count();
+
+ // write out inheritance
+ int i = 0;
+ if(nrof_superclasses >0)
+ startText.append(" extends ");
+ for (UMLClassifier * concept= superclasses.first(); concept; concept = superclasses.next())
+ {
+ startText.append(parentDoc->cleanName(concept->getName()));
+ if(i != (nrof_superclasses-1))
+ startText.append(", ");
+ i++;
+ }
+
+ // write out what we 'implement'
+ i = 0;
+ if(nrof_superinterfaces >0)
+ {
+ // In Java interfaces "extend" other interfaces. Classes "implement" interfaces
+ if(isInterface)
+ startText.append(" extends ");
+ else
+ startText.append(" implements ");
+ }
+ for (UMLClassifier * concept= superinterfaces.first(); concept; concept = superinterfaces.next())
+ {
+ startText.append(parentDoc->cleanName(concept->getName()));
+ if(i != (nrof_superinterfaces-1))
+ startText.append(", ");
+ i++;
+ }
+
+ // Set the header and end text for the hier.codeblock
+ setStartText(startText+" {");
+
+ // setEndText("}"); // not needed
+
+}
+
+void JavaClassDeclarationBlock::init (JavaClassifierCodeDocument *parentDoc, const QString &comment)
+{
+
+ setComment(new JavaCodeDocumentation(parentDoc));
+ getComment()->setText(comment);
+
+ setEndText("}");
+
+ updateContent();
+
+}
+
+
+#include "javaclassdeclarationblock.moc"
diff --git a/umbrello/umbrello/codegenerators/javaclassdeclarationblock.h b/umbrello/umbrello/codegenerators/javaclassdeclarationblock.h
new file mode 100644
index 00000000..136df809
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javaclassdeclarationblock.h
@@ -0,0 +1,66 @@
+
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 16 2003
+ */
+
+#ifndef JAVACLASSDECLARATIONBLOCK_H
+#define JAVACLASSDECLARATIONBLOCK_H
+
+#include <qstring.h>
+
+#include "javaclassifiercodedocument.h"
+#include "../ownedhierarchicalcodeblock.h"
+
+class JavaClassDeclarationBlock : public OwnedHierarchicalCodeBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ explicit JavaClassDeclarationBlock ( JavaClassifierCodeDocument * parentDoc, const QString &start = "", const QString &endText = "}", const QString &comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaClassDeclarationBlock ( );
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * load params from the appropriate XMI element node.
+ */
+ virtual void loadFromXMI ( QDomElement & root );
+
+protected:
+
+ /**
+ * Update the start/end text of this codeblock.
+ */
+ void updateContent ( );
+
+private:
+
+ void init (JavaClassifierCodeDocument * parent, const QString &comment);
+
+};
+
+#endif // JAVACLASSDECLARATIONBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/javaclassifiercodedocument.cpp b/umbrello/umbrello/codegenerators/javaclassifiercodedocument.cpp
new file mode 100644
index 00000000..44e6f242
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javaclassifiercodedocument.cpp
@@ -0,0 +1,583 @@
+/***************************************************************************
+ * *
+ * 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 : Mon Jun 23 2003
+ */
+
+/**
+ We carve the Java document up into sections as follows:
+
+ * header
+ * package declaration
+ * import statements
+ * class declaration
+ * guts of the class (e.g. field decl, accessor methods, operations, dependant classes)
+*/
+
+// own header
+#include "javaclassifiercodedocument.h"
+
+// qt/kde includes
+#include <kdebug.h>
+#include <qregexp.h>
+
+// local includes
+#include "javacodegenerator.h"
+#include "javacodecomment.h"
+#include "javaclassdeclarationblock.h"
+#include "javacodeclassfielddeclarationblock.h"
+#include "codegen_utils.h"
+#include "../classifier.h"
+#include "../codegenerationpolicy.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+JavaClassifierCodeDocument::JavaClassifierCodeDocument ( UMLClassifier * concept )
+ : ClassifierCodeDocument (concept) {
+ init();
+}
+
+JavaClassifierCodeDocument::~JavaClassifierCodeDocument ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+// Make it easier on ourselves
+JavaCodeGenerationPolicy * JavaClassifierCodeDocument::getJavaPolicy() {
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ JavaCodeGenerationPolicy * policy = dynamic_cast<JavaCodeGenerationPolicy*>(pe);
+ return policy;
+}
+
+/**
+ * Get the dialog widget which allows user interaction with the object parameters.
+ * @return CodeDocumentDialog
+ */
+/*
+CodeDocumentDialog JavaClassifierCodeDocument::getDialog ( ) {
+
+}
+*/
+
+bool JavaClassifierCodeDocument::forceDoc () {
+ return UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
+}
+
+// We overwritten by Java language implementation to get lowercase path
+QString JavaClassifierCodeDocument::getPath ( )
+{
+
+ QString path = getPackage();
+
+ // Replace all white spaces with blanks
+ path.simplifyWhiteSpace();
+
+ // Replace all blanks with underscore
+ path.replace(QRegExp(" "), "_");
+
+ path.replace(QRegExp("\\."),"/");
+ path.replace(QRegExp("::"), "/");
+
+ path.lower();
+
+ return path;
+
+}
+
+
+// Other methods
+//
+
+QString JavaClassifierCodeDocument::getJavaClassName (const QString &name) {
+ return Codegen_Utils::capitalizeFirstLetter(CodeGenerator::cleanName(name));
+}
+
+// Initialize this java classifier code document
+void JavaClassifierCodeDocument::init ( ) {
+
+ setFileExtension(".java");
+
+ //initCodeClassFields(); // this is dubious because it calls down to
+ // CodeGenFactory::newCodeClassField(this)
+ // but "this" is still in construction at that time.
+
+ classDeclCodeBlock = 0;
+ operationsBlock = 0;
+ constructorBlock = 0;
+
+ // this will call updateContent() as well as other things that sync our document.
+ synchronize();
+}
+
+/**
+ * @param op
+ */
+// in the vannilla version, we just tack all operations on the end
+// of the document
+bool JavaClassifierCodeDocument::addCodeOperation (CodeOperation * op ) {
+
+ if(!op->getParentOperation()->isLifeOperation())
+ return operationsBlock->addTextBlock(op);
+ else
+ return constructorBlock->addTextBlock(op);
+}
+
+// Sigh. NOT optimal. The only reason that we need to have this
+// is so we can create the JavaClassDeclarationBlock.
+// would be better if we could create a handler interface that each
+// codeblock used so all we have to do here is add the handler
+// for "javaclassdeclarationblock"
+void JavaClassifierCodeDocument::loadChildTextBlocksFromNode ( QDomElement & root)
+{
+
+ QDomNode tnode = root.firstChild();
+ QDomElement telement = tnode.toElement();
+ bool loadCheckForChildrenOK = false;
+ while( !telement.isNull() ) {
+ QString nodeName = telement.tagName();
+
+ if( nodeName == "textblocks" ) {
+
+ QDomNode node = telement.firstChild();
+ QDomElement element = node.toElement();
+
+ // if there is nothing to begin with, then we don't worry about it
+ loadCheckForChildrenOK = element.isNull() ? true : false;
+
+ while( !element.isNull() ) {
+ QString name = element.tagName();
+
+ if( name == "codecomment" ) {
+ CodeComment * block = new JavaCodeComment(this);
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"loadFromXMI : unable to add codeComment to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeaccessormethod" ||
+ name == "ccfdeclarationcodeblock"
+ ) {
+ QString acctag = element.attribute("tag","");
+ // search for our method in the
+ TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
+ if(!tb || !addTextBlock(tb))
+ {
+ kError()<<"loadFromXMI : unable to add codeclassfield child method to:"<<this<<endl;
+ // DON'T delete
+ } else
+ loadCheckForChildrenOK= true;
+
+ } else
+ if( name == "codeblock" ) {
+ CodeBlock * block = newCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"loadFromXMI : unable to add codeBlock to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeblockwithcomments" ) {
+ CodeBlockWithComments * block = newCodeBlockWithComments();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"loadFromXMI : unable to add codeBlockwithcomments to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "header" ) {
+ // do nothing.. this is treated elsewhere
+ } else
+ if( name == "hierarchicalcodeblock" ) {
+ HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeoperation" ) {
+ // find the code operation by id
+ QString id = element.attribute("parent_id","-1");
+ UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
+ UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
+ if(op) {
+ CodeOperation * block = new JavaCodeOperation(this, op);
+ block->loadFromXMI(element);
+ if(addTextBlock(block))
+ loadCheckForChildrenOK= true;
+ else
+ {
+ kError()<<"Unable to add codeoperation to:"<<this<<endl;
+ block->deleteLater();
+ }
+ } else
+ kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
+ } else
+ if( name == "javaclassdeclarationblock" )
+ {
+ JavaClassDeclarationBlock * block = getClassDecl();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add java code declaration block to:"<<this<<endl;
+ // DON'T delete.
+ // block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ }
+ // This last item is only needed for extreme debugging conditions
+ // (E.g. making new codeclassdocument loader)
+ // else
+ // kDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"<<endl;
+
+ node = element.nextSibling();
+ element = node.toElement();
+ }
+ break;
+ }
+
+ tnode = telement.nextSibling();
+ telement = tnode.toElement();
+ }
+
+ if(!loadCheckForChildrenOK)
+ {
+ CodeDocument * test = dynamic_cast<CodeDocument*>(this);
+ if(test)
+ {
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
+ } else {
+ HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
+ if(hb)
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
+ else
+ kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
+ }
+ }
+
+
+}
+
+QString JavaClassifierCodeDocument::scopeToJavaDecl(Uml::Visibility scope)
+{
+ QString scopeString;
+ switch(scope)
+ {
+ case Uml::Visibility::Public:
+ scopeString = "public";
+ break;
+ case Uml::Visibility::Protected:
+ scopeString = "protected";
+ break;
+ case Uml::Visibility::Private:
+ case Uml::Visibility::Implementation:
+ default:
+ scopeString = "private";
+ break;
+ }
+ return scopeString;
+}
+
+JavaClassDeclarationBlock * JavaClassifierCodeDocument::getClassDecl()
+{
+ if(!classDeclCodeBlock)
+ {
+ classDeclCodeBlock = new JavaClassDeclarationBlock (this);
+ classDeclCodeBlock->setTag("ClassDeclBlock");
+ }
+ return classDeclCodeBlock;
+}
+
+void JavaClassifierCodeDocument::resetTextBlocks()
+{
+
+ // all special pointers to text blocks need to be zero'd out
+ operationsBlock = 0;
+ constructorBlock = 0;
+ classDeclCodeBlock = 0;
+
+ // now do traditional release of text blocks.
+ ClassifierCodeDocument::resetTextBlocks();
+}
+
+// This method will cause the class to rebuild its text representation.
+// based on the parent classifier object.
+// For any situation in which this is called, we are either building the code
+// document up, or replacing/regenerating the existing auto-generated parts. As
+// such, we will want to insert everything we resonablely will want
+// during creation. We can set various parts of the document (esp. the
+// comments) to appear or not, as needed.
+void JavaClassifierCodeDocument::updateContent( )
+{
+ // Gather info on the various fields and parent objects of this class...
+ UMLClassifier * c = getParentClassifier();
+ CodeGenerationPolicy * commonPolicy = UMLApp::app()->getCommonPolicy();
+ CodeGenPolicyExt * pe = UMLApp::app()->getPolicyExt();
+ JavaCodeGenerationPolicy * policy = dynamic_cast<JavaCodeGenerationPolicy*>(pe);
+
+ // first, set the global flag on whether or not to show classfield info
+ // This depends on whether or not we have attribute/association classes
+ CodeClassFieldList * cfList = getCodeClassFieldList();
+ for(CodeClassField * field = cfList->first(); field; field = cfList->next())
+ if(field->parentIsAttribute())
+ field->setWriteOutMethods(policy->getAutoGenerateAttribAccessors());
+ else
+ field->setWriteOutMethods(policy->getAutoGenerateAssocAccessors());
+
+ // attribute-based ClassFields
+ // we do it this way to have the static fields sorted out from regular ones
+ CodeClassFieldList staticAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true);
+ CodeClassFieldList attribClassFields = getSpecificClassFields (CodeClassField::Attribute, false);
+ // association-based ClassFields
+ // don't care if they are static or not..all are lumped together
+ CodeClassFieldList plainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation );
+ CodeClassFieldList aggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation );
+ CodeClassFieldList compositionClassFields = getSpecificClassFields ( CodeClassField::Composition );
+
+ bool isInterface = parentIsInterface();
+ bool hasOperationMethods = c->getOpList().last() ? true : false;
+ QString endLine = commonPolicy->getNewLineEndingChars(); // a shortcut..so we don't have to call this all the time
+
+ //
+ // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
+ //
+
+ //
+ // PACKAGE CODE BLOCK
+ //
+ QString pkgs = getPackage();
+ pkgs.replace(QRegExp("::"), ".");
+ QString packageText = getPackage().isEmpty() ? "" : "package "+pkgs+';'+endLine;
+ CodeBlockWithComments * pblock = addOrUpdateTaggedCodeBlockWithComments("packages", packageText, "", 0, false);
+ if(packageText.isEmpty() && pblock->getContentType() == CodeBlock::AutoGenerated)
+ pblock->setWriteOutText(false);
+ else
+ pblock->setWriteOutText(true);
+
+ // IMPORT CODEBLOCK
+ //
+ // Q: Why all utils? Isnt just List and Vector the only classes we are using?
+ // A: doesn't matter at all; its more readable to just include '*' and java compilers
+ // don't slow down or anything. (TZ)
+ QString importStatement = "";
+ if ( hasObjectVectorClassFields() )
+ importStatement.append("import java.util.*;");
+
+ //only import classes in a different package from this class
+ UMLPackageList imports;
+ QMap<UMLPackage*, QString> packageMap; // so we don't repeat packages
+
+ CodeGenerator::findObjectsRelated(c,imports);
+ for(UMLPackage *con = imports.first(); con ; con = imports.next())
+ // NO (default) datatypes in the import statement.. use defined
+ // ones whould be possible, but no idea how to do that...at least for now.
+ // Dynamic casting is slow..not an optimal way to do this.
+ if (!packageMap.contains(con) && con->getBaseType() != Uml::ot_Datatype)
+ {
+ packageMap.insert(con, con->getPackage());
+
+ // now, we DON'T need to import classes that are already in our own package
+ // (that is, IF a package is specified). Otherwise, we should have a declaration.
+ if (con->getPackage() != c->getPackage() ||
+ (c->getPackage().isEmpty() && con->getPackage().isEmpty()))
+ {
+ importStatement.append(endLine+"import ");
+ if(!con->getPackage().isEmpty())
+ importStatement.append(con->getPackage()+'.');
+ importStatement.append(CodeGenerator::cleanName(con->getName())+';');
+ }
+ }
+ // now, add/update the imports codeblock
+ CodeBlockWithComments * iblock = addOrUpdateTaggedCodeBlockWithComments("imports", importStatement, "", 0, false);
+ if(importStatement.isEmpty() && iblock->getContentType() == CodeBlock::AutoGenerated)
+ iblock->setWriteOutText(false);
+ else
+ iblock->setWriteOutText(true);
+
+ // CLASS DECLARATION BLOCK
+ //
+
+ // get the declaration block. If its not already present, add it too
+ JavaClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
+ addTextBlock(myClassDeclCodeBlock); // note: wont add if already present
+
+ // NOW create document in sections..
+ // now we want to populate the body of our class
+ // our layout is the following general groupings of code blocks:
+
+ // start java classifier document
+
+ // header comment
+
+ // package code block
+
+ // import code block
+
+ // class declaration
+
+ // section:
+ // - class field declaration section comment
+ // - class field declarations (0+ codeblocks)
+
+ // section:
+ // - methods section comment
+
+ // sub-section: constructor ops
+ // - constructor method section comment
+ // - constructor methods (0+ codeblocks)
+
+ // sub-section: accessors
+ // - accessor method section comment
+ // - static accessor methods (0+ codeblocks)
+ // - non-static accessor methods (0+ codeblocks)
+
+ // sub-section: non-constructor ops
+ // - operation method section comment
+ // - operations (0+ codeblocks)
+
+ // end class declaration
+
+ // end java classifier document
+
+
+ // Q: Why use the more complicated scheme of arranging code blocks within codeblocks?
+ // A: This will allow us later to preserve the format of our document so that if
+ // codeblocks are added, they may be easily added in the correct place, rather than at
+ // the end of the document, or by using a difficult algorithm to find the location of
+ // the last appropriate code block sibling (which may not exist.. for example user adds
+ // a constructor operation, but there currently are no constructor code blocks
+ // within the document).
+
+ //
+ // * CLASS FIELD declaration section
+ //
+
+ // get/create the field declaration code block
+ HierarchicalCodeBlock * fieldDeclBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("fieldsDecl", "Fields", 1);
+
+ // Update the comment: we only set comment to appear under the following conditions
+ CodeComment * fcomment = fieldDeclBlock->getComment();
+ if (isInterface || (!forceDoc() && !hasClassFields()) )
+ fcomment->setWriteOutText(false);
+ else
+ fcomment->setWriteOutText(true);
+
+ // now actually declare the fields within the appropriate HCodeBlock
+ declareClassFields(staticAttribClassFields, fieldDeclBlock);
+ declareClassFields(attribClassFields, fieldDeclBlock);
+ declareClassFields(plainAssocClassFields, fieldDeclBlock);
+ declareClassFields(aggregationClassFields, fieldDeclBlock);
+ declareClassFields(compositionClassFields, fieldDeclBlock);
+
+ //
+ // METHODS section
+ //
+
+ // get/create the method codeblock
+ HierarchicalCodeBlock * methodsBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("methodsBlock", "Methods", 1);
+
+ // Update the section comment
+ CodeComment * methodsComment = methodsBlock->getComment();
+ // set conditions for showing this comment
+ if (!forceDoc() && !hasClassFields() && !hasOperationMethods)
+ methodsComment->setWriteOutText(false);
+ else
+ methodsComment->setWriteOutText(true);
+
+ // METHODS sub-section : constructor methods
+ //
+
+ // get/create the constructor codeblock
+ HierarchicalCodeBlock * constBlock = methodsBlock->getHierarchicalCodeBlock("constructorMethods", "Constructors", 1);
+ constructorBlock = constBlock; // record this codeblock for later, when operations are updated
+
+ // special condiions for showing comment: only when autogenerateding empty constructors
+ // Although, we *should* check for other constructor methods too
+ CodeComment * constComment = constBlock->getComment();
+ CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();
+ if (!forceDoc() && (isInterface || !pol->getAutoGenerateConstructors()))
+ constComment->setWriteOutText(false);
+ else
+ constComment->setWriteOutText(true);
+
+ // add/get the empty constructor
+ QString JavaClassName = getJavaClassName(c->getName());
+ QString emptyConstStatement = "public "+JavaClassName+" ( ) { }";
+ CodeBlockWithComments * emptyConstBlock =
+ constBlock->addOrUpdateTaggedCodeBlockWithComments("emptyconstructor", emptyConstStatement, "Empty Constructor", 1, false);
+ // Now, as an additional condition we only show the empty constructor block
+ // IF it was desired to be shown
+ if(parentIsClass() && pol->getAutoGenerateConstructors())
+ emptyConstBlock->setWriteOutText(true);
+ else
+ emptyConstBlock->setWriteOutText(false);
+
+ // METHODS subsection : ACCESSOR METHODS
+ //
+
+ // get/create the accessor codeblock
+ HierarchicalCodeBlock * accessorBlock = methodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
+
+ // set conditions for showing section comment
+ CodeComment * accessComment = accessorBlock->getComment();
+ if (!forceDoc() && !hasClassFields())
+ accessComment->setWriteOutText(false);
+ else
+ accessComment->setWriteOutText(true);
+
+ // now, 2 sub-sub sections in accessor block
+ // add/update accessor methods for attributes
+ HierarchicalCodeBlock * staticAccessors = accessorBlock->getHierarchicalCodeBlock("staticAccessorMethods", "", 1);
+ staticAccessors->getComment()->setWriteOutText(false); // never write block comment
+ staticAccessors->addCodeClassFieldMethods(staticAttribClassFields);
+ staticAccessors->addCodeClassFieldMethods(attribClassFields);
+
+ // add/update accessor methods for associations
+ HierarchicalCodeBlock * regularAccessors = accessorBlock->getHierarchicalCodeBlock("regularAccessorMethods", "", 1);
+ regularAccessors->getComment()->setWriteOutText(false); // never write block comment
+ regularAccessors->addCodeClassFieldMethods(plainAssocClassFields);
+ regularAccessors->addCodeClassFieldMethods(aggregationClassFields);
+ regularAccessors->addCodeClassFieldMethods(compositionClassFields);
+
+ // METHODS subsection : Operation methods (which arent constructors)
+ //
+
+ // get/create the operations codeblock
+ operationsBlock = methodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
+
+ // set conditions for showing section comment
+ CodeComment * ocomment = operationsBlock->getComment();
+ if (!forceDoc() && !hasOperationMethods )
+ ocomment->setWriteOutText(false);
+ else
+ ocomment->setWriteOutText(true);
+
+}
+
+
+#include "javaclassifiercodedocument.moc"
diff --git a/umbrello/umbrello/codegenerators/javaclassifiercodedocument.h b/umbrello/umbrello/codegenerators/javaclassifiercodedocument.h
new file mode 100644
index 00000000..ddad6e1a
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javaclassifiercodedocument.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+
+
+#ifndef JAVACLASSIFIERCODEDOCUMENT_H
+#define JAVACLASSIFIERCODEDOCUMENT_H
+
+#include <qstring.h>
+
+#include "../codeclassfieldlist.h"
+#include "../classifiercodedocument.h"
+#include "../classifier.h"
+#include "../hierarchicalcodeblock.h"
+#include "classifierinfo.h"
+#include "javacodeclassfield.h"
+#include "javacodeoperation.h"
+
+class JavaClassDeclarationBlock;
+class JavaCodeGenerationPolicy;
+
+/**
+ * class JavaClassifierCodeDocument
+ * A Java UMLClassifier Code Document.
+ */
+
+class JavaClassifierCodeDocument : public ClassifierCodeDocument
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructor
+ */
+ JavaClassifierCodeDocument (UMLClassifier * classifier);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaClassifierCodeDocument ( );
+
+ /**
+ * Get the dialog widget which allows user interaction with the object parameters.
+ * @return CodeDocumentDialog
+ */
+ //CodeDocumentDialog getDialog ( );
+
+ QString scopeToJavaDecl(Uml::Visibility scope);
+
+ // Make it easier on ourselves
+ JavaCodeGenerationPolicy * getJavaPolicy();
+
+ QString getJavaClassName (const QString &name);
+
+ QString getPath();
+
+ /** add a code operation to this java classifier code document.
+ * @return bool which is true IF the code operation was added successfully
+ */
+ bool addCodeOperation (CodeOperation * op );
+
+protected:
+
+ // reset/clear our inventory of textblocks in this document
+ void resetTextBlocks();
+
+ /**
+ * need to overwrite this for java since we need to pick up the
+ * java class declaration block.
+ */
+ virtual void loadChildTextBlocksFromNode ( QDomElement & root);
+
+ void addOrUpdateCodeClassFieldMethodsInCodeBlock(CodeClassFieldList &list, JavaClassDeclarationBlock * codeBlock);
+
+ bool forceDoc ();
+
+ void updateContent();
+
+private:
+
+ JavaClassDeclarationBlock * classDeclCodeBlock;
+ HierarchicalCodeBlock * constructorBlock;
+ HierarchicalCodeBlock * operationsBlock;
+
+ ClassifierInfo * info;
+
+ void init ( );
+ JavaClassDeclarationBlock * getClassDecl();
+
+
+};
+
+#endif // JAVACLASSIFIERCODEDOCUMENT_H
diff --git a/umbrello/umbrello/codegenerators/javacodeaccessormethod.cpp b/umbrello/umbrello/codegenerators/javacodeaccessormethod.cpp
new file mode 100644
index 00000000..524e6a48
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeaccessormethod.cpp
@@ -0,0 +1,223 @@
+/***************************************************************************
+ * *
+ * 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 : Fri Jun 20 2003
+ */
+
+// own header
+#include "javacodeaccessormethod.h"
+
+// qt/kde includes
+#include <kdebug.h>
+
+// local includes
+#include "../attribute.h"
+#include "../codegenerator.h"
+#include "../codegenerationpolicy.h"
+#include "../classifiercodedocument.h"
+#include "../umlobject.h"
+#include "../umlrole.h"
+#include "../uml.h"
+#include "codegen_utils.h"
+#include "javaclassifiercodedocument.h"
+#include "javacodegenerationpolicy.h"
+#include "javacodeclassfield.h"
+#include "javacodedocumentation.h"
+
+// Constructors/Destructors
+//
+
+JavaCodeAccessorMethod::JavaCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type)
+ : CodeAccessorMethod ( field )
+{
+ setType(type);
+
+ // lets use full-blown comment
+ JavaClassifierCodeDocument* jccd = dynamic_cast<JavaClassifierCodeDocument*>(field->getParentDocument());
+ setComment(new JavaCodeDocumentation(jccd));
+}
+
+JavaCodeAccessorMethod::~JavaCodeAccessorMethod ( ) { }
+
+// Other methods
+//
+
+void JavaCodeAccessorMethod::setAttributesOnNode ( QDomDocument & doc, QDomElement & blockElement)
+{
+
+ // set super-class attributes
+ CodeAccessorMethod::setAttributesOnNode(doc, blockElement);
+
+ // set local attributes now
+}
+
+void JavaCodeAccessorMethod::setAttributesFromNode( QDomElement & root)
+{
+
+ // set attributes from superclass method the XMI
+ CodeAccessorMethod::setAttributesFromNode(root);
+
+ // load local stuff
+
+}
+
+void JavaCodeAccessorMethod::updateContent( )
+{
+
+ CodeClassField * parentField = getParentClassField();
+ JavaCodeClassField * javafield = dynamic_cast<JavaCodeClassField*>(parentField);
+ QString fieldName = javafield->getFieldName();
+
+ QString text = "";
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ {
+ int maxOccurs = javafield->maximumListOccurances();
+ QString fieldType = javafield->getTypeName();
+ QString indent = getIndentation();
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+ if(maxOccurs > 0)
+ text += "if ("+fieldName+".size() < "+ QString::number(maxOccurs)+") {"+endLine+indent;
+ text += fieldName+".add(value);";
+ if(maxOccurs > 0)
+ {
+ text += endLine+"} else {"+endLine;
+ text += indent + "System.err.println(\"ERROR: Cant add"+fieldType+" to "+fieldName+", minimum number of items reached.\");"+endLine+'}'+endLine;
+ }
+ break;
+ }
+ case CodeAccessorMethod::GET:
+ text = "return "+fieldName+';';
+ break;
+ case CodeAccessorMethod::LIST:
+ text = "return (List) "+fieldName+';';
+ break;
+ case CodeAccessorMethod::REMOVE:
+ {
+ int minOccurs = javafield->minimumListOccurances();
+ QString fieldType = javafield->getTypeName();
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+ QString indent = getIndentation();
+
+ if(minOccurs > 0)
+ text += "if ("+fieldName+".size() >= "+ QString::number(minOccurs)+") {"+endLine+indent;
+ text += fieldName+".remove(value);";
+ if(minOccurs > 0)
+ {
+ text += endLine+"} else {"+endLine;
+ text += indent + "System.err.println(\"ERROR: Cant remove"+fieldType+" from "+fieldName+", minimum number of items reached.\");"+endLine+'}'+endLine;
+ }
+ break;
+ }
+ case CodeAccessorMethod::SET:
+ text = fieldName+" = value;";
+ break;
+ default:
+ // do nothing
+ break;
+ }
+
+ setText(text);
+
+}
+
+void JavaCodeAccessorMethod::updateMethodDeclaration()
+{
+
+ JavaCodeClassField * javafield = dynamic_cast<JavaCodeClassField*>(getParentClassField());
+ JavaClassifierCodeDocument * javadoc = dynamic_cast<JavaClassifierCodeDocument*>(javafield->getParentDocument());
+ CodeGenerationPolicy *commonpolicy = UMLApp::app()->getCommonPolicy();
+
+ // gather defs
+ CodeGenerationPolicy::ScopePolicy scopePolicy = commonpolicy->getAttributeAccessorScope();
+ QString strVis = javadoc->scopeToJavaDecl(javafield->getVisibility());
+ QString fieldName = javafield->getFieldName();
+ QString fieldType = javafield->getTypeName();
+ QString objectType = javafield->getListObjectType();
+ if(objectType.isEmpty())
+ objectType = fieldName;
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+
+ // set scope of this accessor appropriately..if its an attribute,
+ // we need to be more sophisticated
+ if(javafield->parentIsAttribute())
+ switch (scopePolicy) {
+ case CodeGenerationPolicy::Public:
+ case CodeGenerationPolicy::Private:
+ case CodeGenerationPolicy::Protected:
+ strVis = javadoc->scopeToJavaDecl((Uml::Visibility::Value) scopePolicy);
+ break;
+ default:
+ case CodeGenerationPolicy::FromParent:
+ // do nothing..already have taken parent value
+ break;
+ }
+
+ // some variables we will need to populate
+ QString headerText = "";
+ QString methodReturnType = "";
+ QString methodName = "";
+ QString methodParams = "";
+
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ methodName = "add" + Codegen_Utils::capitalizeFirstLetter(fieldType);
+ methodReturnType = "void";
+ methodParams = objectType+" value ";
+ headerText = "Add an object of type "+objectType+" to the List "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@return void";
+ break;
+ case CodeAccessorMethod::GET:
+ methodName = "get" + Codegen_Utils::capitalizeFirstLetter(fieldName);
+ methodReturnType = fieldType;
+ headerText = "Get the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@return the value of "+fieldName;
+ break;
+ case CodeAccessorMethod::LIST:
+ methodName = "get" + Codegen_Utils::capitalizeFirstLetter(fieldType)+"List";
+ methodReturnType = "List";
+ headerText = "Get the list of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@return List of "+fieldName;
+ break;
+ case CodeAccessorMethod::REMOVE:
+ methodName = "remove" + Codegen_Utils::capitalizeFirstLetter(fieldType);
+ methodReturnType = "void";
+ methodParams = objectType+" value ";
+ headerText = "Remove an object of type "+objectType+" from the List "+fieldName+endLine+getParentObject()->getDoc();
+ break;
+ case CodeAccessorMethod::SET:
+ methodName = "set" + Codegen_Utils::capitalizeFirstLetter(fieldName);
+ methodReturnType = "void";
+ methodParams = fieldType + " value ";
+ headerText = "Set the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine;
+ break;
+ default:
+ // do nothing..no idea what this is
+ kWarning()<<"Warning: cant generate JavaCodeAccessorMethod for type: "<<getType()<<endl;
+ break;
+ }
+
+ // set header once.
+ if(getComment()->getText().isEmpty())
+ getComment()->setText(headerText);
+
+ // set start/end method text
+ setStartMethodText(strVis+' '+methodReturnType+' '+methodName+" ( "+methodParams+" ) {");
+ setEndMethodText("}");
+
+}
+
+void JavaCodeAccessorMethod::update()
+{
+ updateMethodDeclaration();
+ updateContent();
+}
+
+#include "javacodeaccessormethod.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodeaccessormethod.h b/umbrello/umbrello/codegenerators/javacodeaccessormethod.h
new file mode 100644
index 00000000..5a109b59
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeaccessormethod.h
@@ -0,0 +1,65 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Oct 2 2003
+ */
+
+#ifndef JAVACODEACCESSORMETHOD_H
+#define JAVACODEACCESSORMETHOD_H
+
+#include <qstring.h>
+
+#include "../codeaccessormethod.h"
+
+class CodeClassField;
+
+class JavaCodeAccessorMethod : public CodeAccessorMethod
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ JavaCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeAccessorMethod ( );
+
+ /**
+ * Must be called before this object is usable
+ */
+ void update();
+
+protected:
+
+ /** set attributes of the node that represents this class
+ * in the XMI document.
+ */
+ virtual void setAttributesOnNode ( QDomDocument & doc, QDomElement & blockElement);
+
+ /** set the class attributes of this object from
+ * the passed element node.
+ */
+ virtual void setAttributesFromNode ( QDomElement & element);
+
+ virtual void updateMethodDeclaration();
+ virtual void updateContent();
+
+};
+
+#endif // JAVACODEACCESSORMETHOD_H
diff --git a/umbrello/umbrello/codegenerators/javacodeclassfield.cpp b/umbrello/umbrello/codegenerators/javacodeclassfield.cpp
new file mode 100644
index 00000000..627b9b3e
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeclassfield.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * *
+ * 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 : Mon Jun 30 2003
+ */
+
+// own header
+#include "javacodeclassfield.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "javacodecomment.h"
+#include "javacodegenerator.h"
+
+#include "../attribute.h"
+#include "../umlobject.h"
+#include "../umlrole.h"
+#include "../uml.h"
+
+// #include "javacodeaccessormethod.h"
+#include "javaclassifiercodedocument.h"
+
+// Constructors/Destructors
+//
+
+JavaCodeClassField::JavaCodeClassField (ClassifierCodeDocument * parentDoc, UMLRole * role)
+ : CodeClassField(parentDoc, role)
+{
+
+}
+
+JavaCodeClassField::JavaCodeClassField (ClassifierCodeDocument * parentDoc, UMLAttribute * attrib)
+ : CodeClassField(parentDoc, attrib)
+{
+
+}
+
+JavaCodeClassField::~JavaCodeClassField ( ) { }
+
+//
+// Methods
+//
+
+// Other methods
+//
+
+QString JavaCodeClassField::getFieldName() {
+ if (parentIsAttribute())
+ {
+ UMLAttribute * at = (UMLAttribute*) getParentObject();
+ return cleanName(at->getName());
+ }
+ else
+ {
+ UMLRole * role = (UMLRole*) getParentObject();
+ QString roleName = role->getName();
+ if(fieldIsSingleValue()) {
+ return roleName.replace(0, 1, roleName.left(1).lower());
+ } else {
+ return roleName.lower() + "Vector";
+ }
+ }
+}
+
+
+QString JavaCodeClassField::getInitialValue() {
+
+ if (parentIsAttribute())
+ {
+ UMLAttribute * at = dynamic_cast<UMLAttribute*>( getParentObject() );
+ if (at) {
+ return fixInitialStringDeclValue(at->getInitialValue(), getTypeName());
+ } else {
+ kError() << "JavaodeClassField::getInitialValue: parent object is not a UMLAttribute"
+ << endl;
+ return "";
+ }
+ return fixInitialStringDeclValue(at->getInitialValue(), getTypeName());
+ }
+ else
+ {
+ if(fieldIsSingleValue()) {
+ // FIX : IF the multiplicity is "1" then we should init a new object here, if its 0 or 1,
+ // then we can just return 'empty' string (minor problem).
+ return QString("");
+ } else {
+ return " new "+JavaCodeGenerator::getListFieldClassName()+"( )";
+ }
+ }
+
+}
+
+QString JavaCodeClassField::getTypeName ( )
+{
+ return JavaCodeGenerator::fixTypeName(CodeClassField::getTypeName());
+}
+
+#include "javacodeclassfield.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodeclassfield.h b/umbrello/umbrello/codegenerators/javacodeclassfield.h
new file mode 100644
index 00000000..5ed1cea4
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeclassfield.h
@@ -0,0 +1,59 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 30 2003
+ */
+
+
+
+#ifndef JAVACODECLASSFIELD_H
+#define JAVACODECLASSFIELD_H
+
+#include <qstring.h>
+
+#include "../codeclassfield.h"
+
+class ClassifierCodeDocument;
+
+class JavaCodeClassField : public CodeClassField
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructors
+ */
+ JavaCodeClassField (ClassifierCodeDocument * parentDoc, UMLRole * role);
+ JavaCodeClassField (ClassifierCodeDocument * parentDoc, UMLAttribute * attrib);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeClassField ( );
+
+ QString getFieldType();
+ QString getFieldName();
+ QString getInitialValue();
+
+ QString getTypeName ( );
+protected:
+
+private:
+
+ // void initDeclCodeBlock ();
+
+};
+
+#endif // JAVACODECLASSFIELD_H
diff --git a/umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.cpp b/umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.cpp
new file mode 100644
index 00000000..87ebf78a
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.cpp
@@ -0,0 +1,118 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Fri Jul 25 2003
+ */
+
+#include "javacodeclassfielddeclarationblock.h"
+
+#include "javacodeclassfield.h"
+#include "javaclassifiercodedocument.h"
+#include "javacodegenerationpolicy.h"
+#include "../codegenerator.h"
+#include "../classifier.h"
+#include "../umlrole.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+JavaCodeClassFieldDeclarationBlock::JavaCodeClassFieldDeclarationBlock ( CodeClassField * parent )
+ : CodeClassFieldDeclarationBlock ( parent )
+{
+ setOverallIndentationLevel(1);
+ updateContent();
+}
+
+JavaCodeClassFieldDeclarationBlock::~JavaCodeClassFieldDeclarationBlock ( ) { }
+
+//
+// Methods
+//
+
+
+
+// Other methods
+//
+
+/**
+ */
+void JavaCodeClassFieldDeclarationBlock::updateContent( )
+{
+
+ CodeClassField * cf = getParentClassField();
+ ClassifierCodeDocument * doc = cf->getParentDocument();
+ JavaCodeClassField * jcf = dynamic_cast<JavaCodeClassField*>(cf);
+ JavaClassifierCodeDocument* jdoc = dynamic_cast<JavaClassifierCodeDocument*>(doc);
+ CodeGenerationPolicy * commonpolicy = UMLApp::app()->getCommonPolicy();
+
+ CodeGenerationPolicy::ScopePolicy scopePolicy = commonpolicy->getAssociationFieldScope();
+
+ // Set the comment
+ QString notes = getParentObject()->getDoc();
+ getComment()->setText(notes);
+
+ // Set the body
+ QString staticValue = getParentObject()->getStatic() ? "static " : "";
+ QString scopeStr = jdoc->scopeToJavaDecl(getParentObject()->getVisibility());
+
+ // IF this is from an association, then scope taken as appropriate to policy
+ if(!jcf->parentIsAttribute())
+ {
+ switch (scopePolicy) {
+ case CodeGenerationPolicy::Public:
+ case CodeGenerationPolicy::Private:
+ case CodeGenerationPolicy::Protected:
+ scopeStr = jdoc->scopeToJavaDecl((Uml::Visibility::Value) scopePolicy);
+ break;
+ default:
+ case CodeGenerationPolicy::FromParent:
+ // do nothing here... will leave as from parent object
+ break;
+ }
+ }
+
+ QString typeName = jcf->getTypeName();
+ QString fieldName = jcf->getFieldName();
+ QString initialV = jcf->getInitialValue();
+
+ if (!cf->parentIsAttribute() && !cf->fieldIsSingleValue())
+ typeName = "List";
+
+ QString body = staticValue+scopeStr+' '+typeName+' '+fieldName;
+ if (!initialV.isEmpty())
+ body.append(" = " + initialV);
+ else if (!cf->parentIsAttribute())
+ {
+ UMLRole * role = dynamic_cast<UMLRole*>(cf->getParentObject());
+ if (role->getObject()->getBaseType() == Uml::ot_Interface)
+ {
+ // do nothing.. can't instanciate an interface
+ } else {
+
+ // FIX?: IF a constructor method exists in the classifiercodedoc
+ // of the parent Object, then we can use that instead (if its empty).
+ if(cf->fieldIsSingleValue())
+ {
+ if(!typeName.isEmpty())
+ body.append(" = new " + typeName + " ( )");
+ } else
+ body.append(" = new Vector ( )");
+ }
+ }
+
+ setText(body+';');
+
+}
+
+#include "javacodeclassfielddeclarationblock.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.h b/umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.h
new file mode 100644
index 00000000..8166fced
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeclassfielddeclarationblock.h
@@ -0,0 +1,51 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Fri Jul 25 2003
+ */
+
+#ifndef JAVACODECLASSFIELDDECLARATIONBLOCK_H
+#define JAVACODECLASSFIELDDECLARATIONBLOCK_H
+
+#include <qstring.h>
+
+#include "../codeclassfielddeclarationblock.h"
+
+class JavaCodeClassFieldDeclarationBlock : public CodeClassFieldDeclarationBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ JavaCodeClassFieldDeclarationBlock ( CodeClassField * parent );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeClassFieldDeclarationBlock ( );
+
+protected:
+
+ // this will be called by syncToParent whenever the parent object is "modified"
+ void updateContent ( );
+
+private:
+
+
+};
+
+#endif // JAVACODECLASSFIELDDECLARATIONBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/javacodecomment.cpp b/umbrello/umbrello/codegenerators/javacodecomment.cpp
new file mode 100644
index 00000000..bec0e87b
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodecomment.cpp
@@ -0,0 +1,84 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+#include "javacodecomment.h"
+#include <qregexp.h>
+
+// Constructors/Destructors
+//
+
+JavaCodeComment::JavaCodeComment ( CodeDocument * doc, const QString & text )
+ : CodeComment (doc, text)
+{
+
+}
+
+JavaCodeComment::~JavaCodeComment ( ) { }
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+
+// Public attribute accessor methods
+//
+
+// Other methods
+//
+
+QString JavaCodeComment::getNewEditorLine ( int amount ) {
+ QString line = getIndentationString(amount) + "// ";
+ return line;
+}
+
+/** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+QString JavaCodeComment::unformatText ( const QString & text , const QString & indent)
+{
+
+ // remove leading or trailing comment stuff
+ QString mytext = TextBlock::unformatText(text, indent);
+
+ // now leading slashes
+ mytext.remove(QRegExp("^\\/\\/\\s*"));
+ return mytext;
+}
+
+/**
+ * @return QString
+ */
+QString JavaCodeComment::toString ( )
+{
+
+ QString output = "";
+
+ // simple output method
+ if(getWriteOutText())
+ {
+ QString indent = getIndentationString();
+ QString endLine = getNewLineEndingChars();
+ output.append(formatMultiLineText (getText(), indent +"// ", endLine));
+ }
+
+ return output;
+}
+
+
+#include "javacodecomment.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodecomment.h b/umbrello/umbrello/codegenerators/javacodecomment.h
new file mode 100644
index 00000000..1f9b1d8d
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodecomment.h
@@ -0,0 +1,77 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+
+
+#ifndef JAVACODECOMMENT_H
+#define JAVACODECOMMENT_H
+
+#include <qstring.h>
+#include "../codecomment.h"
+
+/**
+ * class JavaCodeComment
+ * A Java code comment. There is only a single styles of comments:
+ * these are simply started with double slash sequence and no terminating
+ * characters
+ */
+
+class JavaCodeComment : virtual public CodeComment
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructors
+ */
+ explicit JavaCodeComment ( CodeDocument * doc, const QString & text = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeComment ( );
+
+ // Public attributes
+ //
+
+
+ // other
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+ /** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+ virtual QString unformatText ( const QString & text, const QString & indent = "" );
+
+ /** a special version here because we want to not only indent
+ * the new line, but to add the "//" sequence as well.
+ */
+ virtual QString getNewEditorLine ( int amount );
+
+protected:
+
+private:
+
+};
+
+#endif // JAVACODECOMMENT_H
diff --git a/umbrello/umbrello/codegenerators/javacodedocumentation.cpp b/umbrello/umbrello/codegenerators/javacodedocumentation.cpp
new file mode 100644
index 00000000..e831d885
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodedocumentation.cpp
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * *
+ * 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 : Mon Jun 23 2003
+ */
+
+// own header
+#include "javacodedocumentation.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "javaclassifiercodedocument.h"
+#include "../codegenerationpolicy.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+JavaCodeDocumentation::JavaCodeDocumentation ( JavaClassifierCodeDocument * doc, const QString & text )
+ : CodeComment(doc, text)
+{
+
+}
+
+JavaCodeDocumentation::~JavaCodeDocumentation ( ) { }
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * Save the XMI representation of this object
+ */
+void JavaCodeDocumentation::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "javacodedocumentation" );
+ setAttributesOnNode(doc, blockElement); // as we added no additional fields to this class we may
+ // just use parent TextBlock method
+ root.appendChild( blockElement );
+}
+
+/**
+ * @return QString
+ */
+QString JavaCodeDocumentation::toString ( )
+{
+
+ QString output = "";
+
+ // simple output method
+ if(getWriteOutText())
+ {
+ bool useDoubleDashOutput = true;
+
+ // need to figure out output type from java policy
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ useDoubleDashOutput = false;
+
+ QString indent = getIndentationString();
+ QString endLine = getNewLineEndingChars();
+ QString body = getText();
+ if(useDoubleDashOutput)
+ {
+ if(!body.isEmpty())
+ output.append(formatMultiLineText (body, indent +"// ", endLine));
+ } else {
+ output.append(indent+"/**"+endLine);
+ output.append(formatMultiLineText (body, indent +" * ", endLine));
+ output.append(indent+" */"+endLine);
+ }
+ }
+
+ return output;
+}
+
+QString JavaCodeDocumentation::getNewEditorLine ( int amount )
+{
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ return getIndentationString(amount) + " * ";
+ else
+ return getIndentationString(amount) + "// ";
+}
+
+int JavaCodeDocumentation::firstEditableLine() {
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ return 1;
+ return 0;
+}
+
+int JavaCodeDocumentation::lastEditableLine() {
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ {
+ return -1; // very last line is NOT editable
+ }
+ return 0;
+}
+
+/** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+QString JavaCodeDocumentation::unformatText ( const QString & text , const QString & indent)
+{
+
+ QString mytext = TextBlock::unformatText(text, indent);
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ // remove leading or trailing comment stuff
+ mytext.remove(QRegExp('^'+indent));
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ {
+ mytext.remove(QRegExp("^\\/\\*\\*\\s*\n?"));
+ mytext.remove(QRegExp("\\s*\\*\\/\\s*\n?$"));
+ mytext.remove(QRegExp("^\\s*\\*\\s*"));
+ } else
+ mytext.remove(QRegExp("^\\/\\/\\s*"));
+
+ return mytext;
+}
+
+
+#include "javacodedocumentation.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodedocumentation.h b/umbrello/umbrello/codegenerators/javacodedocumentation.h
new file mode 100644
index 00000000..246b87a6
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodedocumentation.h
@@ -0,0 +1,95 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+
+
+#ifndef JAVACODEDOCUMENTATION_H
+#define JAVACODEDOCUMENTATION_H
+
+#include <qstring.h>
+#include "../codecomment.h"
+
+class JavaClassifierCodeDocument;
+
+/**
+ * class JavaCodeDocumentation
+ * A Java code comment. There is only a single styles of comments:
+ * these are simply started with double slash sequence and no terminating
+ * characters
+ */
+
+class JavaCodeDocumentation : virtual public CodeComment
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructors
+ */
+ explicit JavaCodeDocumentation ( JavaClassifierCodeDocument * doc, const QString & text = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeDocumentation ( );
+
+ // Public attributes
+ //
+
+ // Other
+ //
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+ /** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+ virtual QString unformatText ( const QString & text, const QString & indent = "" );
+
+ /** a special version here because we want to not only indent
+ * the new line, but to add the " * " sequence as well.
+ */
+ virtual QString getNewEditorLine ( int amount );
+
+ /** Ush. These are terrifically bad and must one day go away.
+ * Both methods indicate the range of lines in this textblock
+ * which may be edited by the codeeditor (assuming that any are
+ * actually editable). The default case is no lines are editable.
+ * The line numbering starts with '0' and a '-1' means no line
+ * qualifies.
+ */
+ virtual int firstEditableLine();
+ virtual int lastEditableLine();
+
+
+protected:
+
+private:
+
+};
+
+#endif // JAVACODEDOCUMENTATION_H
diff --git a/umbrello/umbrello/codegenerators/javacodegenerationformbase.ui b/umbrello/umbrello/codegenerators/javacodegenerationformbase.ui
new file mode 100644
index 00000000..cd39611a
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodegenerationformbase.ui
@@ -0,0 +1,277 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>JavaCodeGenerationFormBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>462</width>
+ <height>376</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="3" column="0">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Project Generation</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_makeANTDocumentCheckBox</cstring>
+ </property>
+ <property name="text">
+ <string>Create ANT build document</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox" row="2" column="0">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Auto-Generate Methods</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>m_generateConstructors</cstring>
+ </property>
+ <property name="text">
+ <string>Empty constructor methods</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>m_generateAssocAccessors</cstring>
+ </property>
+ <property name="text">
+ <string>Association accessor methods</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>m_generateAttribAccessors</cstring>
+ </property>
+ <property name="text">
+ <string>Attribute accessor methods</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox" row="0" column="1">
+ <item>
+ <property name="text">
+ <string>Public</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Private</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Protected</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>From Parent Object</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_accessorScopeCB</cstring>
+ </property>
+ <property name="currentItem">
+ <number>3</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Default attribute accessor scope:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Default association field scope:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <item>
+ <property name="text">
+ <string>Public</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Private</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Protected</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>From Parent Role</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_assocFieldScopeCB</cstring>
+ </property>
+ <property name="currentItem">
+ <number>3</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Documentation</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Style:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>Slash-Slash (//)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Slash-Star (/** */)</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_SelectCommentStyle</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p align="center"&gt;Java Code Generation&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/umbrello/umbrello/codegenerators/javacodegenerationpolicy.cpp b/umbrello/umbrello/codegenerators/javacodegenerationpolicy.cpp
new file mode 100644
index 00000000..2dcc834e
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodegenerationpolicy.cpp
@@ -0,0 +1,188 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+// own header
+#include "javacodegenerationpolicy.h"
+// qt/kde includes
+#include <kconfig.h>
+// app includes
+#include "javacodegenerationpolicypage.h"
+#include "javacodegenerator.h"
+#include "../uml.h"
+
+const bool JavaCodeGenerationPolicy::DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS = true;
+const bool JavaCodeGenerationPolicy::DEFAULT_AUTO_GEN_ASSOC_ACCESSORS = true;
+
+// Constructors/Destructors
+/*
+
+JavaCodeGenerationPolicy::JavaCodeGenerationPolicy(CodeGenerationPolicy *defaults)
+ : CodeGenerationPolicy(defaults)
+{
+ init();
+ setDefaults(defaults,false);
+}
+ */
+
+JavaCodeGenerationPolicy::JavaCodeGenerationPolicy(KConfig *config)
+ // : CodeGenerationPolicy(config)
+{
+ init();
+ setDefaults(config,false);
+}
+
+JavaCodeGenerationPolicy::~JavaCodeGenerationPolicy ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+// Public attribute accessor methods
+//
+
+/**
+ * Set the value of m_autoGenerateAttribAccessors
+ * @param new_var the new value
+ */
+void JavaCodeGenerationPolicy::setAutoGenerateAttribAccessors( bool var ) {
+ m_autoGenerateAttribAccessors = var;
+ m_commonPolicy->emitModifiedCodeContentSig();
+}
+
+/**
+ * Set the value of m_autoGenerateAssocAccessors
+ * @param new_var the new value
+ */
+void JavaCodeGenerationPolicy::setAutoGenerateAssocAccessors( bool var ) {
+ m_autoGenerateAssocAccessors = var;
+ m_commonPolicy->emitModifiedCodeContentSig();
+}
+
+/**
+ * Get the value of m_autoGenerateAttribAccessors
+ * @return the value of m_autoGenerateAttribAccessors
+ */
+bool JavaCodeGenerationPolicy::getAutoGenerateAttribAccessors( ){
+ return m_autoGenerateAttribAccessors;
+}
+
+/**
+ * Get the value of m_autoGenerateAssocAccessors
+ * @return the value of m_autoGenerateAssocAccessors
+ */
+bool JavaCodeGenerationPolicy::getAutoGenerateAssocAccessors( ){
+ return m_autoGenerateAssocAccessors;
+}
+
+// Other methods
+//
+
+void JavaCodeGenerationPolicy::writeConfig ( KConfig * config )
+{
+
+ // write ONLY the Java specific stuff
+ config->setGroup("Java Code Generation");
+
+ config->writeEntry("autoGenAccessors",getAutoGenerateAttribAccessors());
+ config->writeEntry("autoGenAssocAccessors",getAutoGenerateAssocAccessors());
+
+ CodeGenerator *codegen = UMLApp::app()->getGenerator();
+ JavaCodeGenerator *javacodegen = dynamic_cast<JavaCodeGenerator*>(codegen);
+ if (javacodegen)
+ config->writeEntry("buildANTDocument", javacodegen->getCreateANTBuildFile());
+
+}
+
+void JavaCodeGenerationPolicy::setDefaults ( CodeGenPolicyExt * clone, bool emitUpdateSignal )
+{
+
+ JavaCodeGenerationPolicy * jclone;
+ if (!clone)
+ return;
+
+ // NOW block signals for java param setting
+ blockSignals(true); // we need to do this because otherwise most of these
+ // settors below will each send the modifiedCodeContent() signal
+ // needlessly (we can just make one call at the end).
+
+
+ // now do java-specific stuff IF our clone is also a JavaCodeGenerationPolicy object
+ if((jclone = dynamic_cast<JavaCodeGenerationPolicy*>(clone)))
+ {
+ setAutoGenerateAttribAccessors(jclone->getAutoGenerateAttribAccessors());
+ setAutoGenerateAssocAccessors(jclone->getAutoGenerateAssocAccessors());
+ }
+
+ blockSignals(false); // "as you were citizen"
+
+ if(emitUpdateSignal)
+ m_commonPolicy->emitModifiedCodeContentSig();
+
+}
+
+void JavaCodeGenerationPolicy::setDefaults( KConfig * config, bool emitUpdateSignal )
+{
+
+ if(!config)
+ return;
+
+ // call method at the common policy to init default stuff
+ m_commonPolicy->setDefaults(config, false);
+
+ // NOW block signals (because call to super-class method will leave value at "true")
+ blockSignals(true); // we need to do this because otherwise most of these
+ // settors below will each send the modifiedCodeContent() signal
+ // needlessly (we can just make one call at the end).
+
+ // now do java specific stuff
+ config -> setGroup("Java Code Generation");
+
+ setAutoGenerateAttribAccessors(config->readBoolEntry("autoGenAccessors",DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS));
+ setAutoGenerateAssocAccessors(config->readBoolEntry("autoGenAssocAccessors",DEFAULT_AUTO_GEN_ASSOC_ACCESSORS));
+
+ CodeGenerator *codegen = UMLApp::app()->getGenerator();
+ JavaCodeGenerator *javacodegen = dynamic_cast<JavaCodeGenerator*>(codegen);
+ if (javacodegen) {
+ bool mkant = config->readBoolEntry("buildANTDocument", JavaCodeGenerator::DEFAULT_BUILD_ANT_DOC);
+ javacodegen->setCreateANTBuildFile(mkant);
+ }
+
+ blockSignals(false); // "as you were citizen"
+
+ if(emitUpdateSignal)
+ m_commonPolicy->emitModifiedCodeContentSig();
+}
+
+
+/**
+ * Create a new dialog interface for this object.
+ * @return dialog object
+ */
+CodeGenerationPolicyPage * JavaCodeGenerationPolicy::createPage ( QWidget *parent, const char *name ) {
+ return new JavaCodeGenerationPolicyPage ( parent, name, this );
+}
+
+void JavaCodeGenerationPolicy::init() {
+ m_commonPolicy = UMLApp::app()->getCommonPolicy();
+ m_autoGenerateAttribAccessors = DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS;
+ m_autoGenerateAssocAccessors = DEFAULT_AUTO_GEN_ASSOC_ACCESSORS;
+}
+
+
+#include "javacodegenerationpolicy.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodegenerationpolicy.h b/umbrello/umbrello/codegenerators/javacodegenerationpolicy.h
new file mode 100644
index 00000000..2a40cb57
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodegenerationpolicy.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * *
+ * 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) 2003-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 23 2003
+ */
+
+#ifndef JAVACODEGENERATIONPOLICY_H
+#define JAVACODEGENERATIONPOLICY_H
+
+#include <qstring.h>
+#include "codegenpolicyext.h"
+#include "../codegenerationpolicy.h"
+
+class KConfig;
+class CodeGenerationPolicyPage;
+
+class JavaCodeGenerationPolicy : public CodeGenPolicyExt
+{
+ Q_OBJECT
+public:
+
+ static const bool DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS;
+ static const bool DEFAULT_AUTO_GEN_ASSOC_ACCESSORS;
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructors
+ */
+ //JavaCodeGenerationPolicy (CodeGenerationPolicy * defaults = 0);
+ JavaCodeGenerationPolicy (KConfig * config = 0);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeGenerationPolicy ( );
+
+ // Public attributes
+ //
+
+
+ // Public attribute accessor methods
+ //
+
+ /**
+ * Set the value of m_autoGenerateAttribAccessors
+ * @param var the new value
+ */
+ void setAutoGenerateAttribAccessors ( bool var );
+
+ /**
+ * Get the value of m_autoGenerateAttribAccessors
+ * @return value the boolean value of m_autoGenerateAttribAccessors
+ */
+ bool getAutoGenerateAttribAccessors( );
+
+ /**
+ * Set the value of m_autoGenerateAssocAccessors
+ * @param var the new value
+ */
+ void setAutoGenerateAssocAccessors ( bool var );
+
+ /**
+ * Get the value of m_autoGenerateAssocAccessors
+ * @return value the boolean value of m_autoGenerateAssocAccessors
+ */
+ bool getAutoGenerateAssocAccessors( );
+
+ /**
+ * set the defaults for this code generator from the passed generator.
+ */
+ virtual void setDefaults (CodeGenPolicyExt * defaults, bool emitUpdateSignal = true);
+
+ /**
+ * set the defaults from a config file for this code generator from the passed KConfig pointer.
+ */
+ virtual void setDefaults(KConfig * config, bool emitUpdateSignal = true);
+
+ /**
+ * write Default params to passed KConfig pointer.
+ */
+ virtual void writeConfig (KConfig * config);
+
+ /**
+ * Create a new dialog interface for this object.
+ * @return dialog object
+ */
+ CodeGenerationPolicyPage * createPage ( QWidget *parent = 0, const char * name = 0);
+
+protected:
+
+ /**
+ */
+ void init ( );
+
+private:
+
+ CodeGenerationPolicy *m_commonPolicy;
+ bool m_autoGenerateConstructors;
+ bool m_autoGenerateAttribAccessors;
+ bool m_autoGenerateAssocAccessors;
+
+};
+
+#endif // JAVACODEGENERATIONPOLICY_H
diff --git a/umbrello/umbrello/codegenerators/javacodegenerationpolicypage.cpp b/umbrello/umbrello/codegenerators/javacodegenerationpolicypage.cpp
new file mode 100644
index 00000000..fd6d2ae3
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodegenerationpolicypage.cpp
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 30 2003
+ */
+
+// own header
+#include "javacodegenerationpolicypage.h"
+// qt/kde includes
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <kdebug.h>
+#include <klocale.h>
+// app includes
+#include "javacodegenerationformbase.h"
+#include "../uml.h"
+
+JavaCodeGenerationPolicyPage::JavaCodeGenerationPolicyPage( QWidget *parent, const char *name, JavaCodeGenerationPolicy * policy )
+ : CodeGenerationPolicyPage(parent, name, policy)
+{
+ CodeGenerationPolicy *commonPolicy = UMLApp::app()->getCommonPolicy();
+ form = new JavaCodeGenerationFormBase(this);
+ form->m_SelectCommentStyle->setCurrentItem((int)(commonPolicy->getCommentStyle()));
+ form->m_generateConstructors->setChecked(commonPolicy->getAutoGenerateConstructors());
+ form->m_generateAttribAccessors->setChecked(policy->getAutoGenerateAttribAccessors());
+ form->m_generateAssocAccessors->setChecked(policy->getAutoGenerateAssocAccessors());
+ form->m_accessorScopeCB->setCurrentItem(commonPolicy->getAttributeAccessorScope() - 200);
+ form->m_assocFieldScopeCB->setCurrentItem(commonPolicy->getAssociationFieldScope() - 200);
+
+ /**
+ * @todo unclean - CreateANTBuildFile attribute should be in java policy
+ CodeGenerator *codegen = UMLApp::app()->getGenerator();
+ JavaCodeGenerator *javacodegen = dynamic_cast<JavaCodeGenerator*>(codegen);
+ if (javacodegen)
+ form->m_makeANTDocumentCheckBox->setChecked(javacodegen->getCreateANTBuildFile());
+ */
+}
+
+JavaCodeGenerationPolicyPage::~JavaCodeGenerationPolicyPage()
+{
+}
+
+void JavaCodeGenerationPolicyPage::apply()
+{
+ CodeGenerationPolicy *commonPolicy = UMLApp::app()->getCommonPolicy();
+ JavaCodeGenerationPolicy * parent = (JavaCodeGenerationPolicy*) m_parentPolicy;
+
+ // block signals so we don't cause too many update content calls to code documents
+ commonPolicy->blockSignals(true);
+
+ commonPolicy->setCommentStyle((CodeGenerationPolicy::CommentStyle ) form->m_SelectCommentStyle->currentItem());
+ commonPolicy->setAttributeAccessorScope((CodeGenerationPolicy::ScopePolicy) (form->m_accessorScopeCB->currentItem()+200));
+ commonPolicy->setAssociationFieldScope((CodeGenerationPolicy::ScopePolicy) (form->m_assocFieldScopeCB->currentItem()+200));
+ commonPolicy->setAutoGenerateConstructors(form->m_generateConstructors->isChecked());
+ parent->setAutoGenerateAttribAccessors(form->m_generateAttribAccessors->isChecked());
+ parent->setAutoGenerateAssocAccessors(form->m_generateAssocAccessors->isChecked());
+
+ /**
+ * @todo unclean - CreateANTBuildFile attribute should be in java policy
+ CodeGenerator *codegen = UMLApp::app()->getGenerator();
+ JavaCodeGenerator *javacodegen = dynamic_cast<JavaCodeGenerator*>(codegen);
+ if (javacodegen)
+ javacodegen->setCreateANTBuildFile(form->m_makeANTDocumentCheckBox->isChecked());
+ */
+ commonPolicy->blockSignals(false);
+
+ // now send out modified code content signal
+ commonPolicy->emitModifiedCodeContentSig();
+
+}
+
+
+#include "javacodegenerationpolicypage.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodegenerationpolicypage.h b/umbrello/umbrello/codegenerators/javacodegenerationpolicypage.h
new file mode 100644
index 00000000..3b6f85e0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodegenerationpolicypage.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * *
+ * 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) 2003-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 30 2003
+ */
+
+#ifndef JAVACODEGENERATIONPOLICYPAGE_H
+#define JAVACODEGENERATIONPOLICYPAGE_H
+
+#include "../dialogs/codegenerationpolicypage.h"
+#include "javacodegenerationformbase.h"
+
+#include "javacodegenerationpolicy.h"
+
+/**
+ * @author Brian Thomas
+ */
+
+class JavaCodeGenerationPolicyPage : public CodeGenerationPolicyPage {
+ Q_OBJECT
+public:
+
+ explicit JavaCodeGenerationPolicyPage (QWidget *parent=0, const char *name=0, JavaCodeGenerationPolicy * policy = 0);
+
+ virtual ~JavaCodeGenerationPolicyPage();
+
+protected:
+
+ JavaCodeGenerationFormBase * form;
+
+public slots:
+
+ void apply();
+
+};
+
+#endif
+
diff --git a/umbrello/umbrello/codegenerators/javacodegenerator.cpp b/umbrello/umbrello/codegenerators/javacodegenerator.cpp
new file mode 100644
index 00000000..167804af
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodegenerator.cpp
@@ -0,0 +1,339 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Jun 19 2003
+ */
+
+// own header
+#include "javacodegenerator.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+// local includes
+#include "javacodecomment.h"
+#include "codeviewerdialog.h"
+#include "../uml.h"
+
+const bool JavaCodeGenerator::DEFAULT_BUILD_ANT_DOC = false;
+
+// Constructors/Destructors
+//
+
+JavaCodeGenerator::JavaCodeGenerator (QDomElement & elem)
+ : CodeGenerator(elem)
+{
+ init();
+}
+
+JavaCodeGenerator::JavaCodeGenerator ()
+{
+ init();
+}
+
+JavaCodeGenerator::~JavaCodeGenerator ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+// return our language
+Uml::Programming_Language JavaCodeGenerator::getLanguage() {
+ return Uml::pl_Java;
+}
+
+/**
+ * Set the value of m_createANTBuildFile
+ * @param new_var the new value of m_createANTBuildFile
+ */
+void JavaCodeGenerator::setCreateANTBuildFile ( bool buildIt) {
+ m_createANTBuildFile = buildIt;
+ CodeDocument * antDoc = findCodeDocumentByID("ANTDOC");
+ if (antDoc)
+ antDoc->setWriteOutCode(buildIt);
+}
+
+/**
+ * Get the value of m_createANTBuildFile
+ * @return the value of m_createANTBuildFile
+ */
+bool JavaCodeGenerator::getCreateANTBuildFile ( ) {
+ return m_createANTBuildFile;
+}
+
+// In the Java version, we make the ANT build file also available.
+CodeViewerDialog * JavaCodeGenerator::getCodeViewerDialog ( QWidget* parent, CodeDocument *doc,
+ Settings::CodeViewerState state)
+{
+ CodeViewerDialog *dialog = new CodeViewerDialog(parent, doc, state);
+ if(getCreateANTBuildFile())
+ dialog->addCodeDocument(findCodeDocumentByID("ANTDOC"));
+ return dialog;
+}
+
+
+JavaCodeGenerationPolicy * JavaCodeGenerator::getJavaPolicy() {
+ return dynamic_cast<JavaCodeGenerationPolicy*>(UMLApp::app()->getPolicyExt());
+}
+
+bool JavaCodeGenerator::getAutoGenerateAttribAccessors ( )
+{
+ return getJavaPolicy()->getAutoGenerateAttribAccessors ();
+}
+
+bool JavaCodeGenerator::getAutoGenerateAssocAccessors ( )
+{
+ return getJavaPolicy()->getAutoGenerateAssocAccessors ();
+}
+
+QString JavaCodeGenerator::getListFieldClassName () {
+ return QString("Vector");
+}
+
+// Other methods
+//
+
+// IF the type is "string" we need to declare it as
+// the Java Object "String" (there is no string primative in Java).
+// Same thing again for "bool" to "boolean"
+QString JavaCodeGenerator::fixTypeName(const QString &string)
+{
+ if (string.isEmpty() || string.contains(QRegExp("^\\s+$")))
+ return "void";
+ if (string == "string")
+ return "String";
+ if (string == "bool")
+ return "boolean";
+ return cleanName(string);
+}
+
+/**
+ * @return JavaANTCodeDocument
+ */
+JavaANTCodeDocument * JavaCodeGenerator::newANTCodeDocument ( ) {
+ return new JavaANTCodeDocument();
+}
+
+/**
+ * @return ClassifierCodeDocument
+ * @param classifier
+ */
+CodeDocument * JavaCodeGenerator::newClassifierCodeDocument ( UMLClassifier * c)
+{
+ JavaClassifierCodeDocument * doc = new JavaClassifierCodeDocument(c);
+ doc->initCodeClassFields();
+ return doc;
+}
+
+void JavaCodeGenerator::init() {
+ // load Classifier documents from parent document
+ //initFromParentDocument();
+
+ // add in an ANT document
+ JavaANTCodeDocument * buildDoc = newANTCodeDocument( );
+ addCodeDocument(buildDoc);
+
+ // set our 'writeout' policy for that code document
+ setCreateANTBuildFile(DEFAULT_BUILD_ANT_DOC);
+}
+
+QStringList JavaCodeGenerator::defaultDatatypes() {
+ QStringList l;
+ l.append("int");
+ l.append("char");
+ l.append("boolean");
+ l.append("float");
+ l.append("double");
+ l.append("byte");
+ l.append("short");
+ l.append("long");
+ l.append("String");
+ return l;
+}
+
+const QStringList JavaCodeGenerator::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "abstract"
+ << "AbstractMethodError"
+ << "ArithmeticException"
+ << "ArrayIndexOutOfBoundsException"
+ << "ArrayStoreException"
+ << "assert"
+ << "AssertionError"
+ << "auto"
+ << "boolean"
+ << "Boolean"
+ << "break"
+ << "byte"
+ << "Byte"
+ << "catch"
+ << "char"
+ << "Character"
+ << "CharSequence"
+ << "Class"
+ << "ClassCastException"
+ << "ClassCircularityError"
+ << "ClassFormatError"
+ << "ClassLoader"
+ << "ClassNotFoundException"
+ << "clone"
+ << "Cloneable"
+ << "CloneNotSupportedException"
+ << "Comparable"
+ << "Compiler"
+ << "const"
+ << "continue"
+ << "default"
+ << "delete"
+ << "do"
+ << "double"
+ << "Double"
+ << "else"
+ << "enum"
+ << "equals"
+ << "Error"
+ << "Exception"
+ << "ExceptionInInitializerError"
+ << "extends"
+ << "extern"
+ << "false"
+ << "final"
+ << "finalize"
+ << "finally"
+ << "float"
+ << "Float"
+ << "for"
+ << "friend"
+ << "getClass"
+ << "goto"
+ << "hashCode"
+ << "if"
+ << "IllegalAccessError"
+ << "IllegalAccessException"
+ << "IllegalArgumentException"
+ << "IllegalMonitorStateException"
+ << "IllegalStateException"
+ << "IllegalThreadStateException"
+ << "implements"
+ << "import"
+ << "IncompatibleClassChangeError"
+ << "IndexOutOfBoundsException"
+ << "InheritableThreadLocal"
+ << "inline"
+ << "instanceof"
+ << "InstantiationError"
+ << "InstantiationException"
+ << "int"
+ << "Integer"
+ << "interface"
+ << "InternalError"
+ << "InterruptedException"
+ << "LinkageError"
+ << "long"
+ << "Long"
+ << "Math"
+ << "native"
+ << "NegativeArraySizeException"
+ << "new"
+ << "nextgroup=javaUserLabelRef"
+ << "NoClassDefFoundError"
+ << "NoSuchFieldError"
+ << "NoSuchFieldException"
+ << "NoSuchMethodError"
+ << "NoSuchMethodException"
+ << "notify"
+ << "notifyAll"
+ << "null"
+ << "NullPointerException"
+ << "Number"
+ << "NumberFormatException"
+ << "Object"
+ << "operator"
+ << "OutOfMemoryError"
+ << "package"
+ << "Package"
+ << "private"
+ << "Process"
+ << "protected"
+ << "public"
+ << "redeclared"
+ << "register"
+ << "return"
+ << "Runnable"
+ << "Runtime"
+ << "RuntimeException"
+ << "RuntimePermission"
+ << "SecurityException"
+ << "SecurityManager"
+ << "serializable"
+ << "short"
+ << "Short"
+ << "signed"
+ << "sizeof"
+ << "skipwhite"
+ << "StackOverflowError"
+ << "StackTraceElement"
+ << "static"
+ << "strictfp"
+ << "StrictMath"
+ << "String"
+ << "StringBuffer"
+ << "StringIndexOutOfBoundsException"
+ << "struct"
+ << "super"
+ << "switch"
+ << "synchronized"
+ << "template"
+ << "this"
+ << "Thread"
+ << "ThreadDeath"
+ << "ThreadGroup"
+ << "ThreadLocal"
+ << "throw"
+ << "Throwable"
+ << "throws"
+ << "toString"
+ << "transient"
+ << "true"
+ << "try"
+ << "typedef"
+ << "union"
+ << "UnknownError"
+ << "UnsatisfiedLinkError"
+ << "unsigned"
+ << "UnsupportedClassVersionError"
+ << "UnsupportedOperationException"
+ << "VerifyError"
+ << "VirtualMachineError"
+ << "void"
+ << "Void"
+ << "volatile"
+ << "wait"
+ << "while";
+ }
+
+ return keywords;
+}
+
+#include "javacodegenerator.moc"
+
diff --git a/umbrello/umbrello/codegenerators/javacodegenerator.h b/umbrello/umbrello/codegenerators/javacodegenerator.h
new file mode 100644
index 00000000..29edb16f
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodegenerator.h
@@ -0,0 +1,150 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Jun 19 2003
+ */
+
+
+
+#ifndef JAVACODEGENERATOR_H
+#define JAVACODEGENERATOR_H
+
+#include <qstring.h>
+#include "../codeviewerstate.h"
+#include "../codegenerator.h"
+#include "../codeblockwithcomments.h"
+#include "../umldoc.h"
+
+#include "classifierinfo.h"
+#include "javaclassifiercodedocument.h"
+#include "javaantcodedocument.h"
+
+#include "javacodegenerationpolicy.h"
+
+class CodeViewerDialog;
+
+class JavaCodeGenerator : public CodeGenerator
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ static const bool DEFAULT_BUILD_ANT_DOC;
+
+ /**
+ * Empty Constructor
+ */
+ JavaCodeGenerator ();
+ JavaCodeGenerator (QDomElement & element);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeGenerator ( );
+
+ // Public attributes
+ //
+
+
+ // Public attribute accessor methods
+ //
+
+
+ /**
+ * Set the value of m_createANTBuildFile
+ * @param new_var the new value of m_createANTBuildFile
+ */
+ void setCreateANTBuildFile ( bool new_var );
+
+ /**
+ * Get the value of m_createANTBuildFile
+ * @return the value of m_createANTBuildFile
+ */
+ bool getCreateANTBuildFile ( );
+
+ /**
+ * A utility method to get the javaCodeGenerationPolicy()->getAutoGenerateAttribAccessors() value.
+ */
+ bool getAutoGenerateAttribAccessors( );
+
+ /**
+ * A utility method to get the javaCodeGenerationPolicy()->getAutoGenerateAssocAccessors() value.
+ */
+ bool getAutoGenerateAssocAccessors( );
+
+ /**
+ * Get the list variable class name to use. For Java, we have set this to "Vector".
+ */
+ static QString getListFieldClassName();
+
+ /** Get the editing dialog for this code document
+ */
+ virtual CodeViewerDialog * getCodeViewerDialog( QWidget* parent, CodeDocument * doc,
+ Settings::CodeViewerState state);
+
+ // Other methods
+ //
+
+ /**
+ * Utility function for getting the java code generation policy.
+ */
+ JavaCodeGenerationPolicy * getJavaPolicy();
+
+ /**
+ * @return ClassifierCodeDocument
+ * @param classifier
+ */
+ CodeDocument * newClassifierCodeDocument (UMLClassifier * classifier);
+
+ // return "Java"
+ Uml::Programming_Language getLanguage();
+
+ /**
+ * Adds Java's primitives as datatypes
+ */
+ virtual QStringList defaultDatatypes();
+
+ /**
+ * IF the type is "string" we need to declare it as
+ * the Java Object "String" (there is no string primative in Java).
+ * Same thing again for "bool" to "boolean".
+ */
+ static QString fixTypeName(const QString &string);
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+protected:
+
+ /** create the codeblock that will represent the class declaration
+ * for this classifier
+ */
+ CodeBlockWithComments * createClassDecl ( UMLClassifier *c, ClassifierInfo *info, JavaClassifierCodeDocument * doc);
+
+ /**
+ * @return JavaANTCodeDocument
+ */
+ JavaANTCodeDocument * newANTCodeDocument ( );
+
+private:
+
+ void init();
+
+ bool m_createANTBuildFile;
+};
+
+#endif // JAVACODEGENERATOR_H
diff --git a/umbrello/umbrello/codegenerators/javacodeoperation.cpp b/umbrello/umbrello/codegenerators/javacodeoperation.cpp
new file mode 100644
index 00000000..84ce0331
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeoperation.cpp
@@ -0,0 +1,132 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 30 2003
+ */
+
+#include "javacodeoperation.h"
+
+#include "javaclassifiercodedocument.h"
+#include "javacodedocumentation.h"
+#include "javacodegenerator.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+JavaCodeOperation::JavaCodeOperation
+ ( JavaClassifierCodeDocument * doc, UMLOperation *parent, const QString & body, const QString & comment )
+ : CodeOperation (doc, parent, body, comment)
+{
+ // lets not go with the default comment and instead use
+ // full-blown java documentation object instead
+ setComment(new JavaCodeDocumentation(doc));
+
+ // these things never change..
+ setOverallIndentationLevel(1);
+
+ updateMethodDeclaration();
+ updateContent();
+}
+
+JavaCodeOperation::~JavaCodeOperation ( ) { }
+
+// Other methods
+//
+
+// we basically want to update the doc and start text of this method
+void JavaCodeOperation::updateMethodDeclaration()
+{
+
+ CodeDocument * doc = getParentDocument();
+ JavaClassifierCodeDocument * javadoc = dynamic_cast<JavaClassifierCodeDocument*>(doc);
+ UMLOperation * o = getParentOperation();
+ bool isInterface = javadoc->getParentClassifier()->isInterface();
+ QString endLine = getNewLineEndingChars();
+
+ // now, the starting text.
+ QString strVis = javadoc->scopeToJavaDecl(o->getVisibility());
+ // no return type for constructors
+ QString fixedReturn = JavaCodeGenerator::fixTypeName(o->getTypeName());
+ QString returnType = o->isConstructorOperation() ? QString("") : (fixedReturn + QString(" "));
+ QString methodName = o->getName();
+ QString paramStr = QString("");
+
+ // assemble parameters
+ UMLAttributeList list = getParentOperation()->getParmList();
+ int nrofParam = list.count();
+ int paramNum = 0;
+ for(UMLAttribute* parm = list.first(); parm; parm=list.next())
+ {
+ QString rType = parm->getTypeName();
+ QString paramName = parm->getName();
+ paramStr += rType + ' ' + paramName;
+ paramNum++;
+
+ if (paramNum != nrofParam )
+ paramStr += ", ";
+ }
+ QString maybeStatic;
+ if (o->getStatic())
+ maybeStatic = "static ";
+ QString startText = strVis + ' ' + maybeStatic + returnType + methodName + " (" + paramStr + ')';
+
+ // IF the parent is an interface, our operations look different
+ // e.g. they have no body
+ if(isInterface) {
+ startText += ';';
+ setEndMethodText("");
+ } else {
+ startText += " {";
+ setEndMethodText("}");
+ }
+
+ setStartMethodText(startText);
+
+ // Lastly, for text content generation, we fix the comment on the
+ // operation, IF the codeop is autogenerated & currently empty
+ QString comment = o->getDoc();
+ if(comment.isEmpty() && getContentType() == CodeBlock::AutoGenerated)
+ {
+ UMLAttributeList parameters = o->getParmList();
+ for(UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) {
+ comment += endLine + "@param " + iterator.current()->getName() + ' ';
+ comment += iterator.current()->getDoc();
+ }
+ // add a returns statement too
+ if(!returnType.isEmpty())
+ comment += endLine + "@return " + returnType + ' ';
+ getComment()->setText(comment);
+ }
+
+
+ // In Java, for interfaces..we DON'T write out non-public
+ // method declarations.
+ if(isInterface)
+ {
+ UMLOperation * o = getParentOperation();
+ if(o->getVisibility() != Uml::Visibility::Public)
+ setWriteOutText(false);
+ }
+
+}
+
+int JavaCodeOperation::lastEditableLine() {
+ ClassifierCodeDocument * doc = dynamic_cast<ClassifierCodeDocument*>(getParentDocument());
+ if(doc->parentIsInterface())
+ return -1; // very last line is NOT editable as its a one-line declaration w/ no body in
+ // an interface.
+ return 0;
+}
+
+#include "javacodeoperation.moc"
diff --git a/umbrello/umbrello/codegenerators/javacodeoperation.h b/umbrello/umbrello/codegenerators/javacodeoperation.h
new file mode 100644
index 00000000..08a555d8
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javacodeoperation.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Jun 30 2003
+ */
+
+
+#ifndef JAVACODEOPERATION_H
+#define JAVACODEOPERATION_H
+
+#include <qstring.h>
+#include "../codeoperation.h"
+
+class JavaClassifierCodeDocument;
+
+class JavaCodeOperation : virtual public CodeOperation
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ JavaCodeOperation ( JavaClassifierCodeDocument * doc, UMLOperation * op, const QString & body = "", const QString & comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~JavaCodeOperation ( );
+
+ virtual int lastEditableLine();
+
+protected:
+
+ void updateMethodDeclaration();
+
+};
+
+#endif // JAVACODEOPERATION_H
diff --git a/umbrello/umbrello/codegenerators/javawriter.cpp b/umbrello/umbrello/codegenerators/javawriter.cpp
new file mode 100644
index 00000000..3e945c60
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javawriter.cpp
@@ -0,0 +1,936 @@
+/***************************************************************************
+ javawriter.cpp - description
+ This is the "old" code generator that does not support code editing
+ in the Modeller but uses significantly less file space because the
+ source code is not replicated in the XMI file.
+ -------------------
+ copyright : (C) 2003 Brian Thomas brian.thomas@gsfc.nasa.gov
+ (C) 2004-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// own header
+#include "javawriter.h"
+// qt includes
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+// kde includes
+#include <kdebug.h>
+// app includes
+#include "codegen_utils.h"
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../attribute.h"
+#include "../association.h"
+#include "../template.h"
+#include "../umltemplatelist.h"
+
+JavaWriter::JavaWriter() {
+ startline = m_endl + m_indentation;
+}
+
+JavaWriter::~JavaWriter() {}
+
+Uml::Programming_Language JavaWriter::getLanguage() {
+ return Uml::pl_Java;
+}
+
+void JavaWriter::writeClass(UMLClassifier *c)
+{
+
+ if (!c) {
+ kDebug()<<"Cannot write class of NULL concept!\n";
+ return;
+ }
+
+ isInterface = c->isInterface();
+
+ QString fileName = cleanName(c->getName().lower());
+
+ //find an appropriate name for our file
+ fileName = findFileName(c,".java");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // check that we may open that file for writing
+ QFile file;
+ if ( !openFile(file, fileName) ) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // Preparations
+ //
+
+ // sort attributes by Scope
+ UMLAttributeList atl;
+ UMLAttributeList atpub, atprot, atpriv;
+ UMLAttributeList final_atpub, final_atprot, final_atpriv;
+ atpub.setAutoDelete(false);
+ final_atpub.setAutoDelete(false);
+ atprot.setAutoDelete(false);
+ final_atprot.setAutoDelete(false);
+ atpriv.setAutoDelete(false);
+ final_atpriv.setAutoDelete(false);
+
+ if (!isInterface) {
+ UMLAttributeList atl = c->getAttributeList();
+ for (UMLAttribute *at = atl.first(); at ; at = atl.next()) {
+ switch(at->getVisibility())
+ {
+ case Uml::Visibility::Public:
+ if(at->getStatic())
+ final_atpub.append(at);
+ else
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ if(at->getStatic())
+ final_atprot.append(at);
+ else
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ if(at->getStatic())
+ final_atpriv.append(at);
+ else
+ atpriv.append(at);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // another preparation, determine what we have
+ UMLAssociationList associations = c->getSpecificAssocs(Uml::at_Association); // BAD! only way to get "general" associations.
+ UMLAssociationList uniAssociations = c->getUniAssociationToBeImplemented();
+
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ bool hasAssociations = aggregations.count() > 0 || associations.count() > 0 || compositions.count() > 0 || uniAssociations.count() > 0;
+ bool hasAttributes = (atl.count() > 0);
+ bool hasAccessorMethods = hasAttributes || hasAssociations;
+ bool hasOperationMethods = (c->getOpList().count() > 0);
+ // this is a bit too simplistic..some associations are for
+ // SINGLE objects, and WONT be declared as Vectors, so this
+ // is a bit overly inclusive
+ bool hasVectorFields = hasAssociations ? true : false;
+
+ // open text stream to file
+ QTextStream java(&file);
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".java");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),file.name());
+ java<<str<<m_endl;
+ }
+
+ if(!c->getPackage().isEmpty())
+ java<<"package "<<c->getPackage()<<";"<<m_endl;
+
+ // IMPORT statements
+ // Q: Why all utils? Isnt just List and Vector the only classes we are using?
+ // A: doesn't matter at all; its more readable to just include '*' and java compilers
+ // don't slow down or anything. (TZ)
+ if (hasVectorFields )
+ {
+ writeBlankLine(java);
+ java<<"import java.util.*;"<<m_endl;
+ }
+
+ //only import classes in a different package as this class
+ UMLPackageList imports;
+ findObjectsRelated(c,imports);
+ for (UMLPackage *con = imports.first(); con; con = imports.next()) {
+ if (con->getBaseType() == Uml::ot_Datatype)
+ continue;
+ QString pkg = con->getPackage();
+ if (!pkg.isEmpty() && pkg != c->getPackage())
+ java << "import " << pkg << "." << cleanName(con->getName()) << ";"
+ << m_endl;
+ }
+ writeBlankLine(java);
+
+ // write the opening declaration for the class incl any documentation,
+ // interfaces and/or inheritence issues we have
+ writeClassDecl(c, java);
+
+ // start body of class
+ java<<" {"<<m_endl;
+
+ // ATTRIBUTES
+ //
+
+ // write comment for section IF needed
+ if (forceDoc() || hasAccessorMethods)
+ {
+ writeComment("", m_indentation, java);
+ writeComment("Fields", m_indentation, java);
+ writeComment("", m_indentation, java);
+ writeBlankLine(java);
+ }
+
+ writeAttributeDecls(final_atpub, final_atprot, final_atpriv, java);
+ writeAttributeDecls(atpub, atprot, atpriv, java);
+
+ writeAssociationDecls(associations, c->getID(), java);
+ writeAssociationDecls(uniAssociations, c->getID(), java);
+ writeAssociationDecls(aggregations, c->getID(), java);
+ writeAssociationDecls(compositions, c->getID(), java);
+
+ // Constructors: anything we more we need to do here ?
+ //
+ if(!isInterface)
+ writeConstructor(c, java);
+
+ // METHODS
+ //
+
+ // write comment for section IF needed
+ if (forceDoc() || hasAccessorMethods || hasOperationMethods)
+ {
+
+ java<<startline;
+ writeComment("", m_indentation, java);
+ writeComment("Methods", m_indentation, java);
+ writeComment("", m_indentation, java);
+ writeBlankLine(java);
+ writeBlankLine(java);
+ }
+
+ // write comment for sub-section IF needed
+ if (forceDoc() || hasAccessorMethods )
+ {
+ writeComment("", m_indentation, java);
+ writeComment("Accessor methods", m_indentation, java);
+ writeComment("", m_indentation, java);
+ writeBlankLine(java);
+ }
+
+ // Accessors for attributes
+ writeAttributeMethods(final_atpub, Uml::Visibility::Public, java);
+ writeAttributeMethods(final_atprot, Uml::Visibility::Protected, java);
+ writeAttributeMethods(final_atpriv, Uml::Visibility::Private, java);
+ writeAttributeMethods(atpub, Uml::Visibility::Public, java);
+ writeAttributeMethods(atprot, Uml::Visibility::Protected, java);
+ writeAttributeMethods(atpriv, Uml::Visibility::Private, java);
+
+ // accessor methods for associations
+
+ // first: determine the name of the other class
+ writeAssociationMethods(associations, c, java);
+ writeAssociationMethods(uniAssociations, c, java);
+ writeAssociationMethods(aggregations, c, java);
+ writeAssociationMethods(compositions, c, java);
+
+ // Other operation methods
+ // all other operations are now written
+
+ // write comment for sub-section IF needed
+ if (forceDoc() || hasOperationMethods)
+ {
+ writeComment("", m_indentation, java);
+ writeComment("Other methods", m_indentation, java);
+ writeComment("", m_indentation, java);
+ writeBlankLine(java);
+ }
+ writeOperations(c,java);
+
+ writeBlankLine(java);
+ java<<"}"<<m_endl; // end class
+
+ file.close();
+ emit codeGenerated(c, true);
+}
+
+void JavaWriter::writeClassDecl(UMLClassifier *c, QTextStream &java)
+{
+
+ QString classname = cleanName(c->getName()); // our class name
+
+ // write documentation for class, if any, first
+ if(forceDoc() || !c->getDoc().isEmpty())
+ {
+ if(isInterface)
+ writeDocumentation("Interface "+classname,c->getDoc(),"","",java);
+ else
+ writeDocumentation("Class "+classname,c->getDoc(),"","",java);
+
+ writeBlankLine(java);
+ }
+
+ // Now write the actual class declaration
+ QString scope = ""; // = scopeToJavaDecl(c->getVisibility());
+ if (c->getVisibility() != Uml::Visibility::Public) {
+ // We should emit a warning in here .. java doesn't like to allow
+ // private/protected classes. The best we can do (I believe)
+ // is to let these declarations default to "package visibility"
+ // which is a level between traditional "private" and "protected"
+ // scopes. To get this visibility level we just print nothing..
+ } else
+ scope = "public ";
+
+ java<<((c->getAbstract() && !isInterface) ? QString("abstract ") : QString(""))<<scope;
+ if(isInterface)
+ java<<"interface ";
+ else
+ java<<"class ";
+
+ java<<classname;
+
+ // Generics
+ UMLTemplateList template_params = c->getTemplateList();
+ if (template_params.count()) {
+ java << "<";
+ for (UMLTemplate *t = template_params.first(); t; ) {
+ QString formalName = t->getName();
+ java << formalName;
+ QString typeName = t->getTypeName();
+ if (typeName != "class") {
+ java << " extends " << typeName;
+ }
+ if ((t = template_params.next()) != NULL)
+ java << ", ";
+ }
+ java << ">" << m_endl;
+ }
+
+ // write inheritances out
+ UMLClassifier *concept;
+ UMLClassifierList superclasses = c->findSuperClassConcepts(UMLClassifier::CLASS);
+
+ int i = 0;
+ for (concept= superclasses.first(); concept; concept = superclasses.next())
+ {
+ if (i == 0)
+ {
+ java<< " extends ";
+ }
+ else
+ {
+ //The java generated code is wrong ! : No multiple inheritence of class
+ java<< ", " ;
+ }
+ java<< cleanName(concept->getName());
+ i++;
+ }
+
+ UMLClassifierList superInterfaces = c->findSuperClassConcepts(UMLClassifier::INTERFACE);
+ i = 0;
+ for (concept= superInterfaces.first(); concept; concept = superInterfaces.next())
+ {
+ if (i == 0)
+ {
+ if (isInterface)
+ java<< " extends ";
+ else
+ java<< " implements ";
+ }
+ else
+ {
+ //The java generated code is OK ! : multiple inheritence of interface
+ java<< ", " ;
+ }
+ java<< cleanName(concept->getName());
+ i++;
+ }
+
+}
+
+void JavaWriter::writeAttributeDecls(UMLAttributeList &atpub, UMLAttributeList &atprot,
+ UMLAttributeList &atpriv, QTextStream &java )
+{
+ UMLAttribute *at;
+
+ for(at=atpub.first(); at; at=atpub.next())
+ {
+ QString documentation = at->getDoc();
+ QString staticValue = at->getStatic() ? "static " : "";
+ QString typeName = fixTypeName(at->getTypeName());
+ QString initialValue = fixInitialStringDeclValue(at->getInitialValue(), typeName);
+ if(!documentation.isEmpty())
+ writeComment(documentation, m_indentation, java, true);
+ java<<startline<<staticValue<<"public "<<typeName<<" "<<cleanName(at->getName())
+ <<(initialValue.isEmpty()?QString(""):QString(" = ") + initialValue)<<";";
+ }
+
+ for(at=atprot.first();at;at=atprot.next())
+ {
+ QString documentation = at->getDoc();
+ QString typeName = fixTypeName(at->getTypeName());
+ QString staticValue = at->getStatic() ? "static " : "";
+ QString initialValue = fixInitialStringDeclValue(at->getInitialValue(), typeName);
+ if(!documentation.isEmpty())
+ writeComment(documentation, m_indentation, java, true);
+ java<<startline<<staticValue<<"protected "<<typeName<<" "<<cleanName(at->getName())
+ <<(initialValue.isEmpty()?QString(""):QString(" = ") + initialValue)<<";";
+ }
+
+ for(at=atpriv.first();at;at=atpriv.next())
+ {
+ QString documentation = at->getDoc();
+ QString typeName = fixTypeName(at->getTypeName());
+ QString staticValue = at->getStatic() ? "static " : "";
+ QString initialValue = fixInitialStringDeclValue(at->getInitialValue(), typeName);
+ if(!documentation.isEmpty())
+ writeComment(documentation, m_indentation, java, true);
+ java<<startline<<staticValue<<"private "<<typeName<<" "<<cleanName(at->getName())
+ <<(initialValue.isEmpty()?QString(""):QString(" = ") + initialValue)<<";";
+ }
+
+}
+
+void JavaWriter::writeAttributeMethods(UMLAttributeList &atpub, Uml::Visibility visibility, QTextStream &java)
+{
+
+ UMLAttribute *at;
+ for(at=atpub.first(); at; at=atpub.next())
+ {
+ QString fieldName = cleanName(at->getName());
+ // force capitalizing the field name, this is silly,
+ // from what I can tell, this IS the default behavior for
+ // cleanName. I dunno why its not working -b.t.
+ fieldName.stripWhiteSpace();
+ fieldName.replace(0,1,fieldName.at(0).upper());
+
+ writeSingleAttributeAccessorMethods(at->getTypeName(),
+ cleanName(at->getName()),
+ fieldName,
+ at->getDoc(),
+ visibility, Uml::chg_Changeable, at->getStatic(), java);
+ }
+
+}
+
+void JavaWriter::writeComment(const QString &comment, const QString &myIndent,
+ QTextStream &java, bool javaDocStyle)
+{
+ // in the case we have several line comment..
+ // NOTE: this part of the method has the problem of adopting UNIX newline,
+ // need to resolve for using with MAC/WinDoze eventually I assume
+ if (comment.contains(QRegExp("\n"))) {
+
+ if(javaDocStyle)
+ java << myIndent << "/**" << m_endl;
+ QStringList lines = QStringList::split( "\n", comment);
+ for(uint i= 0; i < lines.count(); i++)
+ {
+ writeBlankLine(java);
+ if(javaDocStyle)
+ java<<myIndent<<" * ";
+ else
+ java<<myIndent<<"// ";
+ java << lines[i];
+ }
+ if(javaDocStyle)
+ java << myIndent << " */" << m_endl;
+ } else {
+ // this should be more fancy in the future, breaking it up into 80 char
+ // lines so that it doesn't look too bad
+ writeBlankLine(java);
+ if(javaDocStyle)
+ java << myIndent << "/**" << m_endl << myIndent << " *";
+ else
+ java<<myIndent<<"//";
+ if(comment.length() > 0)
+ java << " " << comment;
+ if(javaDocStyle)
+ java << m_endl << myIndent << " */";
+ }
+}
+
+void JavaWriter::writeDocumentation(QString header, QString body, QString end, QString indent, QTextStream &java)
+{
+ writeBlankLine(java);
+ java<<indent<<"/**"<<m_endl;
+ if (!header.isEmpty())
+ java<<formatDoc(header, indent+" * ");
+ if (!body.isEmpty())
+ java<<formatDoc(body, indent+" * ");
+ if (!end.isEmpty())
+ {
+ QStringList lines = QStringList::split( "\n", end);
+ for(uint i= 0; i < lines.count(); i++)
+ java<<formatDoc(lines[i], indent+" * ");
+ }
+ java<<indent<<" */";
+}
+
+void JavaWriter::writeAssociationDecls(UMLAssociationList associations, Uml::IDType id, QTextStream &java)
+{
+
+ if( forceSections() || !associations.isEmpty() )
+ {
+ bool printRoleA = false, printRoleB = false;
+ for(UMLAssociation *a = associations.first(); a; a = associations.next())
+ {
+ // it may seem counter intuitive, but you want to insert the role of the
+ // *other* class into *this* class.
+ if (a->getObjectId(Uml::A) == id)
+ printRoleB = true;
+
+ if (a->getObjectId(Uml::B) == id)
+ printRoleA = true;
+
+ // First: we insert documentaion for association IF it has either role AND some documentation (!)
+ if ((printRoleA || printRoleB) && !(a->getDoc().isEmpty()))
+ writeComment(a->getDoc(), m_indentation, java);
+
+ // print RoleB decl
+ if (printRoleB)
+ {
+ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::B)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::B), a->getMulti(Uml::B), a->getRoleDoc(Uml::B), a->getVisibility(Uml::B), java);
+ }
+
+ // print RoleA decl
+ if (printRoleA)
+ {
+ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::A)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::A), a->getMulti(Uml::A), a->getRoleDoc(Uml::A), a->getVisibility(Uml::A), java);
+ }
+ }
+ }
+}
+
+void JavaWriter::writeAssociationRoleDecl(QString fieldClassName,
+ QString roleName, QString multi,
+ QString doc, Uml::Visibility visib, QTextStream &java)
+{
+ // ONLY write out IF there is a rolename given
+ // otherwise its not meant to be declared in the code
+ if (roleName.isEmpty())
+ return;
+
+ QString scope = scopeToJavaDecl(visib);
+
+ // always put space between this and prior decl, if any
+ writeBlankLine(java);
+
+ if (!doc.isEmpty())
+ writeComment(doc, m_indentation, java);
+
+ // declare the association based on whether it is this a single variable
+ // or a List (Vector). One day this will be done correctly with special
+ // multiplicity object that we don't have to figure out what it means via regex.
+ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
+ {
+ QString fieldVarName = "m_" + roleName.replace(0, 1, roleName.left(1).lower());
+ java<<startline<<scope<<" "<<fieldClassName<<" "<<fieldVarName<<";";
+ }
+ else
+ {
+ QString fieldVarName = roleName.lower() + "Vector";
+ java<<startline<<scope<<" Vector "<<fieldVarName<<" = new Vector();";
+ // from here we could initialize default values, or put in an init() section
+ // of the constructors
+ }
+
+}
+
+void JavaWriter::writeAssociationMethods (UMLAssociationList associations, UMLClassifier *thisClass, QTextStream &java)
+{
+ if( forceSections() || !associations.isEmpty() )
+ {
+ for(UMLAssociation *a = associations.first(); a; a = associations.next())
+ {
+
+ // insert the methods to access the role of the other
+ // class in the code of this one
+ if (a->getObjectId(Uml::A) == thisClass->getID())
+ {
+ // only write out IF there is a rolename given
+ if(!a->getRoleName(Uml::B).isEmpty()) {
+ QString fieldClassName = getUMLObjectName(a->getObject(Uml::B));
+ writeAssociationRoleMethod(fieldClassName,
+ a->getRoleName(Uml::B),
+ a->getMulti(Uml::B), a->getRoleDoc(Uml::B),
+ a->getVisibility(Uml::B),
+ a->getChangeability(Uml::B), java);
+ }
+ }
+
+ if (a->getObjectId(Uml::B) == thisClass->getID())
+ {
+ // only write out IF there is a rolename given
+ if(!a->getRoleName(Uml::A).isEmpty()) {
+ QString fieldClassName = getUMLObjectName(a->getObject(Uml::A));
+ writeAssociationRoleMethod(fieldClassName, a->getRoleName(Uml::A),
+ a->getMulti(Uml::A),
+ a->getRoleDoc(Uml::A),
+ a->getVisibility(Uml::A),
+ a->getChangeability(Uml::A),
+ java);
+ }
+ }
+
+ }
+ }
+}
+
+void JavaWriter::writeAssociationRoleMethod (QString fieldClassName, QString roleName, QString multi,
+ QString description, Uml::Visibility visib, Uml::Changeability_Type change,
+ QTextStream &java)
+{
+ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
+ {
+ QString fieldVarName = "m_" + roleName.replace(0, 1, roleName.left(1).lower());
+ writeSingleAttributeAccessorMethods(fieldClassName, fieldVarName, roleName,
+ description, visib, change, false, java);
+ }
+ else
+ {
+ QString fieldVarName = roleName.lower() + "Vector";
+ writeVectorAttributeAccessorMethods(fieldClassName, fieldVarName, roleName,
+ description, visib, change, java);
+ }
+}
+
+void JavaWriter::writeVectorAttributeAccessorMethods (QString fieldClassName, QString fieldVarName,
+ QString fieldName, QString description,
+ Uml::Visibility visibility, Uml::Changeability_Type changeType,
+ QTextStream &java)
+{
+
+ fieldClassName = fixTypeName(fieldClassName);
+ fieldName = Codegen_Utils::capitalizeFirstLetter(fieldName);
+ QString strVis = scopeToJavaDecl(visibility);
+
+ // ONLY IF changeability is NOT Frozen
+ if (changeType != Uml::chg_Frozen)
+ {
+ writeDocumentation("Add a "+fieldName+" object to the "+fieldVarName+" List",description,"",m_indentation,java);
+ java<<startline<<strVis<<" void add"<<fieldName<<" ( "<<fieldClassName<<" new_object ) {";
+ java<<startline<<m_indentation<<fieldVarName<<".add(new_object);";
+ java<<startline<<"}"<<m_endl;
+ }
+
+ // ONLY IF changeability is Changeable
+ if (changeType == Uml::chg_Changeable)
+ {
+ writeDocumentation("Remove a "+fieldName+" object from "+fieldVarName+" List",description,"",m_indentation,java);
+ java<<startline<<strVis<<" void remove"<<fieldName<<" ( "<<fieldClassName<<" new_object )";
+ java<<startline<<"{";
+ java<<startline<<m_indentation<<fieldVarName<<".remove(new_object);";
+ java<<startline<<"}"<<m_endl;
+ }
+
+ // always allow getting the list of stuff
+ writeDocumentation("Get the List of "+fieldName+" objects held by "+fieldVarName,description,"@return List of "+fieldName+" objects held by "+fieldVarName,m_indentation,java);
+ java<<startline<<strVis<<" List get"<<fieldName<<"List ( ) {";
+ java<<startline<<m_indentation<<"return (List) "<<fieldVarName<<";";
+ java<<startline<<"}"<<m_endl;
+ writeBlankLine(java);
+}
+
+
+void JavaWriter::writeSingleAttributeAccessorMethods(QString fieldClassName, QString fieldVarName,
+ QString fieldName, QString description,
+ Uml::Visibility visibility, Uml::Changeability_Type change,
+ bool isFinal, QTextStream &java)
+{
+
+ QString strVis = scopeToJavaDecl(visibility);
+ fieldClassName = fixTypeName(fieldClassName);
+ fieldName = Codegen_Utils::capitalizeFirstLetter(fieldName);
+
+ // set method
+ if (change == Uml::chg_Changeable && !isFinal) {
+ writeDocumentation("Set the value of "+fieldVarName,description,"@param newVar the new value of "+fieldVarName,m_indentation,java);
+ java<<startline<<strVis<<" void set"<<fieldName<<" ( "<<fieldClassName<<" newVar ) {";
+ java<<startline<<m_indentation<<fieldVarName<<" = newVar;";
+ java<<startline<<"}"<<m_endl;
+ }
+
+ // get method
+ writeDocumentation("Get the value of "+fieldVarName,description,"@return the value of "+fieldVarName,m_indentation,java);
+ java<<startline<<strVis<<" "<<fieldClassName<<" get"<<fieldName<<" ( ) {";
+ java<<startline<<m_indentation<<"return "<<fieldVarName<<";";
+ java<<startline<<"}";
+ writeBlankLine(java);
+}
+
+void JavaWriter::writeConstructor(UMLClassifier *c, QTextStream &java)
+{
+
+ if (forceDoc())
+ {
+ java<<startline;
+ writeComment("", m_indentation, java);
+ writeComment("Constructors", m_indentation, java);
+ writeComment("", m_indentation, java);
+ writeBlankLine(java);
+ }
+
+ // write the first constructor
+ QString className = cleanName(c->getName());
+ java<<m_indentation<<"public "<<className<<" () { };";
+
+}
+
+// IF the type is "string" we need to declare it as
+// the Java Object "String" (there is no string primative in Java).
+// Same thing again for "bool" to "boolean"
+QString JavaWriter::fixTypeName(const QString& string)
+{
+ if (string.isEmpty())
+ return "void";
+ if (string == "string")
+ return "String";
+ if (string == "bool")
+ return "boolean";
+ return string;
+}
+
+QStringList JavaWriter::defaultDatatypes() {
+ QStringList l;
+ l.append("int");
+ l.append("char");
+ l.append("boolean");
+ l.append("float");
+ l.append("double");
+ l.append("byte");
+ l.append("short");
+ l.append("long");
+ l.append("String");
+ return l;
+}
+
+
+bool JavaWriter::compareJavaMethod(UMLOperation *op1, UMLOperation *op2)
+{
+ if (op1 == NULL || op2 == NULL)
+ return false;
+ if (op1 == op2)
+ return true;
+ if (op1->getName() != op2->getName())
+ return false;
+ UMLAttributeList atl1 = op1->getParmList();
+ UMLAttributeList atl2 = op2->getParmList();
+ if (atl1.count() != atl2.count())
+ return false;
+ UMLAttribute *at1;
+ UMLAttribute *at2;
+ for (at1 = atl1.first(), at2 = atl2.first(); at1 && at2 ; at1 = atl1.next(),at2 = atl2.next())
+ {
+ if (at1->getTypeName() != at2->getTypeName())
+ return false;
+ }
+ return true;
+
+}
+
+bool JavaWriter::javaMethodInList(UMLOperation *umlOp, UMLOperationList &opl)
+{
+ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
+ if (JavaWriter::compareJavaMethod(op, umlOp)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void JavaWriter::getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath)
+{
+ UMLClassifierList superClasses = c->findSuperClassConcepts();
+
+ for (UMLClassifier *concept= superClasses.first(); concept; concept = superClasses.next())
+ {
+ getSuperImplementedOperations(concept, yetImplementedOpList, toBeImplementedOpList, (concept->isInterface() && noClassInPath));
+ UMLOperationList opl = concept->getOpList();
+ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
+ if (concept->isInterface() && noClassInPath) {
+ if (!JavaWriter::javaMethodInList(op,toBeImplementedOpList))
+ toBeImplementedOpList.append(op);
+ }
+ else
+ {
+ if (!JavaWriter::javaMethodInList(op, yetImplementedOpList))
+ yetImplementedOpList.append(op);
+ }
+ }
+ }
+
+}
+
+void JavaWriter::getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opList )
+{
+ UMLOperationList yetImplementedOpList;
+ UMLOperationList toBeImplementedOpList;
+
+ getSuperImplementedOperations(c,yetImplementedOpList, toBeImplementedOpList);
+ for (UMLOperation *op = toBeImplementedOpList.first(); op; op = toBeImplementedOpList.next())
+ {
+ if ( ! JavaWriter::javaMethodInList(op, yetImplementedOpList) && ! JavaWriter::javaMethodInList(op, opList) )
+ opList.append(op);
+ }
+}
+
+void JavaWriter::writeOperations(UMLClassifier *c, QTextStream &java) {
+ UMLOperationList opl;
+ UMLOperationList oppub,opprot,oppriv;
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ opl = c->getOpList();
+ if (! c->isInterface()) {
+ getInterfacesOperationsToBeImplemented(c, opl);
+ }
+ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // do people REALLY want these comments? Hmm.
+ /*
+ if(forceSections() || oppub.count())
+ {
+ writeComment("public operations",m_indentation,java);
+ writeBlankLine(java);
+ }
+ */
+ writeOperations(oppub,java);
+
+ /*
+ if(forceSections() || opprot.count())
+ {
+ writeComment("protected operations",m_indentation,java);
+ writeBlankLine(java);
+ }
+ */
+ writeOperations(opprot,java);
+
+ /*
+ if(forceSections() || oppriv.count())
+ {
+ writeComment("private operations",m_indentation,java);
+ writeBlankLine(java);
+ }
+ */
+ writeOperations(oppriv,java);
+
+}
+
+void JavaWriter::writeOperations(UMLOperationList &oplist, QTextStream &java) {
+ UMLOperation *op;
+ UMLAttributeList atl;
+ UMLAttribute *at;
+ int i,j;
+ QString str;
+
+ // generate method decl for each operation given
+ for( op=oplist.first(); op ;op=oplist.next())
+ {
+
+ QString returnStr = "";
+ // write documentation
+
+ QString methodReturnType = fixTypeName(op->getTypeName());
+ if(methodReturnType != "void")
+ returnStr += "@return "+methodReturnType+"\n";
+
+ str = ""; // reset for next method
+ str += ((op->getAbstract() && !isInterface) ? "abstract ":"");
+ str += scopeToJavaDecl(op->getVisibility()) + ' ';
+ str += (op->getStatic() ? "static ":"");
+ str += methodReturnType + ' ' +cleanName(op->getName()) + "( ";
+
+ atl = op->getParmList();
+ i= atl.count();
+ j=0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+ QString typeName = fixTypeName(at->getTypeName());
+ QString atName = cleanName(at->getName());
+ str += typeName + ' ' + atName +
+ (!(at->getInitialValue().isEmpty()) ?
+ (QString(" = ")+at->getInitialValue()) :
+ QString(""))
+ + ((j < i-1)?", ":"");
+ returnStr += "@param "+atName+' '+at->getDoc()+"\n";
+ }
+ str+= " )";
+
+ // method only gets a body IF its not abstract
+ if (op->getAbstract() || isInterface)
+ str+=";\n\n"; // terminate now
+ else
+ str+=startline+"{\n\n"+m_indentation+"}\n\n"; // empty method body
+
+ // write it out
+ writeDocumentation("", op->getDoc(), returnStr, m_indentation, java);
+ java<<startline<<str;
+ }
+}
+
+QString JavaWriter::fixInitialStringDeclValue(QString value, QString type)
+{
+ // check for strings only
+ if (!value.isEmpty() && type == "String") {
+ if (!value.startsWith("\""))
+ value.prepend("\"");
+ if (!value.endsWith("\""))
+ value.append("\"");
+ }
+ return value;
+}
+
+QString JavaWriter::scopeToJavaDecl(Uml::Visibility scope)
+{
+ QString scopeString;
+ switch(scope)
+ {
+ case Uml::Visibility::Public:
+ scopeString = "public";
+ break;
+ case Uml::Visibility::Protected:
+ scopeString = "protected";
+ break;
+ case Uml::Visibility::Private:
+ default:
+ scopeString = "private";
+ break;
+ }
+ return scopeString;
+}
+
+// methods like this _shouldn't_ be needed IF we properly did things thruought the code.
+QString JavaWriter::getUMLObjectName(UMLObject *obj)
+{
+ return(obj!=0)?obj->getName():QString("NULL");
+}
+
+void JavaWriter::writeBlankLine(QTextStream &java)
+{
+ java<<m_endl;
+}
+
diff --git a/umbrello/umbrello/codegenerators/javawriter.h b/umbrello/umbrello/codegenerators/javawriter.h
new file mode 100644
index 00000000..2469f6d0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/javawriter.h
@@ -0,0 +1,236 @@
+/***************************************************************************
+ javawriter.h - description
+ This is the "old" code generator that does not support code editing
+ in the Modeller but uses significantly less file space because the
+ source code is not replicated in the XMI file.
+ -------------------
+ copyright : (C) 2003 Brian Thomas
+ (C) 2004 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef JAVAWRITER_H
+#define JAVAWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umloperationlist.h"
+#include "../umlattributelist.h"
+#include "../umlassociationlist.h"
+
+class UMLOperation;
+
+/**
+ * class JavaWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate a java source file for
+ * that concept
+ */
+class JavaWriter : public SimpleCodeGenerator {
+public:
+
+ /**
+ * Constructor, initialises a couple of variables
+ */
+ JavaWriter();
+
+ /**
+ * Destructor, empty
+ */
+ virtual ~JavaWriter();
+
+ /**
+ * call this method to generate java code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "Java"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * Overrides method from class CodeGenerator
+ */
+ QStringList defaultDatatypes();
+
+private:
+
+ /**
+ * Writes class's documentation then the class header
+ * public abstract class Foo extents {
+ */
+ void writeClassDecl(UMLClassifier *c, QTextStream &java);
+
+ /**
+ * Writes the comment and class constructor
+ */
+ void writeConstructor(UMLClassifier *c, QTextStream &java);
+
+ /**
+ * return true if the two operations have the same name and the same parameters
+ * @param op1 first operation to be compared
+ * @param op2 second operation to be compared
+ */
+ static bool compareJavaMethod(UMLOperation *op1, UMLOperation *op2);
+
+ /**
+ * return true if the operation is in the list
+ * @param umlOp operation to be searched
+ * @param opl list of operations
+ */
+ static bool javaMethodInList(UMLOperation *umlOp, UMLOperationList &opl);
+
+ /**
+ * get all operations which a given class inherit from all its super interfaces and get all operations
+ * which this given class inherit from all its super classes
+ * @param c the class for which we are generating code
+ * @param yetImplementedOpList the list of yet implemented operations
+ * @param toBeImplementedOpList the list of to be implemented operations
+ * @param noClassInPath tells if there is a class between the base class and the current interface
+ */
+ void getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath = true);
+
+ /**
+ * get all operations which a given class inherit from all its super interfaces and that should be implemented
+ * @param c the class for which we are generating code
+ * @param opl the list of operations used to append the operations
+ */
+ void getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opl);
+
+ /**
+ * write all operations for a given class
+ * @param c the class for which we are generating code
+ * @param j the stream associated with the output file
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &j);
+
+ /**
+ * write a list of operations for a given class
+ * @param list the list of operations you want to write
+ * @param j the stream associated with the output file
+ */
+ void writeOperations(UMLOperationList &list, QTextStream &j);
+
+ /**
+ * write all attributes for a given class
+ * @param c the class for which we are generating code
+ * @param j the stream associated with the output file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &j);
+
+ /**
+ * writes the Attribute declarations
+ * @param atpub List of public attributes
+ * @param atprot list of protected attributes
+ * @param atpriv list of private attributes
+ * @param java text stream
+ */
+ void writeAttributeDecls(UMLAttributeList &atpub, UMLAttributeList &atprot,
+ UMLAttributeList &atpriv, QTextStream &java );
+
+ /**
+ * Searches a list of associations for appropriate ones to write out as attributes
+ */
+ void writeAssociationDecls(UMLAssociationList associations, Uml::IDType id, QTextStream &java);
+
+ /**
+ * Writes out an association as an attribute using Vector
+ */
+ void writeAssociationRoleDecl(QString fieldClassName, QString roleName, QString multi,
+ QString doc, Uml::Visibility visib, QTextStream &java);
+
+ /**
+ * calls @ref writeSingleAttributeAccessorMethods() on each of the attributes in atpub
+ */
+ void writeAttributeMethods(UMLAttributeList &atpub, Uml::Visibility visibility, QTextStream &java);
+
+ /**
+ * calls @ref writeAssociationRoleMethod() on each of the associations in the given list
+ */
+ void writeAssociationMethods(UMLAssociationList associations, UMLClassifier *thisClass,
+ QTextStream &java);
+
+ /**
+ * calls @ref writeSingleAttributeAccessorMethods() or @ref
+ * writeVectorAttributeAccessorMethods() on the assocaition
+ * role
+ */
+ void writeAssociationRoleMethod(QString fieldClassName, QString roleName, QString multi,
+ QString description, Uml::Visibility visib, Uml::Changeability_Type change,
+ QTextStream &java);
+
+ /**
+ * Writes getFoo() and setFoo() accessor methods for the attribute
+ */
+ void writeSingleAttributeAccessorMethods(QString fieldClassName, QString fieldVarName,
+ QString fieldName, QString description,
+ Uml::Visibility visibility, Uml::Changeability_Type change,
+ bool isFinal, QTextStream &java);
+
+ /**
+ * Writes addFoo() and removeFoo() accessor methods for the Vector attribute
+ */
+ void writeVectorAttributeAccessorMethods(QString fieldClassName, QString fieldVarName,
+ QString fieldName, QString description,
+ Uml::Visibility visibility, Uml::Changeability_Type change,
+ QTextStream &java);
+
+ /**
+ * Writes a // style comment
+ */
+ void writeComment(const QString &text, const QString &indent, QTextStream &java, bool javaDocStyle=false);
+
+ /**
+ * Writes a documentation comment
+ */
+ void writeDocumentation(QString header, QString body, QString end, QString indent, QTextStream &java);
+
+ /**
+ * Returns the name of the given object (if it exists)
+ */
+ QString getUMLObjectName(UMLObject *obj);
+
+ /**
+ * Replaces `string' with `String' and `bool' with `boolean'
+ */
+ QString fixTypeName(const QString& string);
+
+ /**
+ * check that initial values of strings have quotes around them
+ */
+ QString fixInitialStringDeclValue(QString value, QString type);
+
+ /**
+ * Write a blank line
+ */
+ void writeBlankLine(QTextStream& java);
+
+ /**
+ * a little method for converting scope to string value
+ */
+ QString scopeToJavaDecl(Uml::Visibility scope);
+
+ /**
+ * A \n, used at the end of each line
+ */
+ QString startline;
+
+ /**
+ * Whether or not this concept is an interface.
+ */
+ bool isInterface;
+
+};
+
+
+#endif // JAVAWRITER_H
+
diff --git a/umbrello/umbrello/codegenerators/jswriter.cpp b/umbrello/umbrello/codegenerators/jswriter.cpp
new file mode 100644
index 00000000..1dbb45d6
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/jswriter.cpp
@@ -0,0 +1,308 @@
+/***************************************************************************
+ begin : Sat Feb 08 2003
+ copyright : (C) 2003 by Alexander Blum
+ email : blum@kewbee.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License js published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "jswriter.h"
+#include "../association.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../umldoc.h"
+#include "../attribute.h"
+
+#include <kdebug.h>
+
+#include <qregexp.h>
+#include <qtextstream.h>
+
+JSWriter::JSWriter() {
+}
+
+JSWriter::~JSWriter() {}
+
+
+void JSWriter::writeClass(UMLClassifier *c)
+{
+ if(!c)
+ {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ QString classname = cleanName(c->getName());
+ QString fileName = c->getName().lower();
+
+ //find an appropriate name for our file
+ fileName = findFileName(c,".js");
+ if (fileName.isEmpty())
+ {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile filejs;
+ if(!openFile(filejs, fileName))
+ {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream js(&filejs);
+
+ //////////////////////////////
+ //Start generating the code!!
+ /////////////////////////////
+
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".js");
+ if(!str.isEmpty())
+ {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),filejs.name());
+ js << str << m_endl;
+ }
+
+
+ //write includes
+ UMLPackageList includes;
+ findObjectsRelated(c,includes);
+ for (UMLPackage *conc = includes.first(); conc; conc = includes.next())
+ {
+ QString headerName = findFileName(conc, ".js");
+ if ( !headerName.isEmpty() )
+ {
+ js << "#include \"" << headerName << "\"" << m_endl;
+ }
+ }
+ js << m_endl;
+
+ //Write class Documentation if there is somthing or if force option
+ if(forceDoc() || !c->getDoc().isEmpty())
+ {
+ js << m_endl << "/**" << m_endl;
+ js << " * class " << classname << m_endl;
+ js << formatDoc(c->getDoc()," * ");
+ js << " */" << m_endl << m_endl;
+ }
+
+
+ //check if class is abstract and / or has abstract methods
+ if(c->getAbstract() && !hasAbstractOps(c))
+ js << "/******************************* Abstract Class ****************************" << m_endl << " "
+ << classname << " does not have any pure virtual methods, but its author" << m_endl
+ << " defined it as an abstract class, so you should not use it directly." << m_endl
+ << " Inherit from it instead and create only objects from the derived classes" << m_endl
+ << "*****************************************************************************/" << m_endl << m_endl;
+
+ js << classname << " = function ()" << m_endl;
+ js << "{" << m_endl;
+ js << m_indentation << "this._init ();" << m_endl;
+ js << "}" << m_endl;
+ js << m_endl;
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+ for (UMLClassifier *obj = superclasses.first();
+ obj; obj = superclasses.next()) {
+ js << classname << ".prototype = new " << cleanName(obj->getName()) << " ();" << m_endl;
+ }
+
+ js << m_endl;
+
+ if (! c->isInterface()) {
+ UMLAttributeList atl = c->getAttributeList();
+
+ js << "/**" << m_endl;
+ QString temp = "_init sets all " + classname + " attributes to their default value."
+ " Make sure to call this method within your class constructor";
+ js << formatDoc(temp, " * ");
+ js << " */" << m_endl;
+ js << classname << ".prototype._init = function ()" << m_endl;
+ js << "{" << m_endl;
+ for(UMLAttribute *at = atl.first(); at ; at = atl.next())
+ {
+ if (forceDoc() || !at->getDoc().isEmpty())
+ {
+ js << m_indentation << "/**" << m_endl
+ << formatDoc(at->getDoc(), m_indentation + " * ")
+ << m_indentation << " */" << m_endl;
+ }
+ if(!at->getInitialValue().isEmpty())
+ {
+ js << m_indentation << "this.m_" << cleanName(at->getName()) << " = " << at->getInitialValue() << ";" << m_endl;
+ }
+ else
+ {
+ js << m_indentation << "this.m_" << cleanName(at->getName()) << " = \"\";" << m_endl;
+ }
+ }
+ }
+
+ //associations
+ UMLAssociationList aggregations = c->getAggregations();
+ if (forceSections() || !aggregations.isEmpty ())
+ {
+ js << m_endl << m_indentation << "/**Aggregations: */" << m_endl;
+ writeAssociation(classname, aggregations , js );
+
+ }
+ UMLAssociationList compositions = c->getCompositions();
+ if( forceSections() || !compositions.isEmpty())
+ {
+ js << m_endl << m_indentation << "/**Compositions: */" << m_endl;
+ writeAssociation(classname, compositions , js );
+
+ }
+ js << m_endl;
+ js << "}" << m_endl;
+ js << m_endl;
+
+ //operations
+ UMLOperationList ops(c->getOpList());
+ writeOperations(classname, &ops, js);
+
+ js << m_endl;
+
+ //finish file
+
+ //close files and notfiy we are done
+ filejs.close();
+ emit codeGenerated(c, true);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+void JSWriter::writeAssociation(QString& classname, UMLAssociationList& assocList , QTextStream &js)
+{
+ for (UMLAssociation *a = assocList.first(); a; a = assocList.next()) {
+ // association side
+ Uml::Role_Type role = (a->getObject(Uml::A)->getName() == classname ? Uml::B : Uml::A);
+
+ QString roleName(cleanName(a->getRoleName(role)));
+
+ if (!roleName.isEmpty()) {
+
+ // association doc
+ if (forceDoc() || !a->getDoc().isEmpty())
+ {
+ js << m_indentation << "/**" << m_endl
+ << formatDoc(a->getDoc(), m_indentation + " * ")
+ << m_indentation << " */" << m_endl;
+ }
+
+ // role doc
+ if (forceDoc() || !a->getRoleDoc(role).isEmpty())
+ {
+ js << m_indentation << "/**" << m_endl
+ << formatDoc(a->getRoleDoc(role), m_indentation + " * ")
+ << m_indentation << " */" << m_endl;
+ }
+
+ bool okCvt;
+ int nMulti = a->getMulti(role).toInt(&okCvt,10);
+ bool isNotMulti = a->getMulti(role).isEmpty() || (okCvt && nMulti == 1);
+
+ QString typeName(cleanName(a->getObject(role)->getName()));
+
+ if (isNotMulti)
+ js << m_indentation << "this.m_" << roleName << " = new " << typeName << "();" << m_endl;
+ else
+ js << m_indentation << "this.m_" << roleName << " = new Array();" << m_endl;
+
+ // role visibility
+ }
+ }
+}
+
+void JSWriter::writeOperations(QString classname, UMLOperationList *opList, QTextStream &js)
+{
+ UMLOperation *op;
+ UMLAttribute *at;
+
+ for(op = opList->first(); op; op = opList->next())
+ {
+ UMLAttributeList atl = op->getParmList();
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+ for (at = atl.first(); at; at = atl.next())
+ writeDoc |= !at->getDoc().isEmpty();
+
+ if( writeDoc ) //write method documentation
+ {
+ js << "/**" << m_endl << formatDoc(op->getDoc()," * ");
+
+ for (at = atl.first(); at; at = atl.next()) //write parameter documentation
+ {
+ if(forceDoc() || !at->getDoc().isEmpty())
+ {
+ js << " * @param " + cleanName(at->getName())<<m_endl;
+ js << formatDoc(at->getDoc()," * ");
+ }
+ }//end for : write parameter documentation
+ js << " */" << m_endl;
+ }//end if : write method documentation
+
+ js << classname << ".prototype." << cleanName(op->getName()) << " = function " << "(";
+
+ int i = atl.count();
+ int j=0;
+ for (at = atl.first(); at ;at = atl.next(),j++)
+ {
+ js << cleanName(at->getName())
+ << (!(at->getInitialValue().isEmpty()) ? (QString(" = ")+at->getInitialValue()) : QString(""))
+ << ((j < i-1)?", ":"");
+ }
+ js << ")" << m_endl << "{" << m_endl <<
+ m_indentation << m_endl << "}" << m_endl;
+ js << m_endl << m_endl;
+ }//end for
+}
+
+/**
+ * returns "JavaScript"
+ */
+Uml::Programming_Language JSWriter::getLanguage() {
+ return Uml::pl_JavaScript;
+}
+
+const QStringList JSWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "break"
+ << "case"
+ << "const"
+ << "continue"
+ << "default"
+ << "else"
+ << "false"
+ << "for"
+ << "function"
+ << "if"
+ << "in"
+ << "new"
+ << "return"
+ << "switch"
+ << "this"
+ << "true"
+ << "var"
+ << "while"
+ << "with";
+ }
+
+ return keywords;
+}
+
+#include "jswriter.moc"
diff --git a/umbrello/umbrello/codegenerators/jswriter.h b/umbrello/umbrello/codegenerators/jswriter.h
new file mode 100644
index 00000000..a9c5ebde
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/jswriter.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ jswriter.h - description
+ -------------------
+ begin : Sat Feb 08 2003
+ copyright : (C) 2003 by Alexander Blum
+ email : blum@kewbee.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef JSWRITER_H
+#define JSWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umloperationlist.h"
+#include "../umlassociationlist.h"
+
+/**
+ * class JSWriter is a JavaScript code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class JSWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ JSWriter();
+ virtual ~JSWriter();
+
+ /**
+ * call this method to generate Actionscript code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "JavaScript"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * we do not want to write the comment "Private methods" twice
+ */
+ bool bPrivateSectionCommentIsWritten;
+
+ /**
+ * write a list of class operations
+ *
+ * @param classname the name of the class
+ * @param opList the list of operations
+ * @param js output stream for the JS file
+ */
+ void writeOperations(QString classname, UMLOperationList *opList, QTextStream &js);
+
+ /**
+ * write a list of associations
+ *
+ * @param classname the name of the class
+ * @param assocList the list of associations
+ * @param as output stream for the AS file
+ */
+ void writeAssociation(QString& classname, UMLAssociationList& assoclist , QTextStream &js);
+};
+
+#endif //JSWRITER
diff --git a/umbrello/umbrello/codegenerators/pascalwriter.cpp b/umbrello/umbrello/codegenerators/pascalwriter.cpp
new file mode 100644
index 00000000..92a45bd2
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/pascalwriter.cpp
@@ -0,0 +1,542 @@
+/***************************************************************************
+ * *
+ * 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) 2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#include "pascalwriter.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include "../umldoc.h"
+#include "../uml.h"
+#include "../classifier.h"
+#include "../enum.h"
+#include "../classifierlistitem.h"
+#include "../umlclassifierlistitemlist.h"
+#include "../umltemplatelist.h"
+#include "../folder.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../operation.h"
+#include "../template.h"
+#include "../umlnamespace.h"
+#include "classifierinfo.h"
+
+const QString PascalWriter::defaultPackageSuffix = "_Holder";
+
+PascalWriter::PascalWriter() {
+}
+
+PascalWriter::~PascalWriter() {}
+
+/**
+ * returns "Pascal"
+ */
+Uml::Programming_Language PascalWriter::getLanguage() {
+ return Uml::pl_Pascal;
+}
+
+
+bool PascalWriter::isOOClass(UMLClassifier *c) {
+ Uml::Object_Type ot = c->getBaseType();
+ if (ot == Uml::ot_Interface)
+ return true;
+ if (ot == Uml::ot_Enum)
+ return false;
+ if (ot != Uml::ot_Class) {
+ kDebug() << "PascalWriter::isOOClass: unknown object type " << ot << endl;
+ return false;
+ }
+ QString stype = c->getStereotype();
+ if (stype == "CORBAConstant" || stype == "CORBATypedef" ||
+ stype == "CORBAStruct" || stype == "CORBAUnion")
+ return false;
+ // CORBAValue, CORBAInterface, and all empty/unknown stereotypes are
+ // assumed to be OO classes.
+ return true;
+}
+
+QString PascalWriter::qualifiedName(UMLPackage *p, bool withType, bool byValue) {
+ UMLPackage *umlPkg = p->getUMLPackage();
+ QString className = cleanName(p->getName());
+ QString retval;
+
+ if (umlPkg == UMLApp::app()->getDocument()->getRootFolder(Uml::mt_Logical))
+ umlPkg = NULL;
+
+ UMLClassifier *c = dynamic_cast<UMLClassifier*>(p);
+ if (umlPkg == NULL) {
+ retval = className;
+ if (c == NULL || !isOOClass(c))
+ retval.append(defaultPackageSuffix);
+ } else {
+ retval = umlPkg->getFullyQualifiedName(".");
+ if (isOOClass(c)) {
+ retval.append(".");
+ retval.append(className);
+ }
+ }
+ if (! withType)
+ return retval;
+ if (c && isOOClass(c)) {
+ retval.append(".Object");
+ if (! byValue)
+ retval.append("_Ptr");
+ } else {
+ retval.append(".");
+ retval.append(className);
+ }
+ return retval;
+}
+
+void PascalWriter::computeAssocTypeAndRole
+(UMLAssociation *a, QString& typeName, QString& roleName) {
+ roleName = a->getRoleName(Uml::A);
+ if (roleName.isEmpty()) {
+ if (a->getMulti(Uml::A).isEmpty()) {
+ roleName = "M_";
+ roleName.append(typeName);
+ } else {
+ roleName = typeName;
+ roleName.append("_Vector");
+ }
+ }
+ UMLClassifier* c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::A));
+ if (c == NULL)
+ return;
+ typeName = cleanName(c->getName());
+ if (! a->getMulti(Uml::A).isEmpty())
+ typeName.append("_Array_Access");
+}
+
+void PascalWriter::writeClass(UMLClassifier *c) {
+ if (!c) {
+ kDebug() << "Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ const bool isClass = !c->isInterface();
+ QString classname = cleanName(c->getName());
+ QString fileName = qualifiedName(c).lower();
+ fileName.replace('.', '-');
+
+ //find an appropriate name for our file
+ fileName = overwritableName(c, fileName, ".pas");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile file;
+ if (!openFile(file, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // Start generating the code.
+
+ QTextStream pas(&file);
+ //try to find a heading file(license, comments, etc)
+ QString str;
+ str = getHeadingFile(".pas");
+ if (!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"), fileName);
+ str.replace(QRegExp("%filepath%"), file.name());
+ pas << str << endl;
+ }
+
+ QString unit = qualifiedName(c);
+ pas << "unit " << unit << ";" << m_endl << m_endl;
+ pas << "INTERFACE" << m_endl << m_endl;
+ // Use referenced classes.
+ UMLPackageList imports;
+ findObjectsRelated(c, imports);
+ if (imports.count()) {
+ pas << "uses" << m_endl;
+ bool first = true;
+ for (UMLPackage *con = imports.first(); con; con = imports.next()) {
+ if (con->getBaseType() != Uml::ot_Datatype) {
+ if (first)
+ first = false;
+ else
+ pas << "," << m_endl;
+ pas << " " << qualifiedName(con);
+ }
+ }
+ pas << ";" << m_endl << m_endl;
+ }
+
+ pas << "type" << m_endl;
+ m_indentLevel++;
+ if (c->getBaseType() == Uml::ot_Enum) {
+ UMLEnum *ue = static_cast<UMLEnum*>(c);
+ UMLClassifierListItemList litList = ue->getFilteredList(Uml::ot_EnumLiteral);
+ uint i = 0;
+ pas << getIndent() << classname << " = (" << m_endl;
+ m_indentLevel++;
+ for (UMLClassifierListItem *lit = litList.first(); lit; lit = litList.next()) {
+ QString enumLiteral = cleanName(lit->getName());
+ pas << getIndent() << enumLiteral;
+ if (++i < litList.count())
+ pas << "," << m_endl;
+ }
+ m_indentLevel--;
+ pas << ");" << m_endl << m_endl;
+ m_indentLevel--;
+ pas << "end." << m_endl << m_endl;
+ return;
+ }
+ UMLAttributeList atl = c->getAttributeList();
+ if (! isOOClass(c)) {
+ QString stype = c->getStereotype();
+ if (stype == "CORBAConstant") {
+ pas << getIndent() << "// " << stype << " is Not Yet Implemented" << m_endl << m_endl;
+ } else if(stype == "CORBAStruct") {
+ if (isClass) {
+ UMLAttribute *at;
+ pas << getIndent() << classname << " = record" << m_endl;
+ m_indentLevel++;
+ for (at = atl.first(); at; at = atl.next()) {
+ QString name = cleanName(at->getName());
+ QString typeName = at->getTypeName();
+ pas << getIndent() << name << " : " << typeName;
+ QString initialVal = at->getInitialValue();
+ if (initialVal.latin1() && ! initialVal.isEmpty())
+ pas << " := " << initialVal;
+ pas << ";" << m_endl;
+ }
+ m_indentLevel--;
+ pas << "end;" << m_endl << m_endl;
+ }
+ } else if(stype == "CORBAUnion") {
+ pas << getIndent() << "// " << stype << " is Not Yet Implemented" << m_endl << m_endl;
+ } else if(stype == "CORBATypedef") {
+ pas << getIndent() << "// " << stype << " is Not Yet Implemented" << m_endl << m_endl;
+ } else {
+ pas << getIndent() << "// " << stype << ": Unknown stereotype" << m_endl << m_endl;
+ }
+ m_indentLevel--;
+ pas << getIndent() << "end." << m_endl << m_endl;
+ return;
+ }
+
+ // Write class Documentation if non-empty or if force option set.
+ if (forceDoc() || !c->getDoc().isEmpty()) {
+ pas << "//" << m_endl;
+ pas << "// class " << classname << endl;
+ pas << formatDoc(c->getDoc(), "// ");
+ pas << m_endl;
+ }
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+
+ pas << getIndent() << classname << " = object";
+ if (!superclasses.isEmpty()) {
+ // FIXME: Multiple inheritance is not yet supported
+ UMLClassifier* parent = superclasses.first();
+ pas << "(" << qualifiedName(parent) << ")";
+ }
+ pas << m_endl;
+
+ ClassifierInfo info(c);
+ UMLAttributeList atpub = info.atpub;
+ if (isClass && (forceSections() || atpub.count())) {
+ pas << getIndent() << "// Public attributes:" << m_endl;
+ UMLAttribute *at;
+ for (at = atpub.first(); at; at = atpub.next()) {
+ // if (at->getStatic())
+ // continue;
+ pas << getIndent() << cleanName(at->getName()) << " : "
+ << at->getTypeName();
+ if (at && at->getInitialValue().latin1() && ! at->getInitialValue().isEmpty())
+ pas << " := " << at->getInitialValue();
+ pas << ";" << m_endl;
+ }
+ }
+ bool haveAttrs = (isClass && atl.count());
+
+ // Generate public operations.
+ UMLOperationList opl(c->getOpList());
+ UMLOperationList oppub;
+ oppub.setAutoDelete(false);
+ UMLOperation *op;
+ for (op = opl.first(); op; op = opl.next()) {
+ if (op->getVisibility() == Uml::Visibility::Public)
+ oppub.append(op);
+ }
+ if (forceSections() || oppub.count())
+ pas << getIndent() << "// Public methods:" << m_endl << m_endl;
+ for (op = oppub.first(); op; op = oppub.next())
+ writeOperation(op, pas);
+
+ if (info.atprot.count()) {
+ pas << "protected" << m_endl << m_endl;
+ UMLAttribute *at;
+ UMLAttributeList atprot = info.atprot;
+ for (at = atprot.first(); at; at = atprot.next()) {
+ // if (at->getStatic())
+ // continue;
+ pas << getIndent() << cleanName(at->getName()) << " : "
+ << at->getTypeName();
+ if (at && at->getInitialValue().latin1() && ! at->getInitialValue().isEmpty())
+ pas << " := " << at->getInitialValue();
+ pas << ";" << m_endl;
+ }
+ pas << m_endl;
+ }
+ if (info.atpriv.count()) {
+ pas << "private" << m_endl << m_endl;
+ UMLAttribute *at;
+ UMLAttributeList atpriv = info.atpriv;
+ for (at = atpriv.first(); at; at = atpriv.next()) {
+ // if (at->getStatic())
+ // continue;
+ pas << getIndent() << cleanName(at->getName()) << " : "
+ << at->getTypeName();
+ if (at && at->getInitialValue().latin1() && ! at->getInitialValue().isEmpty())
+ pas << " := " << at->getInitialValue();
+ pas << ";" << m_endl;
+ }
+ pas << m_endl;
+ }
+ pas << getIndent() << "end;" << m_endl << m_endl;
+
+ pas << getIndent() << "P" << classname << " = ^" << classname <<";" << m_endl << m_endl;
+
+ m_indentLevel--;
+ pas << "end;" << m_endl << m_endl;
+ file.close();
+ emit codeGenerated(c, true);
+}
+
+
+void PascalWriter::writeOperation(UMLOperation *op, QTextStream &pas, bool is_comment) {
+ if (op->getStatic()) {
+ pas << "// TODO: generate status method " << op->getName() << m_endl;
+ return;
+ }
+ UMLAttributeList atl = op->getParmList();
+ QString rettype = op->getTypeName();
+ bool use_procedure = (rettype.isEmpty() || rettype == "void");
+
+ pas << getIndent();
+ if (is_comment)
+ pas << "// ";
+ if (use_procedure)
+ pas << "procedure ";
+ else
+ pas << "function ";
+ pas << cleanName(op->getName()) << " ";
+ if (atl.count()) {
+ pas << "(" << m_endl;
+ uint i = 0;
+ m_indentLevel++;
+ for (UMLAttribute *at = atl.first(); at; at = atl.next()) {
+ pas << getIndent();
+ if (is_comment)
+ pas << "// ";
+ pas << cleanName(at->getName()) << " : ";
+ Uml::Parameter_Direction pk = at->getParmKind();
+ if (pk != Uml::pd_In)
+ pas << "var ";
+ pas << at->getTypeName();
+ if (! at->getInitialValue().isEmpty())
+ pas << " := " << at->getInitialValue();
+ if (++i < (uint)atl.count())
+ pas << ";" << m_endl;
+ }
+ m_indentLevel--;
+ pas << ")";
+ }
+ if (! use_procedure)
+ pas << " : " << rettype;
+ pas << "; virtual; abstract;" << m_endl << m_endl;
+ // TBH, we make the methods abstract here because we don't have the means
+ // for generating meaningful implementations.
+}
+
+QStringList PascalWriter::defaultDatatypes() {
+ QStringList l;
+ l.append("AnsiString");
+ l.append("Boolean");
+ l.append("Byte");
+ l.append("ByteBool");
+ l.append("Cardinal");
+ l.append("Character");
+ l.append("Currency");
+ l.append("Double");
+ l.append("Extended");
+ l.append("Int64");
+ l.append("Integer");
+ l.append("Longint");
+ l.append("LongBool");
+ l.append("Longword");
+ l.append("QWord");
+ l.append("Real");
+ l.append("Shortint");
+ l.append("ShortString");
+ l.append("Single");
+ l.append("Smallint");
+ l.append("String");
+ l.append("WideString");
+ l.append("Word");
+ return l;
+}
+
+/**
+ * Check whether the given string is a reserved word for the
+ * language of this code generator
+ *
+ * @param rPossiblyReservedKeyword The string to check.
+ */
+bool PascalWriter::isReservedKeyword(const QString & rPossiblyReservedKeyword) {
+
+ const QStringList keywords = reservedKeywords();
+
+ QStringList::ConstIterator it;
+ for (it = keywords.begin(); it != keywords.end(); ++it)
+ if ((*it).lower() == rPossiblyReservedKeyword.lower())
+ return true;
+
+ return false;
+}
+
+/**
+ * get list of reserved keywords
+ */
+const QStringList PascalWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if ( keywords.isEmpty() ) {
+ keywords.append( "absolute" );
+ keywords.append( "abstract" );
+ keywords.append( "and" );
+ keywords.append( "array" );
+ keywords.append( "as" );
+ keywords.append( "asm" );
+ keywords.append( "assembler" );
+ keywords.append( "automated" );
+ keywords.append( "begin" );
+ keywords.append( "case" );
+ keywords.append( "cdecl" );
+ keywords.append( "class" );
+ keywords.append( "const" );
+ keywords.append( "constructor" );
+ keywords.append( "contains" );
+ keywords.append( "default" );
+ keywords.append( "deprecated" );
+ keywords.append( "destructor" );
+ keywords.append( "dispid" );
+ keywords.append( "dispinterface" );
+ keywords.append( "div" );
+ keywords.append( "do" );
+ keywords.append( "downto" );
+ keywords.append( "dynamic" );
+ keywords.append( "else" );
+ keywords.append( "end" );
+ keywords.append( "except" );
+ keywords.append( "export" );
+ keywords.append( "exports" );
+ keywords.append( "external" );
+ keywords.append( "far" );
+ keywords.append( "file" );
+ keywords.append( "final" );
+ keywords.append( "finalization" );
+ keywords.append( "finally" );
+ keywords.append( "for" );
+ keywords.append( "forward" );
+ keywords.append( "function" );
+ keywords.append( "goto" );
+ keywords.append( "if" );
+ keywords.append( "implementation" );
+ keywords.append( "implements" );
+ keywords.append( "in" );
+ keywords.append( "index" );
+ keywords.append( "inherited" );
+ keywords.append( "initialization" );
+ keywords.append( "inline" );
+ keywords.append( "inline" );
+ keywords.append( "interface" );
+ keywords.append( "is" );
+ keywords.append( "label" );
+ keywords.append( "library" );
+ keywords.append( "library" );
+ keywords.append( "local" );
+ keywords.append( "message" );
+ keywords.append( "mod" );
+ keywords.append( "name" );
+ keywords.append( "near" );
+ keywords.append( "nil" );
+ keywords.append( "nodefault" );
+ keywords.append( "not" );
+ keywords.append( "object" );
+ keywords.append( "of" );
+ keywords.append( "or" );
+ keywords.append( "out" );
+ keywords.append( "overload" );
+ keywords.append( "override" );
+ keywords.append( "package" );
+ keywords.append( "packed" );
+ keywords.append( "pascal" );
+ keywords.append( "platform" );
+ keywords.append( "private" );
+ keywords.append( "procedure" );
+ keywords.append( "program" );
+ keywords.append( "property" );
+ keywords.append( "protected" );
+ keywords.append( "public" );
+ keywords.append( "published" );
+ keywords.append( "raise" );
+ keywords.append( "read" );
+ keywords.append( "readonly" );
+ keywords.append( "record" );
+ keywords.append( "register" );
+ keywords.append( "reintroduce" );
+ keywords.append( "repeat" );
+ keywords.append( "requires" );
+ keywords.append( "resident" );
+ keywords.append( "resourcestring" );
+ keywords.append( "safecall" );
+ keywords.append( "sealed" );
+ keywords.append( "set" );
+ keywords.append( "shl" );
+ keywords.append( "shr" );
+ keywords.append( "static" );
+ keywords.append( "stdcall" );
+ keywords.append( "stored" );
+ keywords.append( "string" );
+ keywords.append( "then" );
+ keywords.append( "threadvar" );
+ keywords.append( "to" );
+ keywords.append( "try" );
+ keywords.append( "type" );
+ keywords.append( "unit" );
+ keywords.append( "unsafe" );
+ keywords.append( "until" );
+ keywords.append( "uses" );
+ keywords.append( "var" );
+ keywords.append( "varargs" );
+ keywords.append( "virtual" );
+ keywords.append( "while" );
+ keywords.append( "with" );
+ keywords.append( "write" );
+ keywords.append( "writeonly" );
+ keywords.append( "xor" );
+ }
+
+ return keywords;
+}
+
+#include "pascalwriter.moc"
diff --git a/umbrello/umbrello/codegenerators/pascalwriter.h b/umbrello/umbrello/codegenerators/pascalwriter.h
new file mode 100644
index 00000000..bc34d762
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/pascalwriter.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * *
+ * 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) 2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef PASCALWRITER_H
+#define PASCALWRITER_H
+
+#include "simplecodegenerator.h"
+
+class UMLAssociation;
+class UMLOperation;
+
+/**
+ * Pascal class writer
+ * @author Oliver Kellogg
+ * Bugs and comments to uml-devel@lists.sf.net or http://bugs.kde.org
+ */
+class PascalWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ /**
+ * Basic Constructor
+ */
+ PascalWriter ();
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~PascalWriter ();
+
+ /**
+ * call this method to generate Ada code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass (UMLClassifier *c);
+
+ /**
+ * returns "Pascal"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ QStringList defaultDatatypes();
+
+ /**
+ * Check whether the given string is a reserved word for the
+ * language of this code generator
+ *
+ * @param rPossiblyReservedKeyword The string to check.
+ */
+ virtual bool isReservedKeyword(const QString & rPossiblyReservedKeyword);
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * write one operation
+ * @param op the class for which we are generating code
+ * @param ada the stream associated with the output file
+ */
+ void writeOperation (UMLOperation *op, QTextStream &ada, bool is_comment = false);
+
+ void computeAssocTypeAndRole (UMLAssociation *a, QString& typeName, QString& roleName);
+
+ bool isOOClass (UMLClassifier *c);
+
+ QString qualifiedName
+ (UMLPackage *p, bool withType = false, bool byValue = false);
+
+ static const QString defaultPackageSuffix;
+
+};
+
+#endif // PASCALWRITER_H
+
diff --git a/umbrello/umbrello/codegenerators/perlwriter.cpp b/umbrello/umbrello/codegenerators/perlwriter.cpp
new file mode 100644
index 00000000..7c8360fa
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/perlwriter.cpp
@@ -0,0 +1,716 @@
+/***************************************************************************
+ begin : Wed Jan 22 2003
+ copyright : (C) 2003 by David Hugh-Jones
+ (C) 2004-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ email : hughjonesd@yahoo.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "perlwriter.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../umldoc.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../uml.h"
+
+#include <kdebug.h>
+#include <qregexp.h>
+#include <qstring.h>
+#include <qdir.h>
+#include <qdatetime.h>
+#include <qtextstream.h>
+
+PerlWriter::PerlWriter()
+{
+}
+
+PerlWriter::~PerlWriter() {}
+
+bool PerlWriter::GetUseStatements(UMLClassifier *c, QString &Ret,
+ QString &ThisPkgName){
+
+ if(!c){
+ return(false);
+ }
+
+ UMLPackageList includes;
+ findObjectsRelated(c,includes);
+ UMLPackage *conc;
+ QString AV = "@";
+ QString SV = "$";
+ QString HV = "%";
+ for(conc = includes.first(); conc ;conc = includes.next()) {
+ if (conc->getBaseType() == Uml::ot_Datatype)
+ continue;
+ QString neatName = cleanName(conc->getName());
+ if (neatName != AV && neatName != SV && neatName != HV) {
+ QString OtherPkgName = conc->getPackage(".");
+ OtherPkgName.replace(QRegExp("\\."),"::");
+ QString OtherName = OtherPkgName + "::" + cleanName(conc->getName());
+
+ // Only print out the use statement if the other package isn't the
+ // same as the one we are working on. (This happens for the
+ // "Singleton" design pattern.)
+ if(OtherName != ThisPkgName){
+ Ret += "use ";
+ Ret += OtherName;
+ Ret += ';';
+ Ret += m_endl;
+ }
+ }
+ }
+ UMLClassifierList superclasses = c->getSuperClasses();
+ if (superclasses.count()) {
+ Ret += m_endl;
+ Ret += "use base qw( ";
+ for (UMLClassifier *obj = superclasses.first();
+ obj; obj = superclasses.next()) {
+ QString packageName = obj->getPackage(".");
+ packageName.replace(QRegExp("\\."),"::");
+
+ Ret += packageName + "::" + cleanName(obj->getName()) + ' ';
+ }
+ Ret += ");" + m_endl;
+ }
+
+ return(true);
+}
+
+void PerlWriter::writeClass(UMLClassifier *c) {
+
+ /* if(!c) {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+ */
+ QString classname = cleanName(c->getName());// this is fine: cleanName is "::-clean"
+ QString packageName = c->getPackage(".");
+ QString fileName;
+
+ // Replace all white spaces with blanks
+ packageName.simplifyWhiteSpace();
+
+ // Replace all blanks with underscore
+ packageName.replace(QRegExp(" "), "_");
+
+ // Replace all dots (".") with double colon scope resolution operators
+ // ("::")
+ packageName.replace(QRegExp("\\."),"::");
+
+ // Store complete package name
+ QString ThisPkgName = packageName + "::" + classname;
+
+ fileName = findFileName(c, ".pm");
+ // the above lower-cases my nice class names. That is bad.
+ // correct solution: refactor,
+ // split massive findFileName up, reimplement
+ // parts here
+ // actual solution: shameful ".pm" hack in codegenerator
+
+ CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();
+ QString curDir = pol->getOutputDirectory().absPath();
+ if (fileName.contains("::")) {
+ // create new directories for each level
+ QString newDir;
+ newDir = curDir;
+ QString fragment = fileName;
+ QDir* existing = new QDir (curDir);
+ QRegExp regEx("(.*)(::)");
+ regEx.setMinimal(true);
+ while (regEx.search(fragment) > -1) {
+ newDir = regEx.cap(1);
+ fragment.remove(0, (regEx.pos(2) + 2)); // get round strange minimal matching bug
+ existing->setPath(curDir + '/' + newDir);
+ if (! existing->exists()) {
+ existing->setPath(curDir);
+ if (! existing->mkdir(newDir)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ }
+ curDir += '/' + newDir;
+ }
+ fileName = fragment + ".pm";
+ }
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QString oldDir = pol->getOutputDirectory().absPath();
+ pol->setOutputDirectory(curDir);
+ QFile fileperl;
+ if(!openFile(fileperl, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream perl(&fileperl);
+ pol->setOutputDirectory(oldDir);
+
+ //======================================================================
+ // Start generating the code!!
+ //======================================================================
+
+ // try to find a heading file (license, comments, etc)
+ QString str;
+ bool bPackageDeclared = false;
+ bool bUseStmsWritten = false;
+
+ str = getHeadingFile(".pm"); // what this mean?
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),fileperl.name());
+ str.replace(QRegExp("%year%"),QDate::currentDate().toString("yyyy"));
+ str.replace(QRegExp("%date%"),QDate::currentDate().toString());
+ str.replace(QRegExp("%time%"),QTime::currentTime().toString());
+ str.replace(QRegExp("%package-name%"),ThisPkgName);
+ if(str.find(QRegExp("%PACKAGE-DECLARE%"))){
+ str.replace(QRegExp("%PACKAGE-DECLARE%"),
+ "package " + ThisPkgName + ';'
+ + m_endl + m_endl
+ + "#UML_MODELER_BEGIN_PERSONAL_VARS_" + classname
+ + m_endl + m_endl
+ + "#UML_MODELER_END_PERSONAL_VARS_" + classname
+ + m_endl
+ );
+ bPackageDeclared = true;
+ }
+
+ if(str.find(QRegExp("%USE-STATEMENTS%"))){
+ QString UseStms;
+ if(GetUseStatements(c,UseStms,ThisPkgName)){
+ str.replace(QRegExp("%USE-STATEMENTS%"), UseStms);
+ bUseStmsWritten = true;
+ }
+ }
+
+ perl<<str<<m_endl;
+ }
+
+ // if the package wasn't declared above during keyword substitution,
+ // add it now. (At the end of the file.)
+ if(! bPackageDeclared){
+ perl << m_endl << m_endl << "package " <<ThisPkgName << ";" << m_endl
+ << m_endl;
+ //write includes
+ perl << m_endl << "#UML_MODELER_BEGIN_PERSONAL_VARS_" << classname
+ << m_endl ;
+ perl << m_endl << "#UML_MODELER_END_PERSONAL_VARS_" << classname
+ << m_endl << m_endl ;
+ }
+
+ if(! bUseStmsWritten){
+ QString UseStms;
+ if(GetUseStatements(c,UseStms,ThisPkgName)){
+ perl<<UseStms<<m_endl;
+ }
+ }
+
+ perl << m_endl;
+
+ // Do we really need these for anything???
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ //Write class Documentation
+ if(forceDoc() || !c->getDoc().isEmpty()) {
+ perl << m_endl << "=head1";
+ perl << " " << classname.upper() << m_endl << m_endl;
+ perl << c->getDoc();
+ perl << m_endl << m_endl << "=cut" << m_endl << m_endl;
+ }
+
+ //check if class is abstract and / or has abstract methods
+ if(c->getAbstract())
+ perl << "=head1 ABSTRACT CLASS" << m_endl << m_endl << "=cut" << m_endl;
+
+ //attributes
+ if (! c->isInterface())
+ writeAttributes(c, perl); // keep for documentation's sake
+
+ //operations
+ writeOperations(c,perl);
+
+ perl << m_endl;
+
+ //finish file
+ //perl << m_endl << m_endl << "=cut" << m_endl;
+ perl << m_endl << m_endl << "return 1;" << m_endl;
+
+ //close files and notify we are done
+ fileperl.close();
+ emit codeGenerated(c, true);
+}
+
+/**
+ * returns "Perl"
+ */
+Uml::Programming_Language PerlWriter::getLanguage() {
+ return Uml::pl_Perl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+void PerlWriter::writeOperations(UMLClassifier *c, QTextStream &perl) {
+
+ //Lists to store operations sorted by scope
+ UMLOperationList oppub,opprot,oppriv;
+
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ //keep this for documentation only!
+ UMLOperationList opl(c->getOpList());
+ for(UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ QString classname(cleanName(c->getName()));
+
+ //write operations to file
+ if(forceSections() || !oppub.isEmpty()) {
+ perl << m_endl << "=head1 PUBLIC METHODS" << m_endl << m_endl ;
+ writeOperations(classname,oppub,perl);
+ perl << m_endl << m_endl << "=cut" << m_endl << m_endl;
+ }
+
+ if(forceSections() || !opprot.isEmpty()) {
+ perl << m_endl << "=head1 METHODS FOR SUBCLASSING" << m_endl << m_endl ;
+ //perl << "=pod " << m_endl << m_endl << "=head3 " ;
+ writeOperations(classname,opprot,perl);
+ perl << m_endl << m_endl << "=cut" << m_endl << m_endl;
+ }
+
+ if(forceSections() || !oppriv.isEmpty()) {
+ perl << m_endl << "=head1 PRIVATE METHODS" << m_endl << m_endl ;
+ //perl << "=pod " << m_endl << m_endl << "=head3 " ;
+ writeOperations(classname,oppriv,perl);
+ perl << m_endl << m_endl << "=cut" << m_endl << m_endl;
+ }
+
+ // moved here for perl
+ if (!c->isInterface() && hasDefaultValueAttr(c)) {
+ UMLAttributeList atl = c->getAttributeList();
+
+ perl << m_endl;
+ perl << m_endl << "=head2 _init" << m_endl << m_endl << m_endl;
+ perl << "_init sets all " + classname + " attributes to their default values unless already set" << m_endl << m_endl << "=cut" << m_endl << m_endl;
+ perl << "sub _init {" << m_endl << m_indentation << "my $self = shift;" << m_endl<<m_endl;
+
+ for(UMLAttribute *at = atl.first(); at ; at = atl.next()) {
+ if(!at->getInitialValue().isEmpty())
+ perl << m_indentation << "defined $self->{" << cleanName(at->getName())<<"}"
+ << " or $self->{" << cleanName(at->getName()) << "} = "
+ << at->getInitialValue() << ";" << m_endl;
+ }
+
+ perl << " }" << m_endl;
+ }
+
+ perl << m_endl << m_endl;
+}
+
+void PerlWriter::writeOperations(const QString &/* classname */, UMLOperationList &opList, QTextStream &perl) {
+ UMLOperation *op;
+ UMLAttribute *at;
+
+ for(op=opList.first(); op ; op=opList.next())
+ {
+ UMLAttributeList atl = op->getParmList();
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+ for (at = atl.first(); at ; at = atl.next())
+ writeDoc |= !at->getDoc().isEmpty();
+
+ if( writeDoc ) //write method documentation
+ {
+ perl << "=pod " << m_endl << m_endl << "=head3 " ;
+ perl << cleanName(op->getName()) << m_endl << m_endl;
+
+ perl << " Parameters :" << m_endl ;
+ //write parameter documentation
+ for (at = atl.first(); at ; at = atl.next()) {
+ if(forceDoc() || !at->getDoc().isEmpty()) {
+ perl << " "
+ << cleanName(at->getName()) << " : "
+ << at->getTypeName() << " : "
+ << at->getDoc()
+ << m_endl;
+ }
+ }//end for : write parameter documentation
+
+ perl << m_endl;
+ perl << " Return : " << m_endl;
+ perl << " " << op->getTypeName();
+ perl << m_endl << m_endl;
+ perl << " Description : " << m_endl;
+ perl << " " << op->getDoc();
+ perl << m_endl << m_endl << "=cut" << m_endl << m_endl;
+ }//end if : write method documentation
+
+ perl << "sub " << cleanName(op->getName()) << m_endl << "{" << m_endl;
+ perl << " my($self";
+
+ bool bStartPrinted = false;
+ //write parameters
+ for (at = atl.first(); at; at = atl.next()) {
+ if (!bStartPrinted) {
+ bStartPrinted = true;
+ perl << "," << m_endl;
+ }
+ perl << " $"<< cleanName(at->getName()) << ", # "
+ << at->getTypeName() << " : " << at->getDoc() << m_endl;
+ }
+
+ perl << " ) = @_;" << m_endl;
+
+ perl << "#UML_MODELER_BEGIN_PERSONAL_CODE_" << cleanName(op->getName());
+ perl << m_endl << "#UML_MODELER_END_PERSONAL_CODE_" << cleanName(op->getName()) << m_endl;
+ perl << "}" << m_endl;
+ perl << m_endl << m_endl;
+ }//end for
+}
+
+
+void PerlWriter::writeAttributes(UMLClassifier *c, QTextStream &perl) {
+ UMLAttributeList atpub, atprot, atpriv, atdefval;
+ atpub.setAutoDelete(false);
+ atprot.setAutoDelete(false);
+ atpriv.setAutoDelete(false);
+ atdefval.setAutoDelete(false);
+
+ //sort attributes by scope and see if they have a default value
+ UMLAttributeList atl = c->getAttributeList();
+ UMLAttribute *at;
+ for(at = atl.first(); at ; at = atl.next()) {
+ if(!at->getInitialValue().isEmpty())
+ atdefval.append(at);
+ switch(at->getVisibility()) {
+ case Uml::Visibility::Public:
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ atpriv.append(at);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ if(forceSections() || atpub.count()) {
+ writeAttributes(atpub,perl);
+ }
+ /* not needed as writeAttributes only writes documentation
+ if(forceSections() || atprot.count()) {
+ writeAttributes(atprot,perl);
+ }
+
+ if(forceSections() || atpriv.count()) {
+ writeAttributes(atpriv,perl);
+ }
+ */
+}
+
+
+void PerlWriter::writeAttributes(UMLAttributeList &atList, QTextStream &perl)
+{
+ perl << m_endl << "=head1 PUBLIC ATTRIBUTES" << m_endl << m_endl;
+ perl << "=pod " << m_endl << m_endl ;
+ for (UMLAttribute *at = atList.first(); at ; at = atList.next())
+ {
+ if (forceDoc() || !at->getDoc().isEmpty())
+ {
+ perl << "=head3 " << cleanName(at->getName()) << m_endl << m_endl ;
+ perl << " Description : " << at->getDoc() << m_endl << m_endl;
+ }
+ } // end for
+ perl << m_endl << m_endl << "=cut" << m_endl << m_endl;
+ return;
+}
+
+QStringList PerlWriter::defaultDatatypes() {
+ QStringList l;
+ l.append("$");
+ l.append("@");
+ l.append("%");
+ return l;
+}
+
+const QStringList PerlWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "abs"
+ << "accept"
+ << "alarm"
+ << "and"
+ << "atan2"
+ << "BEGIN"
+ << "bind"
+ << "binmode"
+ << "bless"
+ << "byte"
+ << "caller"
+ << "carp"
+ << "chdir"
+ << "chmod"
+ << "chomp"
+ << "chop"
+ << "chown"
+ << "chr"
+ << "chroot"
+ << "close"
+ << "closedir"
+ << "cmp"
+ << "confess"
+ << "connect"
+ << "continue"
+ << "cos"
+ << "croak"
+ << "crypt"
+ << "dbmclose"
+ << "dbmopen"
+ << "defined"
+ << "delete"
+ << "die"
+ << "do"
+ << "dump"
+ << "each"
+ << "else"
+ << "elsif"
+ << "END"
+ << "endgrent"
+ << "endhostent"
+ << "endnetent"
+ << "endprotoent"
+ << "endpwent"
+ << "endservent"
+ << "eof"
+ << "eq"
+ << "eval"
+ << "exec"
+ << "exists"
+ << "exit"
+ << "exp"
+ << "fcntl"
+ << "fileno"
+ << "flock"
+ << "for"
+ << "foreach"
+ << "fork"
+ << "format"
+ << "formline"
+ << "ge"
+ << "getc"
+ << "getgrent"
+ << "getgrgid"
+ << "getgrnam"
+ << "gethostbyaddr"
+ << "gethostbyname"
+ << "gethostent"
+ << "getlogin"
+ << "getnetbyaddr"
+ << "getnetbyname"
+ << "getnetent"
+ << "getpeername"
+ << "getpgrp"
+ << "getppid"
+ << "getpriority"
+ << "getprotobyname"
+ << "getprotobynumber"
+ << "getprotoent"
+ << "getpwent"
+ << "getpwnam"
+ << "getpwuid"
+ << "getservbyname"
+ << "getservbyport"
+ << "getservent"
+ << "getsockname"
+ << "getsockopt"
+ << "glob"
+ << "gmtime"
+ << "goto"
+ << "grep"
+ << "gt"
+ << "hex"
+ << "if"
+ << "import"
+ << "index"
+ << "int"
+ << "integer"
+ << "ioctl"
+ << "join"
+ << "keys"
+ << "kill"
+ << "last"
+ << "lc"
+ << "lcfirst"
+ << "le"
+ << "length"
+ << "lib"
+ << "link"
+ << "listen"
+ << "local"
+ << "localtime"
+ << "lock"
+ << "log"
+ << "lstat"
+ << "lt"
+ << "map"
+ << "mkdir"
+ << "msgctl"
+ << "msgget"
+ << "msgrcv"
+ << "msgsnd"
+ << "my"
+ << "ne"
+ << "new"
+ << "next"
+ << "no"
+ << "not"
+ << "oct"
+ << "open"
+ << "opendir"
+ << "or"
+ << "ord"
+ << "our"
+ << "pack"
+ << "package"
+ << "pipe"
+ << "pop"
+ << "pos"
+ << "print"
+ << "printf"
+ << "prototype"
+ << "push"
+ << "quotemeta"
+ << "rand"
+ << "read"
+ << "readdir"
+ << "readline"
+ << "readlink"
+ << "readpipe"
+ << "recv"
+ << "redo"
+ << "ref"
+ << "rename"
+ << "require"
+ << "reset"
+ << "return"
+ << "reverse"
+ << "rewinddir"
+ << "rindex"
+ << "rmdir"
+ << "scalar"
+ << "seek"
+ << "seekdir"
+ << "select"
+ << "semctl"
+ << "semget"
+ << "semop"
+ << "send"
+ << "setgrent"
+ << "sethostent"
+ << "setnetent"
+ << "setpgrp"
+ << "setpriority"
+ << "setprotoent"
+ << "setpwent"
+ << "setservent"
+ << "setsockopt"
+ << "shift"
+ << "shmctl"
+ << "shmget"
+ << "shmread"
+ << "shmwrite"
+ << "shutdown"
+ << "sigtrap"
+ << "sin"
+ << "sleep"
+ << "socket"
+ << "socketpair"
+ << "sort"
+ << "splice"
+ << "split"
+ << "sprintf"
+ << "sqrt"
+ << "srand"
+ << "stat"
+ << "strict"
+ << "study"
+ << "sub"
+ << "subs"
+ << "substr"
+ << "switch"
+ << "symlink"
+ << "syscall"
+ << "sysopen"
+ << "sysread"
+ << "sysseek"
+ << "system"
+ << "syswrite"
+ << "tell"
+ << "telldir"
+ << "tie"
+ << "tied"
+ << "time"
+ << "times"
+ << "truncate"
+ << "uc"
+ << "ucfirst"
+ << "umask"
+ << "undef"
+ << "unless"
+ << "unlink"
+ << "unpack"
+ << "unshift"
+ << "untie"
+ << "until"
+ << "use"
+ << "utf8"
+ << "utime"
+ << "values"
+ << "vars"
+ << "vec"
+ << "wait"
+ << "waitpid"
+ << "wantarray"
+ << "warn"
+ << "warnings"
+ << "while"
+ << "write"
+ << "xor";
+ }
+
+ return keywords;
+}
+
+#include "perlwriter.moc"
diff --git a/umbrello/umbrello/codegenerators/perlwriter.h b/umbrello/umbrello/codegenerators/perlwriter.h
new file mode 100644
index 00000000..9dac4e56
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/perlwriter.h
@@ -0,0 +1,101 @@
+/***************************************************************************
+ perlwriter.h - description
+ -------------------
+ begin : Wed Jan 22 2003
+ copyright : (C) 2003 by David Hugh-Jones
+ email : hughjonesd@yahoo.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PERLWRITER_H
+#define PERLWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umlattributelist.h"
+#include "../umloperationlist.h"
+
+class UMLOperation;
+class UMLAttribute;
+class UMLClassifier;
+
+/**
+ * class PerlWriter is a Perl code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class PerlWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ PerlWriter();
+ virtual ~PerlWriter();
+
+ /**
+ * call this method to generate Perl code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "Perl"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+ QStringList defaultDatatypes();
+
+private:
+
+ /**
+ * we do not want to write the comment "Private methods" twice
+ * not sure whether this is php specific
+ */
+ bool bPrivateSectionCommentIsWritten;
+
+ /**
+ * write all operations for a given class
+ *
+ * @param c the concept we are generating code for
+ * @param perl output stream for the Perl file
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &perl);
+
+ /**
+ * write a list of class operations
+ *
+ * @param classname the name of the class
+ * @param opList the list of operations
+ * @param perl output stream for the Perl file
+ */
+ void writeOperations(const QString &classname, UMLOperationList &opList,
+ QTextStream &perl);
+
+ /** write all the attributes of a class
+ * @param c the class we are generating code for
+ * @param perl output stream for the Perl file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &perl);
+
+ /** write a list of class attributes
+ * @param atList the list of attributes
+ * @param perl output stream for the Perl file
+ */
+ void writeAttributes(UMLAttributeList &atList, QTextStream &perl);
+
+ bool GetUseStatements(UMLClassifier *c, QString &Ret,
+ QString &ThisPkgName);
+
+};
+
+#endif //PERLWRITER
diff --git a/umbrello/umbrello/codegenerators/php5writer.cpp b/umbrello/umbrello/codegenerators/php5writer.cpp
new file mode 100644
index 00000000..044d3afe
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/php5writer.cpp
@@ -0,0 +1,3418 @@
+/***************************************************************************
+ begin : Thu Oct 17 2002
+ copyright : (C) 2002 by Heiko Nardmann
+ email : h.nardmann@secunet.de
+ (C) 2003-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ php5 version by Thorsten Kunz (tk AT bytecrash DOT net)
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "php5writer.h"
+
+#include <kdebug.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+
+static const char *php5words[] =
+ {
+ "abs",
+ "abstract",
+ "acos",
+ "acosh",
+ "add",
+ "addAction",
+ "addColor",
+ "addEntry",
+ "addFill",
+ "addShape",
+ "addString",
+ "add_namespace",
+ "addcslashes",
+ "addslashes",
+ "addstring",
+ "aggregate",
+ "aggregate_info",
+ "aggregate_methods",
+ "aggregate_methods_by_list",
+ "aggregate_methods_by_regexp",
+ "aggregate_properties",
+ "aggregate_properties_by_list",
+ "aggregate_properties_by_regexp",
+ "aggregation_info",
+ "align",
+ "apache_child_terminate",
+ "apache_lookup_uri",
+ "apache_note",
+ "apache_request_headers",
+ "apache_response_headers",
+ "apache_setenv",
+ "append_child",
+ "append_sibling",
+ "array",
+ "array_change_key_case",
+ "array_chunk",
+ "array_count_values",
+ "array_diff",
+ "array_diff_assoc",
+ "array_fill",
+ "array_filter",
+ "array_flip",
+ "array_intersect",
+ "array_intersect_assoc",
+ "array_key_exists",
+ "array_keys",
+ "array_map",
+ "array_merge",
+ "array_merge_recursive",
+ "array_multisort",
+ "array_pad",
+ "array_pop",
+ "array_push",
+ "array_rand",
+ "array_reduce",
+ "array_reverse",
+ "array_search",
+ "array_shift",
+ "array_slice",
+ "array_splice",
+ "array_sum",
+ "array_unique",
+ "array_unshift",
+ "array_values",
+ "array_walk",
+ "arsort",
+ "ascii2ebcdic",
+ "asin",
+ "asinh",
+ "asort",
+ "aspell_check",
+ "aspell_new",
+ "aspell_suggest",
+ "assert",
+ "assert_options",
+ "assign",
+ "atan",
+ "atan2",
+ "atanh",
+ "attreditable",
+ "attributes",
+ "base64_decode",
+ "base64_encode",
+ "base_convert",
+ "basename",
+ "bcadd",
+ "bccomp",
+ "bcdiv",
+ "bcmod",
+ "bcmul",
+ "bcpow",
+ "bcpowmod",
+ "bcscale",
+ "bcsqrt",
+ "bcsub",
+ "bin2hex",
+ "bindec",
+ "bindtextdomain",
+ "bind_textdomain_codeset",
+ "bool",
+ "break",
+ "bzclose",
+ "bzcompress",
+ "bzdecompress",
+ "bzerrno",
+ "bzerror",
+ "bzerrstr",
+ "bzflush",
+ "bzopen",
+ "bzread",
+ "bzwrite",
+ "cal_days_in_month",
+ "cal_from_jd",
+ "cal_info",
+ "call_user_func",
+ "call_user_func_array",
+ "call_user_method",
+ "call_user_method_array",
+ "cal_to_jd",
+ "ccvs_add",
+ "ccvs_auth",
+ "ccvs_command",
+ "ccvs_count",
+ "ccvs_delete",
+ "ccvs_done",
+ "ccvs_init",
+ "ccvs_lookup",
+ "ccvs_new",
+ "ccvs_report",
+ "ccvs_return",
+ "ccvs_reverse",
+ "ccvs_sale",
+ "ccvs_status",
+ "ccvs_textvalue",
+ "ccvs_void",
+ "ceil",
+ "chdir",
+ "checkdate",
+ "checkdnsrr",
+ "checkin",
+ "checkout",
+ "chgrp",
+ "child_nodes",
+ "children",
+ "chmod",
+ "chop",
+ "chown",
+ "chr",
+ "chroot",
+ "chunk_split",
+ "class",
+ "class_exists",
+ "clearstatcache",
+ "clone_node",
+ "closedir",
+ "closelog",
+ "com_addref",
+ "com_get",
+ "com_invoke",
+ "com_isenum",
+ "com_load",
+ "com_load_typelib",
+ "compact",
+ "com_propget",
+ "com_propput",
+ "com_propset",
+ "com_release",
+ "com_set",
+ "connection_aborted",
+ "connection_status",
+ "connection_timeout",
+ "constant",
+ "content",
+ "continue",
+ "convert_cyr_string",
+ "_COOKIE",
+ "copy",
+ "cos",
+ "cosh",
+ "count",
+ "count_chars",
+ "cpdf_add_annotation",
+ "cpdf_add_outline",
+ "cpdf_arc",
+ "cpdf_begin_text",
+ "cpdf_circle",
+ "cpdf_clip",
+ "cpdf_close",
+ "cpdf_closepath",
+ "cpdf_closepath_fill_stroke",
+ "cpdf_closepath_stroke",
+ "cpdf_continue_text",
+ "cpdf_curveto",
+ "cpdf_end_text",
+ "cpdf_fill",
+ "cpdf_fill_stroke",
+ "cpdf_finalize",
+ "cpdf_finalize_page",
+ "cpdf_global_set_document_limits",
+ "cpdf_import_jpeg",
+ "cpdf_lineto",
+ "cpdf_moveto",
+ "cpdf_newpath",
+ "cpdf_open",
+ "cpdf_output_buffer",
+ "cpdf_page_init",
+ "cpdf_place_inline_image",
+ "cpdf_rect",
+ "cpdf_restore",
+ "cpdf_rlineto",
+ "cpdf_rmoveto",
+ "cpdf_rotate",
+ "cpdf_rotate_text",
+ "cpdf_save",
+ "cpdf_save_to_file",
+ "cpdf_scale",
+ "cpdf_set_action_url",
+ "cpdf_set_char_spacing",
+ "cpdf_set_creator",
+ "cpdf_set_current_page",
+ "cpdf_setdash",
+ "cpdf_setflat",
+ "cpdf_set_font",
+ "cpdf_set_font_directories",
+ "cpdf_set_font_map_file",
+ "cpdf_setgray",
+ "cpdf_setgray_fill",
+ "cpdf_setgray_stroke",
+ "cpdf_set_horiz_scaling",
+ "cpdf_set_keywords",
+ "cpdf_set_leading",
+ "cpdf_setlinecap",
+ "cpdf_setlinejoin",
+ "cpdf_setlinewidth",
+ "cpdf_setmiterlimit",
+ "cpdf_set_page_animation",
+ "cpdf_setrgbcolor",
+ "cpdf_setrgbcolor_fill",
+ "cpdf_setrgbcolor_stroke",
+ "cpdf_set_subject",
+ "cpdf_set_text_matrix",
+ "cpdf_set_text_pos",
+ "cpdf_set_text_rendering",
+ "cpdf_set_text_rise",
+ "cpdf_set_title",
+ "cpdf_set_viewer_preferences",
+ "cpdf_set_word_spacing",
+ "cpdf_show",
+ "cpdf_show_xy",
+ "cpdf_stringwidth",
+ "cpdf_stroke",
+ "cpdf_text",
+ "cpdf_translate",
+ "crack_check",
+ "crack_closedict",
+ "crack_getlastmessage",
+ "crack_opendict",
+ "crc32",
+ "create_attribute",
+ "create_cdata_section",
+ "create_comment",
+ "create_element",
+ "create_element_ns",
+ "create_entity_reference",
+ "create_function",
+ "create_processing_instruction",
+ "create_text_node",
+ "crypt",
+ "ctype_alnum",
+ "ctype_alpha",
+ "ctype_cntrl",
+ "ctype_digit",
+ "ctype_graph",
+ "ctype_lower",
+ "ctype_print",
+ "ctype_punct",
+ "ctype_space",
+ "ctype_upper",
+ "ctype_xdigit",
+ "curl_close",
+ "curl_errno",
+ "curl_error",
+ "curl_exec",
+ "curl_getinfo",
+ "curl_init",
+ "curl_setopt",
+ "curl_version",
+ "current",
+ "cybercash_base64_decode",
+ "cybercash_base64_encode",
+ "cybercash_decr",
+ "cybercash_encr",
+ "cybermut_creerformulairecm",
+ "cybermut_creerreponsecm",
+ "cybermut_testmac",
+ "cyrus_authenticate",
+ "cyrus_bind",
+ "cyrus_close",
+ "cyrus_connect",
+ "cyrus_query",
+ "cyrus_unbind",
+ "data",
+ "date",
+ "dba_close",
+ "dba_delete",
+ "dba_exists",
+ "dba_fetch",
+ "dba_firstkey",
+ "dba_handlers",
+ "dba_insert",
+ "dba_list",
+ "dba_nextkey",
+ "dba_open",
+ "dba_optimize",
+ "dba_popen",
+ "dba_replace",
+ "dbase_add_record",
+ "dbase_close",
+ "dbase_create",
+ "dbase_delete_record",
+ "dbase_get_record",
+ "dbase_get_record_with_names",
+ "dbase_numfields",
+ "dbase_numrecords",
+ "dbase_open",
+ "dbase_pack",
+ "dbase_replace_record",
+ "dba_sync",
+ "dblist",
+ "dbmclose",
+ "dbmdelete",
+ "dbmexists",
+ "dbmfetch",
+ "dbmfirstkey",
+ "dbminsert",
+ "dbmnextkey",
+ "dbmopen",
+ "dbmreplace",
+ "dbplus_add",
+ "dbplus_aql",
+ "dbplus_chdir",
+ "dbplus_close",
+ "dbplus_curr",
+ "dbplus_errcode",
+ "dbplus_errno",
+ "dbplus_find",
+ "dbplus_first",
+ "dbplus_flush",
+ "dbplus_freealllocks",
+ "dbplus_freelock",
+ "dbplus_freerlocks",
+ "dbplus_getlock",
+ "dbplus_getunique",
+ "dbplus_info",
+ "dbplus_last",
+ "dbplus_lockrel",
+ "dbplus_next",
+ "dbplus_open",
+ "dbplus_prev",
+ "dbplus_rchperm",
+ "dbplus_rcreate",
+ "dbplus_rcrtexact",
+ "dbplus_rcrtlike",
+ "dbplus_resolve",
+ "dbplus_restorepos",
+ "dbplus_rkeys",
+ "dbplus_ropen",
+ "dbplus_rquery",
+ "dbplus_rrename",
+ "dbplus_rsecindex",
+ "dbplus_runlink",
+ "dbplus_rzap",
+ "dbplus_savepos",
+ "dbplus_setindex",
+ "dbplus_setindexbynumber",
+ "dbplus_sql",
+ "dbplus_tcl",
+ "dbplus_tremove",
+ "dbplus_undo",
+ "dbplus_undoprepare",
+ "dbplus_unlockrel",
+ "dbplus_unselect",
+ "dbplus_update",
+ "dbplus_xlockrel",
+ "dbplus_xunlockrel",
+ "dbstat",
+ "dbx_close",
+ "dbx_compare",
+ "dbx_connect",
+ "dbx_error",
+ "dbx_escape_string",
+ "dbx_query",
+ "dbx_sort",
+ "dcgettext",
+ "dcngettext",
+ "dcstat",
+ "deaggregate",
+ "debug_backtrace",
+ "debugger_off",
+ "debugger_on",
+ "decbin",
+ "dechex",
+ "declare",
+ "decoct",
+ "DEFAULT_INCLUDE_PATH",
+ "define",
+ "defined",
+ "define_syslog_variables",
+ "deg2rad",
+ "delete",
+ "description",
+ "dgettext",
+ "die",
+ "dio_close",
+ "dio_fcntl",
+ "dio_open",
+ "dio_read",
+ "dio_seek",
+ "dio_stat",
+ "dio_tcsetattr",
+ "dio_truncate",
+ "dio_write",
+ "dir",
+ "dirname",
+ "disk_free_space",
+ "diskfreespace",
+ "disk_total_space",
+ "dl",
+ "dngettext",
+ "dns_check_record",
+ "dns_get_mx",
+ "dns_get_record",
+ "do",
+ "doctype",
+ "document_element",
+ "DOCUMENT_ROOT",
+ "domxml_new_doc",
+ "domxml_open_file",
+ "domxml_open_mem",
+ "domxml_version",
+ "domxml_xmltree",
+ "domxml_xslt_stylesheet",
+ "domxml_xslt_stylesheet_doc",
+ "domxml_xslt_stylesheet_file",
+ "dotnet_load",
+ "doubleval",
+ "drawCurve",
+ "drawCurveTo",
+ "drawLine",
+ "drawLineTo",
+ "dstanchors",
+ "dstofsrcanchors",
+ "dump_file",
+ "dump_mem",
+ "dump_node",
+ "each",
+ "E_ALL",
+ "easter_date",
+ "easter_days",
+ "ebcdic2ascii",
+ "echo",
+ "E_COMPILE_ERROR",
+ "E_COMPILE_WARNING",
+ "E_CORE_ERROR",
+ "E_CORE_WARNING",
+ "E_ERROR",
+ "else",
+ "elseif",
+ "empty",
+ "end",
+ "endfor",
+ "endforeach",
+ "endif",
+ "endswitch",
+ "endwhile",
+ "E_NOTICE",
+ "entities",
+ "_ENV",
+ "E_PARSE",
+ "ereg",
+ "eregi",
+ "eregi_replace",
+ "ereg_replace",
+ "error_log",
+ "error_reporting",
+ "escapeshellarg",
+ "escapeshellcmd",
+ "E_USER_ERROR",
+ "E_USER_NOTICE",
+ "E_USER_WARNING",
+ "eval",
+ "E_WARNING",
+ "exec",
+ "exif_imagetype",
+ "exif_read_data",
+ "exif_thumbnail",
+ "exit",
+ "exp",
+ "explode",
+ "expm1",
+ "extension_loaded",
+ "extract",
+ "ezmlm_hash",
+ "FALSE",
+ "fbsql_affected_rows",
+ "fbsql_autocommit",
+ "fbsql_change_user",
+ "fbsql_close",
+ "fbsql_commit",
+ "fbsql_connect",
+ "fbsql_create_blob",
+ "fbsql_create_clob",
+ "fbsql_create_db",
+ "fbsql_database",
+ "fbsql_database_password",
+ "fbsql_data_seek",
+ "fbsql_db_query",
+ "fbsql_db_status",
+ "fbsql_drop_db",
+ "fbsql_errno",
+ "fbsql_error",
+ "fbsql_fetch_array",
+ "fbsql_fetch_assoc",
+ "fbsql_fetch_field",
+ "fbsql_fetch_lengths",
+ "fbsql_fetch_object",
+ "fbsql_fetch_row",
+ "fbsql_field_flags",
+ "fbsql_field_len",
+ "fbsql_field_name",
+ "fbsql_field_seek",
+ "fbsql_field_table",
+ "fbsql_field_type",
+ "fbsql_free_result",
+ "fbsql_get_autostart_info",
+ "fbsql_hostname",
+ "fbsql_insert_id",
+ "fbsql_list_dbs",
+ "fbsql_list_fields",
+ "fbsql_list_tables",
+ "fbsql_next_result",
+ "fbsql_num_fields",
+ "fbsql_num_rows",
+ "fbsql_password",
+ "fbsql_pconnect",
+ "fbsql_query",
+ "fbsql_read_blob",
+ "fbsql_read_clob",
+ "fbsql_result",
+ "fbsql_rollback",
+ "fbsql_select_db",
+ "fbsql_set_lob_mode",
+ "fbsql_set_transaction",
+ "fbsql_start_db",
+ "fbsql_stop_db",
+ "fbsql_tablename",
+ "fbsql_username",
+ "fbsql_warnings",
+ "fclose",
+ "fdf_add_doc_javascript",
+ "fdf_add_template",
+ "fdf_close",
+ "fdf_create",
+ "fdf_errno",
+ "fdf_error",
+ "fdf_get_ap",
+ "fdf_get_attachment",
+ "fdf_get_encoding",
+ "fdf_get_file",
+ "fdf_get_status",
+ "fdf_get_value",
+ "fdf_get_version",
+ "fdf_header",
+ "fdf_next_field_name",
+ "fdf_open",
+ "fdf_open_string",
+ "fdf_save",
+ "fdf_save_string",
+ "fdf_set_ap",
+ "fdf_set_encoding",
+ "fdf_set_file",
+ "fdf_set_flags",
+ "fdf_set_javascript_action",
+ "fdf_set_opt",
+ "fdf_set_status",
+ "fdf_set_submit_form_action",
+ "fdf_set_target_frame",
+ "fdf_set_value",
+ "fdf_set_version",
+ "feof",
+ "fflush",
+ "fgetc",
+ "fgetcsv",
+ "fgets",
+ "fgetss",
+ "file",
+ "__FILE__",
+ "fileatime",
+ "filectime",
+ "file_exists",
+ "file_get_contents",
+ "filegroup",
+ "fileinode",
+ "filemtime",
+ "fileowner",
+ "fileperms",
+ "filepro",
+ "filepro_fieldcount",
+ "filepro_fieldname",
+ "filepro_fieldtype",
+ "filepro_fieldwidth",
+ "filepro_retrieve",
+ "filepro_rowcount",
+ "_FILES",
+ "filesize",
+ "filetype",
+ "find",
+ "first_child",
+ "floatval",
+ "flock",
+ "floor",
+ "flush",
+ "fmod",
+ "fnmatch",
+ "fopen",
+ "for",
+ "foreach",
+ "fpassthru",
+ "fprintf",
+ "fputs",
+ "fread",
+ "frenchtojd",
+ "fribidi_log2vis",
+ "fscanf",
+ "fseek",
+ "fsockopen",
+ "fstat",
+ "ftell",
+ "ftok",
+ "ftp_cdup",
+ "ftp_chdir",
+ "ftp_close",
+ "ftp_connect",
+ "ftp_delete",
+ "ftp_exec",
+ "ftp_fget",
+ "ftp_fput",
+ "ftp_get",
+ "ftp_get_option",
+ "ftp_login",
+ "ftp_mdtm",
+ "ftp_mkdir",
+ "ftp_nb_continue",
+ "ftp_nb_fget",
+ "ftp_nb_fput",
+ "ftp_nb_get",
+ "ftp_nb_put",
+ "ftp_nlist",
+ "ftp_pasv",
+ "ftp_put",
+ "ftp_pwd",
+ "ftp_quit",
+ "ftp_rawlist",
+ "ftp_rename",
+ "ftp_rmdir",
+ "ftp_set_option",
+ "ftp_site",
+ "ftp_size",
+ "ftp_ssl_connect",
+ "ftp_systype",
+ "ftruncate",
+ "ftstat",
+ "func_get_arg",
+ "func_get_args",
+ "func_num_args",
+ "function",
+ "function_exists",
+ "fwrite",
+ "GATEWAY_INTERFACE",
+ "gd_info",
+ "_GET",
+ "getallheaders",
+ "get_attribute",
+ "get_attribute_node",
+ "get_browser",
+ "get_cfg_var",
+ "get_class",
+ "get_class_methods",
+ "get_class_vars",
+ "get_content",
+ "get_current_user",
+ "getcwd",
+ "getdate",
+ "get_declared_classes",
+ "get_defined_constants",
+ "get_defined_functions",
+ "get_defined_vars",
+ "get_element_by_id",
+ "get_elements_by_tagname",
+ "getenv",
+ "get_extension_funcs",
+ "getHeight",
+ "gethostbyaddr",
+ "gethostbyname",
+ "gethostbynamel",
+ "get_html_translation_table",
+ "getimagesize",
+ "get_included_files",
+ "get_include_path",
+ "getlastmod",
+ "get_loaded_extensions",
+ "get_magic_quotes_gpc",
+ "get_magic_quotes_runtime",
+ "get_meta_tags",
+ "getmxrr",
+ "getmygid",
+ "getmyinode",
+ "getmypid",
+ "getmyuid",
+ "get_object_vars",
+ "getopt",
+ "get_parent_class",
+ "getprotobyname",
+ "getprotobynumber",
+ "getrandmax",
+ "get_required_files",
+ "get_resource_type",
+ "getrusage",
+ "getservbyname",
+ "getservbyport",
+ "getshape1",
+ "getshape2",
+ "gettext",
+ "gettimeofday",
+ "gettype",
+ "getwidth",
+ "getWidth",
+ "glob",
+ "global",
+ "GLOBALS",
+ "gmdate",
+ "gmmktime",
+ "gmp_abs",
+ "gmp_add",
+ "gmp_and",
+ "gmp_clrbit",
+ "gmp_cmp",
+ "gmp_com",
+ "gmp_div",
+ "gmp_divexact",
+ "gmp_div_q",
+ "gmp_div_qr",
+ "gmp_div_r",
+ "gmp_fact",
+ "gmp_gcd",
+ "gmp_gcdext",
+ "gmp_hamdist",
+ "gmp_init",
+ "gmp_intval",
+ "gmp_invert",
+ "gmp_jacobi",
+ "gmp_legendre",
+ "gmp_mod",
+ "gmp_mul",
+ "gmp_neg",
+ "gmp_or",
+ "gmp_perfect_square",
+ "gmp_popcount",
+ "gmp_pow",
+ "gmp_powm",
+ "gmp_prob_prime",
+ "gmp_random",
+ "gmp_scan0",
+ "gmp_scan1",
+ "gmp_setbit",
+ "gmp_sign",
+ "gmp_sqrt",
+ "gmp_sqrtrm",
+ "gmp_strval",
+ "gmp_sub",
+ "gmp_xor",
+ "gmstrftime",
+ "gregoriantojd",
+ "gzclose",
+ "gzcompress",
+ "gzdeflate",
+ "gzencode",
+ "gzeof",
+ "gzfile",
+ "gzgetc",
+ "gzgets",
+ "gzgetss",
+ "gzinflate",
+ "gzopen",
+ "gzpassthru",
+ "gzputs",
+ "gzread",
+ "gzrewind",
+ "gzseek",
+ "gztell",
+ "gzuncompress",
+ "gzwrite",
+ "has_attribute",
+ "has_attributess",
+ "has_child_nodes",
+ "header",
+ "headers_sent",
+ "hebrev",
+ "hebrevc",
+ "hexdec",
+ "highlight_file",
+ "highlight_string",
+ "html_dump_mem",
+ "htmlentities",
+ "html_entity_decode",
+ "htmlspecialchars",
+ "HTTP_ACCEPT",
+ "HTTP_ACCEPT_CHARSET",
+ "HTTP_ACCEPT_LANGUAGE",
+ "HTTP_CONNECTION",
+ "HTTP_COOKIE_VARS",
+ "HTTP_ENCODING",
+ "HTTP_ENV_VARS",
+ "HTTP_GET_VARS",
+ "HTTP_HOST",
+ "HTTP_POST_FILES",
+ "HTTP_POST_VARS",
+ "HTTP_RAW_POST_DATA",
+ "HTTP_REFERER",
+ "HTTP_SERVER_VARS",
+ "HTTP_SESSION_VARS",
+ "HTTP_STATE_VARS",
+ "HTTP_USER_AGENT",
+ "hw_api_attribute",
+ "hw_api_content",
+ "hwapi_hgcsp",
+ "hw_api_object",
+ "hw_Array2Objrec",
+ "hw_changeobject",
+ "hw_Children",
+ "hw_ChildrenObj",
+ "hw_Close",
+ "hw_Connect",
+ "hw_connection_info",
+ "hw_Cp",
+ "hw_Deleteobject",
+ "hw_DocByAnchor",
+ "hw_DocByAnchorObj",
+ "hw_Document_Attributes",
+ "hw_Document_BodyTag",
+ "hw_Document_Content",
+ "hw_Document_SetContent",
+ "hw_Document_Size",
+ "hw_dummy",
+ "hw_EditText",
+ "hw_Error",
+ "hw_ErrorMsg",
+ "hw_Free_Document",
+ "hw_GetAnchors",
+ "hw_GetAnchorsObj",
+ "hw_GetAndLock",
+ "hw_GetChildColl",
+ "hw_GetChildCollObj",
+ "hw_GetChildDocColl",
+ "hw_GetChildDocCollObj",
+ "hw_GetObject",
+ "hw_GetObjectByQuery",
+ "hw_GetObjectByQueryColl",
+ "hw_GetObjectByQueryCollObj",
+ "hw_GetObjectByQueryObj",
+ "hw_GetParents",
+ "hw_GetParentsObj",
+ "hw_getrellink",
+ "hw_GetRemote",
+ "hw_GetRemoteChildren",
+ "hw_GetSrcByDestObj",
+ "hw_GetText",
+ "hw_getusername",
+ "hw_Identify",
+ "hw_InCollections",
+ "hw_Info",
+ "hw_InsColl",
+ "hw_InsDoc",
+ "hw_insertanchors",
+ "hw_InsertDocument",
+ "hw_InsertObject",
+ "hw_mapid",
+ "hw_Modifyobject",
+ "hw_Mv",
+ "hw_New_Document",
+ "hw_Objrec2Array",
+ "hw_Output_Document",
+ "hw_pConnect",
+ "hw_PipeDocument",
+ "hw_Root",
+ "hw_setlinkroot",
+ "hw_stat",
+ "hwstat",
+ "hw_Unlock",
+ "hw_Who",
+ "hypot",
+ "ibase_blob_add",
+ "ibase_blob_cancel",
+ "ibase_blob_close",
+ "ibase_blob_create",
+ "ibase_blob_echo",
+ "ibase_blob_get",
+ "ibase_blob_import",
+ "ibase_blob_info",
+ "ibase_blob_open",
+ "ibase_close",
+ "ibase_commit",
+ "ibase_connect",
+ "ibase_errmsg",
+ "ibase_execute",
+ "ibase_fetch_object",
+ "ibase_fetch_row",
+ "ibase_field_info",
+ "ibase_free_query",
+ "ibase_free_result",
+ "ibase_num_fields",
+ "ibase_pconnect",
+ "ibase_prepare",
+ "ibase_query",
+ "ibase_rollback",
+ "ibase_timefmt",
+ "ibase_trans",
+ "iconv",
+ "iconv_get_encoding",
+ "iconv_set_encoding",
+ "identify",
+ "if",
+ "ifx_affected_rows",
+ "ifx_blobinfile_mode",
+ "ifx_byteasvarchar",
+ "ifx_close",
+ "ifx_connect",
+ "ifx_copy_blob",
+ "ifx_create_blob",
+ "ifx_create_char",
+ "ifx_do",
+ "ifx_error",
+ "ifx_errormsg",
+ "ifx_fetch_row",
+ "ifx_fieldproperties",
+ "ifx_fieldtypes",
+ "ifx_free_blob",
+ "ifx_free_char",
+ "ifx_free_result",
+ "ifx_get_blob",
+ "ifx_get_char",
+ "ifx_getsqlca",
+ "ifx_htmltbl_result",
+ "ifx_nullformat",
+ "ifx_num_fields",
+ "ifx_num_rows",
+ "ifx_pconnect",
+ "ifx_prepare",
+ "ifx_query",
+ "ifx_textasvarchar",
+ "ifx_update_blob",
+ "ifx_update_char",
+ "ifxus_close_slob",
+ "ifxus_create_slob",
+ "ifxus_free_slob",
+ "ifxus_open_slob",
+ "ifxus_read_slob",
+ "ifxus_seek_slob",
+ "ifxus_tell_slob",
+ "ifxus_write_slob",
+ "ignore_user_abort",
+ "image2wbmp",
+ "imagealphablending",
+ "imagearc",
+ "imagechar",
+ "imagecharup",
+ "imagecolorallocate",
+ "imagecolorallocatealpha",
+ "imagecolorat",
+ "imagecolorclosest",
+ "imagecolorclosestalpha",
+ "imagecolorclosesthwb",
+ "imagecolordeallocate",
+ "imagecolorexact",
+ "imagecolorexactalpha",
+ "imagecolorresolve",
+ "imagecolorresolvealpha",
+ "imagecolorset",
+ "imagecolorsforindex",
+ "imagecolorstotal",
+ "imagecolortransparent",
+ "imagecopy",
+ "imagecopymerge",
+ "imagecopymergegray",
+ "imagecopyresampled",
+ "imagecopyresized",
+ "imagecreate",
+ "imagecreatefromgd",
+ "imagecreatefromgd2",
+ "imagecreatefromgd2part",
+ "imagecreatefromgif",
+ "imagecreatefromjpeg",
+ "imagecreatefrompng",
+ "imagecreatefromstring",
+ "imagecreatefromwbmp",
+ "imagecreatefromxbm",
+ "imagecreatefromxpm",
+ "imagecreatetruecolor",
+ "imagedashedline",
+ "imagedestroy",
+ "imageellipse",
+ "imagefill",
+ "imagefilledarc",
+ "imagefilledellipse",
+ "imagefilledpolygon",
+ "imagefilledrectangle",
+ "imagefilltoborder",
+ "imagefontheight",
+ "imagefontwidth",
+ "imageftbbox",
+ "imagefttext",
+ "imagegammacorrect",
+ "imagegd",
+ "imagegd2",
+ "imagegif",
+ "imageinterlace",
+ "imagejpeg",
+ "imageline",
+ "imageloadfont",
+ "imagepalettecopy",
+ "imagepng",
+ "imagepolygon",
+ "imagepsbbox",
+ "imagepscopyfont",
+ "imagepsencodefont",
+ "imagepsextendfont",
+ "imagepsfreefont",
+ "imagepsloadfont",
+ "imagepsslantfont",
+ "imagepstext",
+ "imagerectangle",
+ "imagerotate",
+ "imagesetbrush",
+ "imagesetpixel",
+ "imagesetstyle",
+ "imagesetthickness",
+ "imagesettile",
+ "imagestring",
+ "imagestringup",
+ "imagesx",
+ "imagesy",
+ "imagetruecolortopalette",
+ "imagettfbbox",
+ "imagettftext",
+ "imagetypes",
+ "image_type_to_mime_type",
+ "imagewbmp",
+ "imap_8bit",
+ "imap_alerts",
+ "imap_append",
+ "imap_base64",
+ "imap_binary",
+ "imap_body",
+ "imap_bodystruct",
+ "imap_check",
+ "imap_clearflag_full",
+ "imap_close",
+ "imap_createmailbox",
+ "imap_delete",
+ "imap_deletemailbox",
+ "imap_errors",
+ "imap_expunge",
+ "imap_fetchbody",
+ "imap_fetchheader",
+ "imap_fetch_overview",
+ "imap_fetchstructure",
+ "imap_getmailboxes",
+ "imap_get_quota",
+ "imap_get_quotaroot",
+ "imap_getsubscribed",
+ "imap_header",
+ "imap_headerinfo",
+ "imap_headers",
+ "imap_last_error",
+ "imap_list",
+ "imap_listmailbox",
+ "imap_listscan",
+ "imap_listsubscribed",
+ "imap_lsub",
+ "imap_mail",
+ "imap_mailboxmsginfo",
+ "imap_mail_compose",
+ "imap_mail_copy",
+ "imap_mail_move",
+ "imap_mime_header_decode",
+ "imap_msgno",
+ "imap_num_msg",
+ "imap_num_recent",
+ "imap_open",
+ "imap_ping",
+ "imap_qprint",
+ "imap_renamemailbox",
+ "imap_reopen",
+ "imap_rfc822_parse_adrlist",
+ "imap_rfc822_parse_headers",
+ "imap_rfc822_write_address",
+ "imap_scanmailbox",
+ "imap_search",
+ "imap_setacl",
+ "imap_setflag_full",
+ "imap_set_quota",
+ "imap_sort",
+ "imap_status",
+ "imap_subscribe",
+ "imap_thread",
+ "imap_uid",
+ "imap_undelete",
+ "imap_unsubscribe",
+ "imap_utf7_decode",
+ "imap_utf7_encode",
+ "imap_utf8",
+ "implements",
+ "implode",
+ "import_request_variables",
+ "in_array",
+ "include",
+ "include_once",
+ "info",
+ "ingres_autocommit",
+ "ingres_close",
+ "ingres_commit",
+ "ingres_connect",
+ "ingres_fetch_array",
+ "ingres_fetch_object",
+ "ingres_fetch_row",
+ "ingres_field_length",
+ "ingres_field_name",
+ "ingres_field_nullable",
+ "ingres_field_precision",
+ "ingres_field_scale",
+ "ingres_field_type",
+ "ingres_num_fields",
+ "ingres_num_rows",
+ "ingres_pconnect",
+ "ingres_query",
+ "ingres_rollback",
+ "ini_alter",
+ "ini_get",
+ "ini_get_all",
+ "ini_restore",
+ "ini_set",
+ "insert",
+ "insertanchor",
+ "insert_before",
+ "insertcollection",
+ "insertdocument",
+ "int",
+ "interface",
+ "internal_subset",
+ "intval",
+ "ip2long",
+ "iptcembed",
+ "iptcparse",
+ "ircg_channel_mode",
+ "ircg_disconnect",
+ "ircg_fetch_error_msg",
+ "ircg_get_username",
+ "ircg_html_encode",
+ "ircg_ignore_add",
+ "ircg_ignore_del",
+ "ircg_is_conn_alive",
+ "ircg_join",
+ "ircg_kick",
+ "ircg_lookup_format_messages",
+ "ircg_msg",
+ "ircg_nick",
+ "ircg_nickname_escape",
+ "ircg_nickname_unescape",
+ "ircg_notice",
+ "ircg_part",
+ "ircg_pconnect",
+ "ircg_register_format_messages",
+ "ircg_set_current",
+ "ircg_set_file",
+ "ircg_set_on_die",
+ "ircg_topic",
+ "ircg_whois",
+ "is_a",
+ "is_array",
+ "is_blank_node",
+ "is_bool",
+ "is_callable",
+ "is_dir",
+ "is_double",
+ "is_executable",
+ "is_file",
+ "is_finite",
+ "is_float",
+ "is_infinite",
+ "is_int",
+ "is_integer",
+ "is_link",
+ "is_long",
+ "is_nan",
+ "is_null",
+ "is_numeric",
+ "is_object",
+ "is_readable",
+ "is_real",
+ "is_resource",
+ "is_scalar",
+ "isset",
+ "is_string",
+ "is_subclass_of",
+ "is_uploaded_file",
+ "is_writable",
+ "is_writeable",
+ "java_last_exception_clear",
+ "java_last_exception_get",
+ "jddayofweek",
+ "jdmonthname",
+ "jdtofrench",
+ "jdtogregorian",
+ "jdtojewish",
+ "jdtojulian",
+ "jdtounix",
+ "jewishtojd",
+ "join",
+ "jpeg2wbmp",
+ "juliantojd",
+ "key",
+ "krsort",
+ "ksort",
+ "langdepvalue",
+ "last_child",
+ "lcg_value",
+ "ldap_8859_to_t61",
+ "ldap_add",
+ "ldap_bind",
+ "ldap_close",
+ "ldap_compare",
+ "ldap_connect",
+ "ldap_count_entries",
+ "ldap_delete",
+ "ldap_dn2ufn",
+ "ldap_err2str",
+ "ldap_errno",
+ "ldap_error",
+ "ldap_explode_dn",
+ "ldap_first_attribute",
+ "ldap_first_entry",
+ "ldap_first_reference",
+ "ldap_free_result",
+ "ldap_get_attributes",
+ "ldap_get_dn",
+ "ldap_get_entries",
+ "ldap_get_option",
+ "ldap_get_values",
+ "ldap_get_values_len",
+ "ldap_list",
+ "ldap_mod_add",
+ "ldap_mod_del",
+ "ldap_modify",
+ "ldap_mod_replace",
+ "ldap_next_attribute",
+ "ldap_next_entry",
+ "ldap_next_reference",
+ "ldap_parse_reference",
+ "ldap_parse_result",
+ "ldap_read",
+ "ldap_rename",
+ "ldap_search",
+ "ldap_set_option",
+ "ldap_set_rebind_proc",
+ "ldap_sort",
+ "ldap_start_tls",
+ "ldap_t61_to_8859",
+ "ldap_unbind",
+ "levenshtein",
+ "__LINE__",
+ "link",
+ "linkinfo",
+ "list",
+ "localeconv",
+ "localtime",
+ "lock",
+ "log",
+ "log10",
+ "log1p",
+ "long2ip",
+ "lstat",
+ "ltrim",
+ "mail",
+ "mailparse_determine_best_xfer_encoding",
+ "mailparse_msg_create",
+ "mailparse_msg_extract_part",
+ "mailparse_msg_extract_part_file",
+ "mailparse_msg_free",
+ "mailparse_msg_get_part",
+ "mailparse_msg_get_part_data",
+ "mailparse_msg_get_structure",
+ "mailparse_msg_parse",
+ "mailparse_msg_parse_file",
+ "mailparse_rfc822_parse_addresses",
+ "mailparse_stream_encode",
+ "mailparse_uudecode_all",
+ "main",
+ "max",
+ "mb_convert_case",
+ "mb_convert_encoding",
+ "mb_convert_kana",
+ "mb_convert_variables",
+ "mb_decode_mimeheader",
+ "mb_decode_numericentity",
+ "mb_detect_encoding",
+ "mb_detect_order",
+ "mb_encode_mimeheader",
+ "mb_encode_numericentity",
+ "mb_ereg",
+ "mb_eregi",
+ "mb_eregi_replace",
+ "mb_ereg_match",
+ "mb_ereg_replace",
+ "mb_ereg_search",
+ "mb_ereg_search_getpos",
+ "mb_ereg_search_getregs",
+ "mb_ereg_search_init",
+ "mb_ereg_search_pos",
+ "mb_ereg_search_regs",
+ "mb_ereg_search_setpos",
+ "mb_get_info",
+ "mb_http_input",
+ "mb_http_output",
+ "mb_internal_encoding",
+ "mb_language",
+ "mb_output_handler",
+ "mb_parse_str",
+ "mb_preferred_mime_name",
+ "mb_regex_encoding",
+ "mb_regex_set_options",
+ "mb_send_mail",
+ "mb_split",
+ "mb_strcut",
+ "mb_strimwidth",
+ "mb_strlen",
+ "mb_strpos",
+ "mb_strrpos",
+ "mb_strtolower",
+ "mb_strtoupper",
+ "mb_strwidth",
+ "mb_substitute_character",
+ "mb_substr",
+ "mb_substr_count",
+ "mcal_append_event",
+ "mcal_close",
+ "mcal_create_calendar",
+ "mcal_date_compare",
+ "mcal_date_valid",
+ "mcal_day_of_week",
+ "mcal_day_of_year",
+ "mcal_days_in_month",
+ "mcal_delete_calendar",
+ "mcal_delete_event",
+ "mcal_event_add_attribute",
+ "mcal_event_init",
+ "mcal_event_set_alarm",
+ "mcal_event_set_category",
+ "mcal_event_set_class",
+ "mcal_event_set_description",
+ "mcal_event_set_end",
+ "mcal_event_set_recur_daily",
+ "mcal_event_set_recur_monthly_mday",
+ "mcal_event_set_recur_monthly_wday",
+ "mcal_event_set_recur_none",
+ "mcal_event_set_recur_weekly",
+ "mcal_event_set_recur_yearly",
+ "mcal_event_set_start",
+ "mcal_event_set_title",
+ "mcal_expunge",
+ "mcal_fetch_current_stream_event",
+ "mcal_fetch_event",
+ "mcal_is_leap_year",
+ "mcal_list_alarms",
+ "mcal_list_events",
+ "mcal_next_recurrence",
+ "mcal_open",
+ "mcal_popen",
+ "mcal_rename_calendar",
+ "mcal_reopen",
+ "mcal_snooze",
+ "mcal_store_event",
+ "mcal_time_valid",
+ "mcal_week_of_year",
+ "mcrypt_cbc",
+ "mcrypt_cfb",
+ "mcrypt_create_iv",
+ "mcrypt_decrypt",
+ "mcrypt_ecb",
+ "mcrypt_enc_get_algorithms_name",
+ "mcrypt_enc_get_block_size",
+ "mcrypt_enc_get_iv_size",
+ "mcrypt_enc_get_key_size",
+ "mcrypt_enc_get_modes_name",
+ "mcrypt_enc_get_supported_key_sizes",
+ "mcrypt_enc_is_block_algorithm",
+ "mcrypt_enc_is_block_algorithm_mode",
+ "mcrypt_enc_is_block_mode",
+ "mcrypt_encrypt",
+ "mcrypt_enc_self_test",
+ "mcrypt_generic",
+ "mcrypt_generic_deinit",
+ "mcrypt_generic_end",
+ "mcrypt_generic_init",
+ "mcrypt_get_block_size",
+ "mcrypt_get_cipher_name",
+ "mcrypt_get_iv_size",
+ "mcrypt_get_key_size",
+ "mcrypt_list_algorithms",
+ "mcrypt_list_modes",
+ "mcrypt_module_close",
+ "mcrypt_module_get_algo_block_size",
+ "mcrypt_module_get_algo_key_size",
+ "mcrypt_module_get_supported_key_sizes",
+ "mcrypt_module_is_block_algorithm",
+ "mcrypt_module_is_block_algorithm_mode",
+ "mcrypt_module_is_block_mode",
+ "mcrypt_module_open",
+ "mcrypt_module_self_test",
+ "mcrypt_ofb",
+ "mcve_adduser",
+ "mcve_adduserarg",
+ "mcve_bt",
+ "mcve_checkstatus",
+ "mcve_chkpwd",
+ "mcve_chngpwd",
+ "mcve_completeauthorizations",
+ "mcve_connect",
+ "mcve_connectionerror",
+ "mcve_deleteresponse",
+ "mcve_deletetrans",
+ "mcve_deleteusersetup",
+ "mcve_deluser",
+ "mcve_destroyconn",
+ "mcve_destroyengine",
+ "mcve_disableuser",
+ "mcve_edituser",
+ "mcve_enableuser",
+ "mcve_force",
+ "mcve_getcell",
+ "mcve_getcellbynum",
+ "mcve_getcommadelimited",
+ "mcve_getheader",
+ "mcve_getuserarg",
+ "mcve_getuserparam",
+ "mcve_gft",
+ "mcve_gl",
+ "mcve_gut",
+ "mcve_initconn",
+ "mcve_initengine",
+ "mcve_initusersetup",
+ "mcve_iscommadelimited",
+ "mcve_liststats",
+ "mcve_listusers",
+ "mcve_maxconntimeout",
+ "mcve_monitor",
+ "mcve_numcolumns",
+ "mcve_numrows",
+ "mcve_override",
+ "mcve_parsecommadelimited",
+ "mcve_ping",
+ "mcve_preauth",
+ "mcve_preauthcompletion",
+ "mcve_qc",
+ "mcve_responseparam",
+ "mcve_return",
+ "mcve_returncode",
+ "mcve_returnstatus",
+ "mcve_sale",
+ "mcve_setblocking",
+ "mcve_setdropfile",
+ "mcve_setip",
+ "mcve_setssl",
+ "mcve_settimeout",
+ "mcve_settle",
+ "mcve_text_avs",
+ "mcve_text_code",
+ "mcve_text_cv",
+ "mcve_transactionauth",
+ "mcve_transactionavs",
+ "mcve_transactionbatch",
+ "mcve_transactioncv",
+ "mcve_transactionid",
+ "mcve_transactionitem",
+ "mcve_transactionssent",
+ "mcve_transactiontext",
+ "mcve_transinqueue",
+ "mcve_transnew",
+ "mcve_transparam",
+ "mcve_transsend",
+ "mcve_ub",
+ "mcve_uwait",
+ "mcve_verifyconnection",
+ "mcve_verifysslcert",
+ "mcve_void",
+ "md5",
+ "md5_file",
+ "mdecrypt_generic",
+ "memory_get_usage",
+ "metaphone",
+ "method_exists",
+ "mhash",
+ "mhash_count",
+ "mhash_get_block_size",
+ "mhash_get_hash_name",
+ "mhash_keygen_s2k",
+ "microtime",
+ "mime_content_type",
+ "mimetype",
+ "min",
+ "ming_setcubicthreshold",
+ "ming_setscale",
+ "ming_useswfversion",
+ "mkdir",
+ "mktime",
+ "money_format",
+ "move",
+ "movePen",
+ "movePenTo",
+ "moveTo",
+ "move_uploaded_file",
+ "msession_connect",
+ "msession_count",
+ "msession_create",
+ "msession_destroy",
+ "msession_disconnect",
+ "msession_find",
+ "msession_get",
+ "msession_get_array",
+ "msession_getdata",
+ "msession_inc",
+ "msession_list",
+ "msession_listvar",
+ "msession_lock",
+ "msession_plugin",
+ "msession_randstr",
+ "msession_set",
+ "msession_set_array",
+ "msession_setdata",
+ "msession_timeout",
+ "msession_uniq",
+ "msession_unlock",
+ "msg_get_queue",
+ "msg_receive",
+ "msg_remove_queue",
+ "msg_send",
+ "msg_set_queue",
+ "msg_stat_queue",
+ "msql",
+ "msql_affected_rows",
+ "msql_close",
+ "msql_connect",
+ "msql_create_db",
+ "msql_createdb",
+ "msql_data_seek",
+ "msql_dbname",
+ "msql_drop_db",
+ "msql_dropdb",
+ "msql_error",
+ "msql_fetch_array",
+ "msql_fetch_field",
+ "msql_fetch_object",
+ "msql_fetch_row",
+ "msql_fieldflags",
+ "msql_fieldlen",
+ "msql_fieldname",
+ "msql_field_seek",
+ "msql_fieldtable",
+ "msql_fieldtype",
+ "msql_free_result",
+ "msql_freeresult",
+ "msql_list_dbs",
+ "msql_listdbs",
+ "msql_list_fields",
+ "msql_listfields",
+ "msql_list_tables",
+ "msql_listtables",
+ "msql_num_fields",
+ "msql_numfields",
+ "msql_num_rows",
+ "msql_numrows",
+ "msql_pconnect",
+ "msql_query",
+ "msql_regcase",
+ "msql_result",
+ "msql_select_db",
+ "msql_selectdb",
+ "msql_tablename",
+ "mssql_bind",
+ "mssql_close",
+ "mssql_connect",
+ "mssql_data_seek",
+ "mssql_execute",
+ "mssql_fetch_array",
+ "mssql_fetch_assoc",
+ "mssql_fetch_batch",
+ "mssql_fetch_field",
+ "mssql_fetch_object",
+ "mssql_fetch_row",
+ "mssql_field_length",
+ "mssql_field_name",
+ "mssql_field_seek",
+ "mssql_field_type",
+ "mssql_free_result",
+ "mssql_free_statement",
+ "mssql_get_last_message",
+ "mssql_guid_string",
+ "mssql_init",
+ "mssql_min_error_severity",
+ "mssql_min_message_severity",
+ "mssql_next_result",
+ "mssql_num_fields",
+ "mssql_num_rows",
+ "mssql_pconnect",
+ "mssql_query",
+ "mssql_result",
+ "mssql_rows_affected",
+ "mssql_select_db",
+ "mt_getrandmax",
+ "mt_rand",
+ "mt_srand",
+ "multColor",
+ "muscat_close",
+ "muscat_get",
+ "muscat_give",
+ "muscat_setup",
+ "muscat_setup_net",
+ "mysql_affected_rows",
+ "mysql_change_user",
+ "mysql_client_encoding",
+ "mysql_close",
+ "mysql_connect",
+ "mysql_create_db",
+ "mysql_data_seek",
+ "mysql_db_name",
+ "mysql_db_query",
+ "mysql_drop_db",
+ "mysql_errno",
+ "mysql_error",
+ "mysql_escape_string",
+ "mysql_fetch_array",
+ "mysql_fetch_assoc",
+ "mysql_fetch_field",
+ "mysql_fetch_lengths",
+ "mysql_fetch_object",
+ "mysql_fetch_row",
+ "mysql_field_flags",
+ "mysql_field_len",
+ "mysql_field_name",
+ "mysql_field_seek",
+ "mysql_field_table",
+ "mysql_field_type",
+ "mysql_free_result",
+ "mysql_get_client_info",
+ "mysql_get_host_info",
+ "mysql_get_proto_info",
+ "mysql_get_server_info",
+ "mysql_info",
+ "mysql_insert_id",
+ "mysql_list_dbs",
+ "mysql_list_fields",
+ "mysql_list_processes",
+ "mysql_list_tables",
+ "mysql_num_fields",
+ "mysql_num_rows",
+ "mysql_pconnect",
+ "mysql_ping",
+ "mysql_query",
+ "mysql_real_escape_string",
+ "mysql_result",
+ "mysql_select_db",
+ "mysql_stat",
+ "mysql_tablename",
+ "mysql_thread_id",
+ "mysql_unbuffered_query",
+ "name",
+ "natcasesort",
+ "natsort",
+ "ncurses_addch",
+ "ncurses_addchnstr",
+ "ncurses_addchstr",
+ "ncurses_addnstr",
+ "ncurses_addstr",
+ "ncurses_assume_default_colors",
+ "ncurses_attroff",
+ "ncurses_attron",
+ "ncurses_attrset",
+ "ncurses_baudrate",
+ "ncurses_beep",
+ "ncurses_bkgd",
+ "ncurses_bkgdset",
+ "ncurses_border",
+ "ncurses_can_change_color",
+ "ncurses_cbreak",
+ "ncurses_clear",
+ "ncurses_clrtobot",
+ "ncurses_clrtoeol",
+ "ncurses_color_set",
+ "ncurses_curs_set",
+ "ncurses_define_key",
+ "ncurses_def_prog_mode",
+ "ncurses_def_shell_mode",
+ "ncurses_delay_output",
+ "ncurses_delch",
+ "ncurses_deleteln",
+ "ncurses_delwin",
+ "ncurses_doupdate",
+ "ncurses_echo",
+ "ncurses_echochar",
+ "ncurses_end",
+ "ncurses_erase",
+ "ncurses_erasechar",
+ "ncurses_filter",
+ "ncurses_flash",
+ "ncurses_flushinp",
+ "ncurses_getch",
+ "ncurses_getmouse",
+ "ncurses_halfdelay",
+ "ncurses_has_colors",
+ "ncurses_has_ic",
+ "ncurses_has_il",
+ "ncurses_has_key",
+ "ncurses_hline",
+ "ncurses_inch",
+ "ncurses_init",
+ "ncurses_init_color",
+ "ncurses_init_pair",
+ "ncurses_insch",
+ "ncurses_insdelln",
+ "ncurses_insertln",
+ "ncurses_insstr",
+ "ncurses_instr",
+ "ncurses_isendwin",
+ "ncurses_keyok",
+ "ncurses_killchar",
+ "ncurses_longname",
+ "ncurses_mouseinterval",
+ "ncurses_mousemask",
+ "ncurses_move",
+ "ncurses_mvaddch",
+ "ncurses_mvaddchnstr",
+ "ncurses_mvaddchstr",
+ "ncurses_mvaddnstr",
+ "ncurses_mvaddstr",
+ "ncurses_mvcur",
+ "ncurses_mvdelch",
+ "ncurses_mvgetch",
+ "ncurses_mvhline",
+ "ncurses_mvinch",
+ "ncurses_mvvline",
+ "ncurses_mvwaddstr",
+ "ncurses_napms",
+ "ncurses_newwin",
+ "ncurses_nl",
+ "ncurses_nocbreak",
+ "ncurses_noecho",
+ "ncurses_nonl",
+ "ncurses_noqiflush",
+ "ncurses_noraw",
+ "ncurses_putp",
+ "ncurses_qiflush",
+ "ncurses_raw",
+ "ncurses_refresh",
+ "ncurses_resetty",
+ "ncurses_savetty",
+ "ncurses_scr_dump",
+ "ncurses_scr_init",
+ "ncurses_scrl",
+ "ncurses_scr_restore",
+ "ncurses_scr_set",
+ "ncurses_slk_attr",
+ "ncurses_slk_attroff",
+ "ncurses_slk_attron",
+ "ncurses_slk_attrset",
+ "ncurses_slk_clear",
+ "ncurses_slk_color",
+ "ncurses_slk_init",
+ "ncurses_slk_noutrefresh",
+ "ncurses_slk_refresh",
+ "ncurses_slk_restore",
+ "ncurses_slk_touch",
+ "ncurses_standend",
+ "ncurses_standout",
+ "ncurses_start_color",
+ "ncurses_termattrs",
+ "ncurses_termname",
+ "ncurses_timeout",
+ "ncurses_typeahead",
+ "ncurses_ungetch",
+ "ncurses_ungetmouse",
+ "ncurses_use_default_colors",
+ "ncurses_use_env",
+ "ncurses_use_extended_names",
+ "ncurses_vidattr",
+ "ncurses_vline",
+ "ncurses_wrefresh",
+ "new",
+ "next",
+ "nextframe",
+ "next_sibling",
+ "ngettext",
+ "nl2br",
+ "nl_langinfo",
+ "node_name",
+ "node_type",
+ "node_value",
+ "notations",
+ "notes_body",
+ "notes_copy_db",
+ "notes_create_db",
+ "notes_create_note",
+ "notes_drop_db",
+ "notes_find_note",
+ "notes_header_info",
+ "notes_list_msgs",
+ "notes_mark_read",
+ "notes_mark_unread",
+ "notes_nav_create",
+ "notes_search",
+ "notes_unread",
+ "notes_version",
+ "NULL",
+ "number_format",
+ "ob_clean",
+ "ob_end_clean",
+ "ob_end_flush",
+ "ob_flush",
+ "ob_get_contents",
+ "ob_get_length",
+ "ob_get_level",
+ "ob_get_status",
+ "ob_gzhandler",
+ "ob_iconv_handler",
+ "ob_implicit_flush",
+ "object",
+ "objectbyanchor",
+ "ob_start",
+ "ocibindbyname",
+ "ocicancel",
+ "OCICollAppend",
+ "ocicollassign",
+ "ocicollassignelem",
+ "ocicollgetelem",
+ "ocicollmax",
+ "ocicollsize",
+ "ocicolltrim",
+ "ocicolumnisnull",
+ "ocicolumnname",
+ "ocicolumnprecision",
+ "ocicolumnscale",
+ "ocicolumnsize",
+ "ocicolumntype",
+ "ocicolumntyperaw",
+ "ocicommit",
+ "ocidefinebyname",
+ "ocierror",
+ "ociexecute",
+ "ocifetch",
+ "ocifetchinto",
+ "ocifetchstatement",
+ "ocifreecollection",
+ "ocifreecursor",
+ "OCIFreeDesc",
+ "ocifreestatement",
+ "ociinternaldebug",
+ "ociloadlob",
+ "ocilogoff",
+ "ocilogon",
+ "ocinewcollection",
+ "ocinewcursor",
+ "ocinewdescriptor",
+ "ocinlogon",
+ "ocinumcols",
+ "ociparse",
+ "ociplogon",
+ "ociresult",
+ "ocirollback",
+ "ocirowcount",
+ "ocisavelob",
+ "ocisavelobfile",
+ "ociserverversion",
+ "ocisetprefetch",
+ "ocistatementtype",
+ "ociwritelobtofile",
+ "octdec",
+ "odbc_autocommit",
+ "odbc_binmode",
+ "odbc_close",
+ "odbc_close_all",
+ "odbc_columnprivileges",
+ "odbc_columns",
+ "odbc_commit",
+ "odbc_connect",
+ "odbc_cursor",
+ "odbc_data_source",
+ "odbc_do",
+ "odbc_error",
+ "odbc_errormsg",
+ "odbc_exec",
+ "odbc_execute",
+ "odbc_fetch_array",
+ "odbc_fetch_into",
+ "odbc_fetch_object",
+ "odbc_fetch_row",
+ "odbc_field_len",
+ "odbc_field_name",
+ "odbc_field_num",
+ "odbc_field_precision",
+ "odbc_field_scale",
+ "odbc_field_type",
+ "odbc_foreignkeys",
+ "odbc_free_result",
+ "odbc_gettypeinfo",
+ "odbc_longreadlen",
+ "odbc_next_result",
+ "odbc_num_fields",
+ "odbc_num_rows",
+ "odbc_pconnect",
+ "odbc_prepare",
+ "odbc_primarykeys",
+ "odbc_procedurecolumns",
+ "odbc_procedures",
+ "odbc_result",
+ "odbc_result_all",
+ "odbc_rollback",
+ "odbc_setoption",
+ "odbc_specialcolumns",
+ "odbc_statistics",
+ "odbc_tableprivileges",
+ "odbc_tables",
+ "opendir",
+ "openlog",
+ "openssl_csr_export",
+ "openssl_csr_export_to_file",
+ "openssl_csr_new",
+ "openssl_csr_sign",
+ "openssl_error_string",
+ "openssl_free_key",
+ "openssl_get_privatekey",
+ "openssl_get_publickey",
+ "openssl_open",
+ "openssl_pkcs7_decrypt",
+ "openssl_pkcs7_encrypt",
+ "openssl_pkcs7_sign",
+ "openssl_pkcs7_verify",
+ "openssl_pkey_export",
+ "openssl_pkey_export_to_file",
+ "openssl_pkey_get_private",
+ "openssl_pkey_get_public",
+ "openssl_pkey_new",
+ "openssl_private_decrypt",
+ "openssl_private_encrypt",
+ "openssl_public_decrypt",
+ "openssl_public_encrypt",
+ "openssl_seal",
+ "openssl_sign",
+ "openssl_verify",
+ "openssl_x509_check_private_key",
+ "openssl_x509_checkpurpose",
+ "openssl_x509_export",
+ "openssl_x509_export_to_file",
+ "openssl_x509_free",
+ "openssl_x509_parse",
+ "openssl_x509_read",
+ "ora_bind",
+ "ora_close",
+ "ora_columnname",
+ "ora_columnsize",
+ "ora_columntype",
+ "ora_commit",
+ "ora_commitoff",
+ "ora_commiton",
+ "ora_do",
+ "ora_error",
+ "ora_errorcode",
+ "ora_exec",
+ "ora_fetch",
+ "ora_fetch_into",
+ "ora_getcolumn",
+ "ora_logoff",
+ "ora_logon",
+ "ora_numcols",
+ "ora_numrows",
+ "ora_open",
+ "ora_parse",
+ "ora_plogon",
+ "ora_rollback",
+ "ord",
+ "output",
+ "overload",
+ "ovrimos_close",
+ "ovrimos_commit",
+ "ovrimos_connect",
+ "ovrimos_cursor",
+ "ovrimos_exec",
+ "ovrimos_execute",
+ "ovrimos_fetch_into",
+ "ovrimos_fetch_row",
+ "ovrimos_field_len",
+ "ovrimos_field_name",
+ "ovrimos_field_num",
+ "ovrimos_field_type",
+ "ovrimos_free_result",
+ "ovrimos_longreadlen",
+ "ovrimos_num_fields",
+ "ovrimos_num_rows",
+ "ovrimos_prepare",
+ "ovrimos_result",
+ "ovrimos_result_all",
+ "ovrimos_rollback",
+ "owner_document",
+ "pack",
+ "parent_node",
+ "parents",
+ "parse_ini_file",
+ "parse_str",
+ "parse_url",
+ "passthru",
+ "pathinfo",
+ "PATH_TRANSLATED",
+ "pclose",
+ "pcntl_exec",
+ "pcntl_fork",
+ "pcntl_signal",
+ "pcntl_waitpid",
+ "pcntl_wexitstatus",
+ "pcntl_wifexited",
+ "pcntl_wifsignaled",
+ "pcntl_wifstopped",
+ "pcntl_wstopsig",
+ "pcntl_wtermsig",
+ "pdf_add_annotation",
+ "pdf_add_bookmark",
+ "pdf_add_launchlink",
+ "pdf_add_locallink",
+ "pdf_add_note",
+ "pdf_add_outline",
+ "pdf_add_pdflink",
+ "pdf_add_thumbnail",
+ "pdf_add_weblink",
+ "pdf_arc",
+ "pdf_arcn",
+ "pdf_attach_file",
+ "pdf_begin_page",
+ "pdf_begin_pattern",
+ "pdf_begin_template",
+ "pdf_circle",
+ "pdf_clip",
+ "pdf_close",
+ "pdf_close_image",
+ "pdf_closepath",
+ "pdf_closepath_fill_stroke",
+ "pdf_closepath_stroke",
+ "pdf_close_pdi",
+ "pdf_close_pdi_page",
+ "pdf_concat",
+ "pdf_continue_text",
+ "pdf_curveto",
+ "pdf_delete",
+ "pdf_end_page",
+ "pdf_endpath",
+ "pdf_end_pattern",
+ "pdf_end_template",
+ "pdf_fill",
+ "pdf_fill_stroke",
+ "pdf_findfont",
+ "pdf_get_buffer",
+ "pdf_get_font",
+ "pdf_get_fontname",
+ "pdf_get_fontsize",
+ "pdf_get_image_height",
+ "pdf_get_image_width",
+ "pdf_get_majorversion",
+ "pdf_get_minorversion",
+ "pdf_get_parameter",
+ "pdf_get_pdi_parameter",
+ "pdf_get_pdi_value",
+ "pdf_get_value",
+ "pdf_initgraphics",
+ "pdf_lineto",
+ "pdf_makespotcolor",
+ "pdf_moveto",
+ "pdf_new",
+ "pdf_open",
+ "pdf_open_CCITT",
+ "pdf_open_file",
+ "pdf_open_gif",
+ "pdf_open_image",
+ "pdf_open_image_file",
+ "pdf_open_jpeg",
+ "pdf_open_memory_image",
+ "pdf_open_pdi",
+ "pdf_open_pdi_page",
+ "pdf_open_png",
+ "pdf_open_tiff",
+ "pdf_place_image",
+ "pdf_place_pdi_page",
+ "pdf_rect",
+ "pdf_restore",
+ "pdf_rotate",
+ "pdf_save",
+ "pdf_scale",
+ "pdf_set_border_color",
+ "pdf_set_border_dash",
+ "pdf_set_border_style",
+ "pdf_set_char_spacing",
+ "pdf_setcolor",
+ "pdf_setdash",
+ "pdf_set_duration",
+ "pdf_setflat",
+ "pdf_set_font",
+ "pdf_setfont",
+ "pdf_setgray",
+ "pdf_setgray_fill",
+ "pdf_setgray_stroke",
+ "pdf_set_horiz_scaling",
+ "pdf_set_info",
+ "pdf_set_info_author",
+ "pdf_set_info_creator",
+ "pdf_set_info_keywords",
+ "pdf_set_info_subject",
+ "pdf_set_info_title",
+ "pdf_set_leading",
+ "pdf_setlinecap",
+ "pdf_setlinejoin",
+ "pdf_setlinewidth",
+ "pdf_setmatrix",
+ "pdf_setmiterlimit",
+ "pdf_set_parameter",
+ "pdf_setpolydash",
+ "pdf_setrgbcolor",
+ "pdf_setrgbcolor_fill",
+ "pdf_setrgbcolor_stroke",
+ "pdf_set_text_matrix",
+ "pdf_set_text_pos",
+ "pdf_set_text_rendering",
+ "pdf_set_text_rise",
+ "pdf_set_value",
+ "pdf_set_word_spacing",
+ "pdf_show",
+ "pdf_show_boxed",
+ "pdf_show_xy",
+ "pdf_skew",
+ "pdf_stringwidth",
+ "pdf_stroke",
+ "pdf_translate",
+ "PEAR_EXTENSION_DIR",
+ "PEAR_INSTALL_DIR",
+ "pfpro_cleanup",
+ "pfpro_init",
+ "pfpro_process",
+ "pfpro_process_raw",
+ "pfpro_version",
+ "pfsockopen",
+ "pg_affected_rows",
+ "pg_cancel_query",
+ "pg_client_encoding",
+ "pg_close",
+ "pg_connect",
+ "pg_connection_busy",
+ "pg_connection_reset",
+ "pg_connection_status",
+ "pg_convert",
+ "pg_copy_from",
+ "pg_copy_to",
+ "pg_dbname",
+ "pg_delete",
+ "pg_end_copy",
+ "pg_escape_bytea",
+ "pg_escape_string",
+ "pg_fetch_all",
+ "pg_fetch_array",
+ "pg_fetch_assoc",
+ "pg_fetch_object",
+ "pg_fetch_result",
+ "pg_fetch_row",
+ "pg_field_is_null",
+ "pg_field_name",
+ "pg_field_num",
+ "pg_field_prtlen",
+ "pg_field_size",
+ "pg_field_type",
+ "pg_free_result",
+ "pg_get_notify",
+ "pg_get_pid",
+ "pg_get_result",
+ "pg_host",
+ "pg_insert",
+ "pg_last_error",
+ "pg_last_notice",
+ "pg_last_oid",
+ "pg_lo_close",
+ "pg_lo_create",
+ "pg_lo_export",
+ "pg_lo_import",
+ "pg_lo_open",
+ "pg_lo_read",
+ "pg_lo_read_all",
+ "pg_lo_seek",
+ "pg_lo_tell",
+ "pg_lo_unlink",
+ "pg_lo_write",
+ "pg_meta_data",
+ "pg_num_fields",
+ "pg_num_rows",
+ "pg_options",
+ "pg_pconnect",
+ "pg_ping",
+ "pg_port",
+ "pg_put_line",
+ "pg_query",
+ "pg_result_error",
+ "pg_result_seek",
+ "pg_result_status",
+ "pg_select",
+ "pg_send_query",
+ "pg_set_client_encoding",
+ "pg_trace",
+ "pg_tty",
+ "pg_unescape_bytea",
+ "pg_untrace",
+ "pg_update",
+ "PHP_BINDIR",
+ "PHP_CONFIG_FILE_PATH",
+ "phpcredits",
+ "PHP_DATADIR",
+ "PHP_ERRMSG",
+ "PHP_EXTENSION_DIR",
+ "phpinfo",
+ "php_ini_scanned_files",
+ "PHP_LIBDIR",
+ "PHP_LOCALSTATEDIR",
+ "php_logo_guid",
+ "PHP_OS",
+ "PHP_OUTPUT_HANDLER_CONT",
+ "PHP_OUTPUT_HANDLER_END",
+ "PHP_OUTPUT_HANDLER_START",
+ "php_sapi_name",
+ "PHP_SELF",
+ "PHP_SYSCONFDIR",
+ "php_uname",
+ "phpversion",
+ "PHP_VERSION",
+ "pi",
+ "png2wbmp",
+ "popen",
+ "pos",
+ "posix_ctermid",
+ "posix_getcwd",
+ "posix_getegid",
+ "posix_geteuid",
+ "posix_getgid",
+ "posix_getgrgid",
+ "posix_getgrnam",
+ "posix_getgroups",
+ "posix_getlogin",
+ "posix_getpgid",
+ "posix_getpgrp",
+ "posix_getpid",
+ "posix_getppid",
+ "posix_getpwnam",
+ "posix_getpwuid",
+ "posix_getrlimit",
+ "posix_getsid",
+ "posix_getuid",
+ "posix_isatty",
+ "posix_kill",
+ "posix_mkfifo",
+ "posix_setegid",
+ "posix_seteuid",
+ "posix_setgid",
+ "posix_setpgid",
+ "posix_setsid",
+ "posix_setuid",
+ "posix_times",
+ "posix_ttyname",
+ "posix_uname",
+ "_POST",
+ "pow",
+ "prefix",
+ "preg_grep",
+ "preg_match",
+ "preg_match_all",
+ "preg_quote",
+ "preg_replace",
+ "preg_replace_callback",
+ "preg_split",
+ "prev",
+ "previous_sibling",
+ "print",
+ "printer_abort",
+ "printer_close",
+ "printer_create_brush",
+ "printer_create_dc",
+ "printer_create_font",
+ "printer_create_pen",
+ "printer_delete_brush",
+ "printer_delete_dc",
+ "printer_delete_font",
+ "printer_delete_pen",
+ "printer_draw_bmp",
+ "printer_draw_chord",
+ "printer_draw_elipse",
+ "printer_draw_line",
+ "printer_draw_pie",
+ "printer_draw_rectangle",
+ "printer_draw_roundrect",
+ "printer_draw_text",
+ "printer_end_doc",
+ "printer_end_page",
+ "printer_get_option",
+ "printer_list",
+ "printer_logical_fontheight",
+ "printer_open",
+ "printer_select_brush",
+ "printer_select_font",
+ "printer_select_pen",
+ "printer_set_option",
+ "printer_start_doc",
+ "printer_start_page",
+ "printer_write",
+ "printf",
+ "print_r",
+ "private",
+ "proc_close",
+ "process",
+ "proc_open",
+ "protected",
+ "pspell_add_to_personal",
+ "pspell_add_to_session",
+ "pspell_check",
+ "pspell_clear_session",
+ "pspell_config_create",
+ "pspell_config_ignore",
+ "pspell_config_mode",
+ "pspell_config_personal",
+ "pspell_config_repl",
+ "pspell_config_runtogether",
+ "pspell_config_save_repl",
+ "pspell_new",
+ "pspell_new_config",
+ "pspell_new_personal",
+ "pspell_save_wordlist",
+ "pspell_store_replacement",
+ "pspell_suggest",
+ "public",
+ "public_id",
+ "putenv",
+ "qdom_error",
+ "qdom_tree",
+ "QUERY_STRING",
+ "quoted_printable_decode",
+ "quotemeta",
+ "rad2deg",
+ "rand",
+ "range",
+ "rawurldecode",
+ "rawurlencode",
+ "read",
+ "readdir",
+ "read_exif_data",
+ "readfile",
+ "readgzfile",
+ "readline",
+ "readline_add_history",
+ "readline_clear_history",
+ "readline_completion_function",
+ "readline_info",
+ "readline_list_history",
+ "readline_read_history",
+ "readline_write_history",
+ "readlink",
+ "realpath",
+ "reason",
+ "recode",
+ "recode_file",
+ "recode_string",
+ "register_shutdown_function",
+ "register_tick_function",
+ "REMOTE_ADDR",
+ "REMOTE_PORT",
+ "remove",
+ "remove_attribute",
+ "remove_child",
+ "rename",
+ "replace",
+ "replace_child",
+ "replace_node",
+ "_REQUEST",
+ "REQUEST_METHOD",
+ "REQUEST_URI",
+ "require",
+ "require_once",
+ "reset",
+ "restore_error_handler",
+ "restore_include_path",
+ "result_dump_file",
+ "result_dump_mem",
+ "return",
+ "rewind",
+ "rewinddir",
+ "rmdir",
+ "Rotate",
+ "rotateTo",
+ "round",
+ "rsort",
+ "rtrim",
+ "save",
+ "scale",
+ "scaleTo",
+ "SCRIPT_FILENAME",
+ "SCRIPT_NAME",
+ "sem_acquire",
+ "sem_get",
+ "sem_release",
+ "sem_remove",
+ "serialize",
+ "_SERVER",
+ "SERVER_ADMIN",
+ "SERVER_NAME",
+ "SERVER_PORT",
+ "SERVER_PROTOCOL",
+ "SERVER_SIGNATURE",
+ "SERVER_SOFTWARE",
+ "sesam_affected_rows",
+ "sesam_commit",
+ "sesam_connect",
+ "sesam_diagnostic",
+ "sesam_disconnect",
+ "sesam_errormsg",
+ "sesam_execimm",
+ "sesam_fetch_array",
+ "sesam_fetch_result",
+ "sesam_fetch_row",
+ "sesam_field_array",
+ "sesam_field_name",
+ "sesam_free_result",
+ "sesam_num_fields",
+ "sesam_query",
+ "sesam_rollback",
+ "sesam_seek_row",
+ "sesam_settransaction",
+ "_SESSION",
+ "session_cache_expire",
+ "session_cache_limiter",
+ "session_decode",
+ "session_destroy",
+ "session_encode",
+ "session_get_cookie_params",
+ "session_id",
+ "session_is_registered",
+ "session_module_name",
+ "session_name",
+ "session_readonly",
+ "session_register",
+ "session_save_path",
+ "session_set_cookie_params",
+ "session_set_save_handler",
+ "session_start",
+ "session_unregister",
+ "session_unset",
+ "session_write_close",
+ "setAction",
+ "set_attribute",
+ "setbackground",
+ "setbounds",
+ "setcolor",
+ "setColor",
+ "setcommitedversion",
+ "set_content",
+ "setcookie",
+ "setDepth",
+ "setdimension",
+ "setdown",
+ "set_error_handler",
+ "set_file_buffer",
+ "setFont",
+ "setframes",
+ "setHeight",
+ "setHit",
+ "set_include_path",
+ "setindentation",
+ "setLeftFill",
+ "setLeftMargin",
+ "setLine",
+ "setLineSpacing",
+ "setlocale",
+ "set_magic_quotes_runtime",
+ "setMargins",
+ "set_name",
+ "setname",
+ "setName",
+ "set_namespace",
+ "setOver",
+ "setrate",
+ "setRatio",
+ "setRightFill",
+ "setrightMargin",
+ "setSpacing",
+ "set_time_limit",
+ "settype",
+ "setUp",
+ "sha1",
+ "sha1_file",
+ "shell_exec",
+ "shm_attach",
+ "shm_detach",
+ "shm_get_var",
+ "shmop_close",
+ "shmop_delete",
+ "shmop_open",
+ "shmop_read",
+ "shmop_size",
+ "shmop_write",
+ "shm_put_var",
+ "shm_remove",
+ "shm_remove_var",
+ "show_source",
+ "shuffle",
+ "similar_text",
+ "sin",
+ "sinh",
+ "sizeof",
+ "skewX",
+ "skewXTo",
+ "skewY",
+ "skewYTo",
+ "sleep",
+ "snmpget",
+ "snmp_get_quick_print",
+ "snmprealwalk",
+ "snmpset",
+ "snmp_set_quick_print",
+ "snmpwalk",
+ "snmpwalkoid",
+ "socket_accept",
+ "socket_bind",
+ "socket_clear_error",
+ "socket_close",
+ "socket_connect",
+ "socket_create",
+ "socket_create_listen",
+ "socket_create_pair",
+ "socket_get_option",
+ "socket_getpeername",
+ "socket_getsockname",
+ "socket_get_status",
+ "socket_iovec_add",
+ "socket_iovec_alloc",
+ "socket_iovec_delete",
+ "socket_iovec_fetch",
+ "socket_iovec_free",
+ "socket_iovec_set",
+ "socket_last_error",
+ "socket_listen",
+ "socket_read",
+ "socket_readv",
+ "socket_recv",
+ "socket_recvfrom",
+ "socket_recvmsg",
+ "socket_select",
+ "socket_send",
+ "socket_sendmsg",
+ "socket_sendto",
+ "socket_set_blocking",
+ "socket_set_nonblock",
+ "socket_set_option",
+ "socket_set_timeout",
+ "socket_shutdown",
+ "socket_strerror",
+ "socket_write",
+ "socket_writev",
+ "sort",
+ "soundex",
+ "specified",
+ "split",
+ "spliti",
+ "sprintf",
+ "sql_regcase",
+ "sqrt",
+ "srand",
+ "srcanchors",
+ "srcsofdst",
+ "sscanf",
+ "stat",
+ "static",
+ "stdClass",
+ "strcasecmp",
+ "strchr",
+ "strcmp",
+ "strcoll",
+ "strcspn",
+ "stream_context_create",
+ "stream_context_get_options",
+ "stream_context_set_option",
+ "stream_context_set_params",
+ "stream_filter_append",
+ "stream_filter_prepend",
+ "stream_get_filters",
+ "stream_get_meta_data",
+ "stream_get_wrappers",
+ "streammp3",
+ "stream_register_filter",
+ "stream_register_wrapper",
+ "stream_select",
+ "stream_set_blocking",
+ "stream_set_timeout",
+ "stream_set_write_buffer",
+ "strftime",
+ "stripcslashes",
+ "stripslashes",
+ "strip_tags",
+ "stristr",
+ "strlen",
+ "strnatcasecmp",
+ "strnatcmp",
+ "strncasecmp",
+ "strncmp",
+ "str_pad",
+ "strpos",
+ "strrchr",
+ "str_repeat",
+ "str_replace",
+ "strrev",
+ "str_rot13",
+ "strrpos",
+ "str_shuffle",
+ "strspn",
+ "strstr",
+ "strtok",
+ "strtolower",
+ "strtotime",
+ "strtoupper",
+ "strtr",
+ "strval",
+ "str_word_count",
+ "substr",
+ "substr_count",
+ "substr_replace",
+ "SWFAction",
+ "swf_actiongeturl",
+ "swf_actiongotoframe",
+ "swf_actiongotolabel",
+ "swf_actionnextframe",
+ "swf_actionplay",
+ "swf_actionprevframe",
+ "swf_actionsettarget",
+ "swf_actionstop",
+ "swf_actiontogglequality",
+ "swf_actionwaitforframe",
+ "swf_addbuttonrecord",
+ "swf_addcolor",
+ "SWFBitmap",
+ "SWFbutton",
+ "swfbutton_keypress",
+ "swf_closefile",
+ "swf_definebitmap",
+ "swf_definefont",
+ "swf_defineline",
+ "swf_definepoly",
+ "swf_definerect",
+ "swf_definetext",
+ "SWFDisplayItem",
+ "swf_endbutton",
+ "swf_enddoaction",
+ "swf_endshape",
+ "swf_endsymbol",
+ "SWFFill",
+ "SWFFont",
+ "swf_fontsize",
+ "swf_fontslant",
+ "swf_fonttracking",
+ "swf_getbitmapinfo",
+ "swf_getfontinfo",
+ "swf_getframe",
+ "SWFGradient",
+ "swf_labelframe",
+ "swf_lookat",
+ "swf_modifyobject",
+ "SWFMorph",
+ "SWFMovie",
+ "swf_mulcolor",
+ "swf_nextid",
+ "swf_oncondition",
+ "swf_openfile",
+ "swf_ortho",
+ "swf_ortho2",
+ "swf_perspective",
+ "swf_placeobject",
+ "swf_polarview",
+ "swf_popmatrix",
+ "swf_posround",
+ "swf_pushmatrix",
+ "swf_removeobject",
+ "swf_rotate",
+ "swf_scale",
+ "swf_setfont",
+ "swf_setframe",
+ "SWFShape",
+ "swf_shapearc",
+ "swf_shapecurveto",
+ "swf_shapecurveto3",
+ "swf_shapefillbitmapclip",
+ "swf_shapefillbitmaptile",
+ "swf_shapefilloff",
+ "swf_shapefillsolid",
+ "swf_shapelinesolid",
+ "swf_shapelineto",
+ "swf_shapemoveto",
+ "swf_showframe",
+ "SWFSprite",
+ "swf_startbutton",
+ "swf_startdoaction",
+ "swf_startshape",
+ "swf_startsymbol",
+ "SWFText",
+ "SWFTextField",
+ "swf_textwidth",
+ "swf_translate",
+ "swf_viewport",
+ "switch",
+ "sybase_affected_rows",
+ "sybase_close",
+ "sybase_connect",
+ "sybase_data_seek",
+ "sybase_fetch_array",
+ "sybase_fetch_field",
+ "sybase_fetch_object",
+ "sybase_fetch_row",
+ "sybase_field_seek",
+ "sybase_free_result",
+ "sybase_get_last_message",
+ "sybase_min_client_severity",
+ "sybase_min_error_severity",
+ "sybase_min_message_severity",
+ "sybase_min_server_severity",
+ "sybase_num_fields",
+ "sybase_num_rows",
+ "sybase_pconnect",
+ "sybase_query",
+ "sybase_result",
+ "sybase_select_db",
+ "symlink",
+ "syslog",
+ "system",
+ "system_id",
+ "tagname",
+ "tan",
+ "tanh",
+ "target",
+ "tempnam",
+ "textdomain",
+ "time",
+ "title",
+ "tmpfile",
+ "token_get_all",
+ "token_name",
+ "touch",
+ "trigger_error",
+ "trim",
+ "TRUE",
+ "type",
+ "uasort",
+ "ucfirst",
+ "ucwords",
+ "udm_add_search_limit",
+ "udm_alloc_agent",
+ "udm_api_version",
+ "udm_cat_list",
+ "udm_cat_path",
+ "udm_check_charset",
+ "udm_check_stored",
+ "udm_clear_search_limits",
+ "udm_close_stored",
+ "udm_crc32",
+ "udm_errno",
+ "udm_error",
+ "udm_find",
+ "udm_free_agent",
+ "udm_free_ispell_data",
+ "udm_free_res",
+ "udm_get_doc_count",
+ "udm_get_res_field",
+ "udm_get_res_param",
+ "udm_load_ispell_data",
+ "udm_open_stored",
+ "udm_set_agent_param",
+ "uksort",
+ "umask",
+ "uniqid",
+ "unixtojd",
+ "unlink",
+ "unlink_node",
+ "unlock",
+ "unpack",
+ "unregister_tick_function",
+ "unserialize",
+ "unset",
+ "urldecode",
+ "urlencode",
+ "user",
+ "user_error",
+ "userlist",
+ "usleep",
+ "usort",
+ "utf8_decode",
+ "utf8_encode",
+ "value",
+ "values",
+ "var",
+ "var_dump",
+ "var_export",
+ "version_compare",
+ "virtual",
+ "vpopmail_add_alias_domain",
+ "vpopmail_add_alias_domain_ex",
+ "vpopmail_add_domain",
+ "vpopmail_add_domain_ex",
+ "vpopmail_add_user",
+ "vpopmail_alias_add",
+ "vpopmail_alias_del",
+ "vpopmail_alias_del_domain",
+ "vpopmail_alias_get",
+ "vpopmail_alias_get_all",
+ "vpopmail_auth_user",
+ "vpopmail_del_domain",
+ "vpopmail_del_domain_ex",
+ "vpopmail_del_user",
+ "vpopmail_error",
+ "vpopmail_passwd",
+ "vpopmail_set_user_quota",
+ "vprintf",
+ "vsprintf",
+ "w32api_deftype",
+ "w32api_init_dtype",
+ "w32api_invoke_function",
+ "w32api_register_function",
+ "w32api_set_call_method",
+ "wddx_add_vars",
+ "wddx_deserialize",
+ "wddx_packet_end",
+ "wddx_packet_start",
+ "wddx_serialize_value",
+ "wddx_serialize_vars",
+ "while",
+ "wordwrap",
+ "xinclude",
+ "xml_error_string",
+ "xml_get_current_byte_index",
+ "xml_get_current_column_number",
+ "xml_get_current_line_number",
+ "xml_get_error_code",
+ "xml_parse",
+ "xml_parse_into_struct",
+ "xml_parser_create",
+ "xml_parser_create_ns",
+ "xml_parser_free",
+ "xml_parser_get_option",
+ "xml_parser_set_option",
+ "xmlrpc_decode",
+ "xmlrpc_decode_request",
+ "xmlrpc_encode",
+ "xmlrpc_encode_request",
+ "xmlrpc_get_type",
+ "xmlrpc_parse_method_descriptions",
+ "xmlrpc_server_add_introspection_data",
+ "xmlrpc_server_call_method",
+ "xmlrpc_server_create",
+ "xmlrpc_server_destroy",
+ "xmlrpc_server_register_introspection_callback",
+ "xmlrpc_server_register_method",
+ "xmlrpc_set_type",
+ "xml_set_character_data_handler",
+ "xml_set_default_handler",
+ "xml_set_element_handler",
+ "xml_set_end_namespace_decl_handler",
+ "xml_set_external_entity_ref_handler",
+ "xml_set_notation_decl_handler",
+ "xml_set_object",
+ "xml_set_processing_instruction_handler",
+ "xml_set_start_namespace_decl_handler",
+ "xml_set_unparsed_entity_decl_handler",
+ "xpath_eval",
+ "xpath_eval_expression",
+ "xpath_new_context",
+ "xptr_eval",
+ "xptr_new_context",
+ "xslt_create",
+ "xslt_errno",
+ "xslt_error",
+ "xslt_free",
+ "xslt_output_process",
+ "xslt_set_base",
+ "xslt_set_encoding",
+ "xslt_set_error_handler",
+ "xslt_set_log",
+ "xslt_set_sax_handler",
+ "xslt_set_sax_handlers",
+ "xslt_set_scheme_handler",
+ "xslt_set_scheme_handlers",
+ "yaz_addinfo",
+ "yaz_ccl_conf",
+ "yaz_ccl_parse",
+ "yaz_close",
+ "yaz_connect",
+ "yaz_database",
+ "yaz_element",
+ "yaz_errno",
+ "yaz_error",
+ "yaz_get_option",
+ "yaz_hits",
+ "yaz_itemorder",
+ "yaz_present",
+ "yaz_range",
+ "yaz_record",
+ "yaz_scan",
+ "yaz_scan_result",
+ "yaz_schema",
+ "yaz_search",
+ "yaz_set_option",
+ "yaz_sort",
+ "yaz_syntax",
+ "yaz_wait",
+ "yp_all",
+ "yp_cat",
+ "yp_errno",
+ "yp_err_string",
+ "yp_first",
+ "yp_get_default_domain",
+ "yp_master",
+ "yp_match",
+ "yp_next",
+ "yp_order",
+ "zend_logo_guid",
+ "zend_version",
+ "zend_version",
+ "zip_close",
+ "zip_entry_close",
+ "zip_entry_compressedsize",
+ "zip_entry_compressionmethod",
+ "zip_entry_filesize",
+ "zip_entry_name",
+ "zip_entry_open",
+ "zip_entry_read",
+ "zip_open",
+ "zip_read",
+ 0
+ };
+
+Php5Writer::Php5Writer() {
+}
+
+Php5Writer::~Php5Writer() {}
+
+
+void Php5Writer::writeClass(UMLClassifier *c) {
+ if(!c) {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ QString classname = cleanName(c->getName());
+ //find an appropriate name for our file
+ QString fileName = findFileName(c, ".php");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile filephp;
+ if(!openFile(filephp, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream php(&filephp);
+
+ //////////////////////////////
+ //Start generating the code!!
+ /////////////////////////////
+
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".php");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),filephp.name());
+ php<<str<<m_endl;
+ }
+
+
+ //write includes
+ UMLPackageList includes;
+ findObjectsRelated(c,includes);
+ UMLPackage *conc;
+ for(conc = includes.first(); conc ;conc = includes.next()) {
+ QString headerName = findFileName(conc, ".php");
+ if (!headerName.isEmpty()) {
+ php << "require_once '" << headerName << "';" << m_endl;
+ }
+ }
+ php << m_endl;
+
+ //Write class Documentation if there is somthing or if force option
+ if(forceDoc() || !c->getDoc().isEmpty()) {
+ php << m_endl << "/**" << m_endl;
+ php << " * class " << classname << m_endl;
+ php << formatDoc(c->getDoc()," * ");
+ php << " */" << m_endl ;
+ }
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+ UMLAssociationList realizations = c->getRealizations();
+ UMLAssociation *a;
+ bool isInterface = c->isInterface();
+
+ //check if it is an interface or regular class
+ if(isInterface) {
+ php << "interface " << classname;
+ } else {
+ //check if class is abstract and / or has abstract methods
+ if(c->getAbstract())
+ php << "abstract ";
+ php << "class " << classname << (superclasses.count() > 0 ? " extends ":"");
+ if(superclasses.count() > 0) {
+ //php5 does not support multiple inheritance so only use the first one and print a warning if more are used
+ UMLClassifier *obj = superclasses.first();
+ php << cleanName(obj->getName());
+ if(superclasses.count() > 1)
+ php << m_indentation << "//WARNING: PHP5 does not support multiple inheritance but there is more than 1 superclass defined in your UML model!";
+ }
+ //check for realizations
+ if( !realizations.isEmpty()) {
+ int rc = realizations.count();
+ int ri = rc;
+ for (a = realizations.first(); a; a = realizations.next()) {
+ UMLObject *o = a->getObject(Uml::B);
+ QString typeName = cleanName(o->getName());
+ if(ri == rc)
+ php << m_endl << m_indentation << m_indentation << m_indentation << "implements ";
+ php << typeName << (--rc == 0 ? "" : ", ");
+ }
+ }
+ }
+ php << m_endl << '{' << m_endl;
+
+ //associations
+ if( forceSections() || !aggregations.isEmpty()) {
+ php<< m_endl << m_indentation << "/** Aggregations: */" << m_endl;
+ for (a = aggregations.first(); a; a = aggregations.next()) {
+ php<< m_endl;
+ //maybe we should parse the string here and take multiplicity into account to decide
+ //which container to use.
+ UMLObject *o = a->getObject(Uml::A);
+ if (o == NULL) {
+ kError() << "aggregation role A object is NULL" << endl;
+ continue;
+ }
+ QString typeName = cleanName(o->getName());
+ if (a->getMulti(Uml::A).isEmpty()) {
+ php << m_indentation << "var $m_" << ';' << m_endl;
+ } else {
+ php << m_indentation << "var $m_" << "Vector = array();" << m_endl;
+ }
+ }//end for
+ }
+
+ if( forceSections() || !compositions.isEmpty()) {
+ php<< m_endl << m_indentation << "/** Compositions: */" << m_endl;
+ for (a = compositions.first(); a ; a = compositions.next()) {
+ // see comment on Aggregation about multiplicity...
+ UMLObject *o = a->getObject(Uml::A);
+ if (o == NULL) {
+ kError() << "composition role A object is NULL" << endl;
+ continue;
+ }
+ QString typeName = cleanName(o->getName());
+ if (a->getMulti(Uml::A).isEmpty()) {
+ php << m_indentation << "var $m_" << ';' << m_endl;
+ } else {
+ php << m_indentation << "var $m_" << "Vector = array();" << m_endl;
+ }
+ }
+ }
+
+ //attributes
+ if (!isInterface)
+ writeAttributes(c, php);
+
+ //operations
+ writeOperations(c,php);
+
+ php << m_endl;
+
+ //finish file
+ php << m_endl << "} // end of " << classname << m_endl;
+ php << "?>" << m_endl;
+
+ //close files and notfiy we are done
+ filephp.close();
+ emit codeGenerated(c, true);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+void Php5Writer::writeOperations(UMLClassifier *c, QTextStream &php) {
+
+ //Lists to store operations sorted by scope
+ UMLOperationList oppub,opprot,oppriv;
+
+ bool isInterface = c->isInterface();
+ bool generateErrorStub = false;
+
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList opl(c->getOpList());
+ for(UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ QString classname(cleanName(c->getName()));
+
+ //write operations to file
+ if(forceSections() || !oppub.isEmpty()) {
+ php << m_endl;
+ writeOperations(classname,oppub,php,isInterface,generateErrorStub);
+ }
+
+ if(forceSections() || !opprot.isEmpty()) {
+ php << m_endl;
+ writeOperations(classname,opprot,php,isInterface,generateErrorStub);
+ }
+
+ if(forceSections() || !oppriv.isEmpty()) {
+ php << m_endl;
+ writeOperations(classname,oppriv,php,isInterface,generateErrorStub);
+ }
+
+
+ // build an oplist for all of the realized operations
+ UMLOperationList opreal;
+ opreal.setAutoDelete(false);
+
+ // go through each of the realizations, taking each op
+ UMLAssociationList realizations = c->getRealizations();
+ UMLAssociation *a;
+
+ if( !realizations.isEmpty()) {
+ for (a = realizations.first(); a; a = realizations.next()) {
+
+ // we know its a classifier if its in the list
+ UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B);
+
+ UMLOperationList opl(real->getOpList());
+ for(UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ opreal.append(op);
+ }
+ }
+ }
+
+ // write out all the realizations operations
+ writeOperations(classname,opreal,php,false,true);
+
+}
+
+void Php5Writer::writeOperations(const QString &/* classname */, UMLOperationList &opList,
+ QTextStream &php, bool isInterface /* = false */,
+ bool generateErrorStub /* = false */) {
+ for (UMLOperation *op=opList.first(); op ; op=opList.next()) {
+ UMLAttributeList atl = op->getParmList();
+ UMLAttribute *at;
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+ for (at = atl.first(); at; at = atl.next())
+ writeDoc |= !at->getDoc().isEmpty();
+
+ if( writeDoc ) //write method documentation
+ {
+ php <<m_indentation << "/**" << m_endl <<formatDoc(op->getDoc(),m_indentation + " * ");
+ php << m_indentation << " *" << m_endl;
+
+ for (at = atl.first(); at; at = atl.next()) //write parameter documentation
+ {
+ if(forceDoc() || !at->getDoc().isEmpty()) {
+ php <<m_indentation << " * @param " + at->getTypeName() + ' ' + cleanName(at->getName());
+ php << ' ' + formatDoc(at->getDoc(),"") << m_endl;
+ }
+ }//end for : write parameter documentation
+ php << m_indentation << " * @return " << op->getTypeName() << m_endl;
+ if (op->getAbstract()) php << m_indentation << " * @abstract" << m_endl;
+ if (op->getStatic()) php << m_indentation << " * @static" << m_endl;
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ php << m_indentation << " * @access public" << m_endl;
+ break;
+ case Uml::Visibility::Protected:
+ php << m_indentation << " * @access protected" << m_endl;
+ break;
+ case Uml::Visibility::Private:
+ php << m_indentation << " * @access private" << m_endl;
+ break;
+ default:
+ break;
+ }
+ php <<m_indentation << " */" << m_endl;
+ }//end if : write method documentation
+
+ php << m_indentation;
+ if (op->getAbstract()) php << "abstract ";
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ php << "public ";
+ break;
+ case Uml::Visibility::Protected:
+ php << "protected ";
+ break;
+ case Uml::Visibility::Private:
+ php << "private ";
+ break;
+ default:
+ break;
+ }
+ if (op->getStatic()) php << "static ";
+ php << "function " << cleanName(op->getName()) << "(";
+
+ int i= atl.count();
+ int j=0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+ php << " $" << cleanName(at->getName())
+ << (!(at->getInitialValue().isEmpty()) ?
+ (QString(" = ")+at->getInitialValue()) :
+ QString(""))
+ << ((j < i-1)?", ":"");
+ }
+ php <<" )";
+ if(!isInterface && !op->getAbstract()) {
+ php << " {" << m_endl << m_indentation << m_indentation;
+ if(generateErrorStub) {
+ php << "trigger_error(\"Implement \" . __FUNCTION__);";
+ }
+ php << m_endl << m_indentation << "} // end of member function " + cleanName(op->getName()) + m_endl;
+ }
+ else {
+ php << ';' + m_endl;
+ }
+ php << m_endl;
+ }//end for
+}
+
+void Php5Writer::writeAttributes(UMLClassifier *c, QTextStream &php) {
+ UMLAttributeList atpub, atprot, atpriv, atdefval;
+ atpub.setAutoDelete(false);
+ atprot.setAutoDelete(false);
+ atpriv.setAutoDelete(false);
+ atdefval.setAutoDelete(false);
+
+ //sort attributes by scope and see if they have a default value
+ UMLAttributeList atl = c->getAttributeList();
+ UMLAttribute *at;
+ for(at = atl.first(); at ; at = atl.next()) {
+ if(!at->getInitialValue().isEmpty())
+ atdefval.append(at);
+ switch(at->getVisibility()) {
+ case Uml::Visibility::Public:
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ atpriv.append(at);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(forceSections() || atl.count())
+ php<< m_endl << m_indentation << " /*** Attributes: ***/" << m_endl <<m_endl;
+
+ if(forceSections() || atpub.count()) {
+ writeAttributes(atpub,php);
+ }
+
+ if(forceSections() || atprot.count()) {
+ writeAttributes(atprot,php);
+ }
+
+ if(forceSections() || atpriv.count()) {
+ writeAttributes(atpriv,php);
+ }
+}
+
+
+void Php5Writer::writeAttributes(UMLAttributeList &atList, QTextStream &php) {
+ for (UMLAttribute *at = atList.first(); at ; at = atList.next()) {
+ bool isStatic = at->getStatic();
+ if (forceDoc() || !at->getDoc().isEmpty()) {
+ php << m_indentation << "/**" << m_endl << formatDoc(at->getDoc(), m_indentation + " * ");
+ if(isStatic) php << m_indentation << " * @static" << m_endl;
+ switch(at->getVisibility()) {
+ case Uml::Visibility::Public:
+ php << m_indentation << " * @access public" << m_endl;
+ break;
+ case Uml::Visibility::Protected:
+ php << m_indentation << " * @access protected" << m_endl;
+ break;
+ case Uml::Visibility::Private:
+ php << m_indentation << " * @access private" << m_endl;
+ break;
+ default:
+ break;
+ }
+ php << m_indentation << " */" << m_endl;
+ }
+ php << m_indentation;
+ switch(at->getVisibility()) {
+ case Uml::Visibility::Public:
+ php << "public ";
+ break;
+ case Uml::Visibility::Protected:
+ php << "protected ";
+ break;
+ case Uml::Visibility::Private:
+ php << "private ";
+ break;
+ default:
+ break;
+ }
+ if(isStatic) php << "static ";
+ php << "$" << cleanName(at->getName());
+ if(!at->getInitialValue().isEmpty())
+ php << " = " << at->getInitialValue();
+ php << ";" << m_endl << m_endl;
+ } // end for
+ return;
+}
+
+/**
+ * returns "PHP"
+ */
+Uml::Programming_Language Php5Writer::getLanguage() {
+ return Uml::pl_PHP5;
+}
+
+const QStringList Php5Writer::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ for (int i = 0; php5words[i]; i++)
+ keywords.append(php5words[i]);
+ }
+
+ return keywords;
+}
+
+#include "php5writer.moc"
+
diff --git a/umbrello/umbrello/codegenerators/php5writer.h b/umbrello/umbrello/codegenerators/php5writer.h
new file mode 100644
index 00000000..3adc983c
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/php5writer.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ php5writer.h - description
+ -------------------
+ begin : Thu Oct 17 2002
+ copyright : (C) 2002 by Heiko Nardmann
+ email : h.nardmann@secunet.de
+
+ php5 version by Thorsten Kunz (tk AT bytecrash DOT net)
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHP5WRITER_H
+#define PHP5WRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umlattributelist.h"
+#include "../umloperationlist.h"
+
+/**
+ * class Php5Writer is a PHP code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class Php5Writer : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ Php5Writer();
+ virtual ~Php5Writer();
+
+ /**
+ * call this method to generate Php code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "PHP"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * we do not want to write the comment "Private methods" twice
+ */
+ bool bPrivateSectionCommentIsWritten;
+
+ /**
+ * write all operations for a given class
+ *
+ * @param c the concept we are generating code for
+ * @param php output stream for the PHP file
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &php);
+
+ /**
+ * write a list of class operations
+ *
+ * @param classname the name of the class
+ * @param opList the list of operations
+ * @param php output stream for the PHP file
+ * @param interface indicates if the operation is an interface member
+ */
+ void writeOperations(const QString &classname, UMLOperationList &opList,
+ QTextStream &php,
+ bool interface = false, bool generateErrorStub = false);
+
+ /** write all the attributes of a class
+ * @param c the class we are generating code for
+ * @param php output stream for the PHP file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &php);
+
+ /** write a list of class attributes
+ * @param atList the list of attributes
+ * @param php output stream for the PHP file
+ */
+ void writeAttributes(UMLAttributeList &atList, QTextStream &php);
+};
+
+#endif //PHP5WRITER
+
diff --git a/umbrello/umbrello/codegenerators/phpwriter.cpp b/umbrello/umbrello/codegenerators/phpwriter.cpp
new file mode 100644
index 00000000..6d71c102
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/phpwriter.cpp
@@ -0,0 +1,3339 @@
+/***************************************************************************
+ begin : Thu Oct 17 2002
+ copyright : (C) 2002 by Heiko Nardmann
+ email : h.nardmann@secunet.de
+ (C) 2003-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "phpwriter.h"
+
+#include <kdebug.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+
+static const char *words[] =
+ {
+ "abs",
+ "acos",
+ "acosh",
+ "add",
+ "addAction",
+ "addColor",
+ "addcslashes",
+ "addEntry",
+ "addFill",
+ "add_namespace",
+ "addShape",
+ "addslashes",
+ "addstring",
+ "addString",
+ "aggregate",
+ "aggregate_info",
+ "aggregate_methods",
+ "aggregate_methods_by_list",
+ "aggregate_methods_by_regexp",
+ "aggregate_properties",
+ "aggregate_properties_by_list",
+ "aggregate_properties_by_regexp",
+ "aggregation_info",
+ "align",
+ "apache_child_terminate",
+ "apache_lookup_uri",
+ "apache_note",
+ "apache_request_headers",
+ "apache_response_headers",
+ "apache_setenv",
+ "append_child",
+ "append_sibling",
+ "array",
+ "array_change_key_case",
+ "array_chunk",
+ "array_count_values",
+ "array_diff",
+ "array_diff_assoc",
+ "array_fill",
+ "array_filter",
+ "array_flip",
+ "array_intersect",
+ "array_intersect_assoc",
+ "array_key_exists",
+ "array_keys",
+ "array_map",
+ "array_merge",
+ "array_merge_recursive",
+ "array_multisort",
+ "array_pad",
+ "array_pop",
+ "array_push",
+ "array_rand",
+ "array_reduce",
+ "array_reverse",
+ "array_search",
+ "array_shift",
+ "array_slice",
+ "array_splice",
+ "array_sum",
+ "array_unique",
+ "array_unshift",
+ "array_values",
+ "array_walk",
+ "arsort",
+ "ascii2ebcdic",
+ "asin",
+ "asinh",
+ "asort",
+ "aspell_check",
+ "aspell_new",
+ "aspell_suggest",
+ "assert",
+ "assert_options",
+ "assign",
+ "atan",
+ "atan2",
+ "atanh",
+ "attreditable",
+ "attributes",
+ "base64_decode",
+ "base64_encode",
+ "base_convert",
+ "basename",
+ "bcadd",
+ "bccomp",
+ "bcdiv",
+ "bcmod",
+ "bcmul",
+ "bcpow",
+ "bcpowmod",
+ "bcscale",
+ "bcsqrt",
+ "bcsub",
+ "bin2hex",
+ "bindec",
+ "bindtextdomain",
+ "bind_textdomain_codeset",
+ "bool",
+ "break",
+ "bzclose",
+ "bzcompress",
+ "bzdecompress",
+ "bzerrno",
+ "bzerror",
+ "bzerrstr",
+ "bzflush",
+ "bzopen",
+ "bzread",
+ "bzwrite",
+ "cal_days_in_month",
+ "cal_from_jd",
+ "cal_info",
+ "call_user_func",
+ "call_user_func_array",
+ "call_user_method",
+ "call_user_method_array",
+ "cal_to_jd",
+ "ccvs_add",
+ "ccvs_auth",
+ "ccvs_command",
+ "ccvs_count",
+ "ccvs_delete",
+ "ccvs_done",
+ "ccvs_init",
+ "ccvs_lookup",
+ "ccvs_new",
+ "ccvs_report",
+ "ccvs_return",
+ "ccvs_reverse",
+ "ccvs_sale",
+ "ccvs_status",
+ "ccvs_textvalue",
+ "ccvs_void",
+ "ceil",
+ "chdir",
+ "checkdate",
+ "checkdnsrr",
+ "checkin",
+ "checkout",
+ "chgrp",
+ "child_nodes",
+ "children",
+ "chmod",
+ "chop",
+ "chown",
+ "chr",
+ "chroot",
+ "chunk_split",
+ "class",
+ "class_exists",
+ "clearstatcache",
+ "clone_node",
+ "closedir",
+ "closelog",
+ "com_addref",
+ "com_get",
+ "com_invoke",
+ "com_isenum",
+ "com_load",
+ "com_load_typelib",
+ "compact",
+ "com_propget",
+ "com_propput",
+ "com_propset",
+ "com_release",
+ "com_set",
+ "connection_aborted",
+ "connection_status",
+ "connection_timeout",
+ "constant",
+ "content",
+ "continue",
+ "convert_cyr_string",
+ "_COOKIE",
+ "copy",
+ "cos",
+ "cosh",
+ "count",
+ "count_chars",
+ "cpdf_add_annotation",
+ "cpdf_add_outline",
+ "cpdf_arc",
+ "cpdf_begin_text",
+ "cpdf_circle",
+ "cpdf_clip",
+ "cpdf_close",
+ "cpdf_closepath",
+ "cpdf_closepath_fill_stroke",
+ "cpdf_closepath_stroke",
+ "cpdf_continue_text",
+ "cpdf_curveto",
+ "cpdf_end_text",
+ "cpdf_fill",
+ "cpdf_fill_stroke",
+ "cpdf_finalize",
+ "cpdf_finalize_page",
+ "cpdf_global_set_document_limits",
+ "cpdf_import_jpeg",
+ "cpdf_lineto",
+ "cpdf_moveto",
+ "cpdf_newpath",
+ "cpdf_open",
+ "cpdf_output_buffer",
+ "cpdf_page_init",
+ "cpdf_place_inline_image",
+ "cpdf_rect",
+ "cpdf_restore",
+ "cpdf_rlineto",
+ "cpdf_rmoveto",
+ "cpdf_rotate",
+ "cpdf_rotate_text",
+ "cpdf_save",
+ "cpdf_save_to_file",
+ "cpdf_scale",
+ "cpdf_set_action_url",
+ "cpdf_set_char_spacing",
+ "cpdf_set_creator",
+ "cpdf_set_current_page",
+ "cpdf_setdash",
+ "cpdf_setflat",
+ "cpdf_set_font",
+ "cpdf_set_font_directories",
+ "cpdf_set_font_map_file",
+ "cpdf_setgray",
+ "cpdf_setgray_fill",
+ "cpdf_setgray_stroke",
+ "cpdf_set_horiz_scaling",
+ "cpdf_set_keywords",
+ "cpdf_set_leading",
+ "cpdf_setlinecap",
+ "cpdf_setlinejoin",
+ "cpdf_setlinewidth",
+ "cpdf_setmiterlimit",
+ "cpdf_set_page_animation",
+ "cpdf_setrgbcolor",
+ "cpdf_setrgbcolor_fill",
+ "cpdf_setrgbcolor_stroke",
+ "cpdf_set_subject",
+ "cpdf_set_text_matrix",
+ "cpdf_set_text_pos",
+ "cpdf_set_text_rendering",
+ "cpdf_set_text_rise",
+ "cpdf_set_title",
+ "cpdf_set_viewer_preferences",
+ "cpdf_set_word_spacing",
+ "cpdf_show",
+ "cpdf_show_xy",
+ "cpdf_stringwidth",
+ "cpdf_stroke",
+ "cpdf_text",
+ "cpdf_translate",
+ "crack_check",
+ "crack_closedict",
+ "crack_getlastmessage",
+ "crack_opendict",
+ "crc32",
+ "create_attribute",
+ "create_cdata_section",
+ "create_comment",
+ "create_element",
+ "create_element_ns",
+ "create_entity_reference",
+ "create_function",
+ "create_processing_instruction",
+ "create_text_node",
+ "crypt",
+ "ctype_alnum",
+ "ctype_alpha",
+ "ctype_cntrl",
+ "ctype_digit",
+ "ctype_graph",
+ "ctype_lower",
+ "ctype_print",
+ "ctype_punct",
+ "ctype_space",
+ "ctype_upper",
+ "ctype_xdigit",
+ "curl_close",
+ "curl_errno",
+ "curl_error",
+ "curl_exec",
+ "curl_getinfo",
+ "curl_init",
+ "curl_setopt",
+ "curl_version",
+ "current",
+ "cybercash_base64_decode",
+ "cybercash_base64_encode",
+ "cybercash_decr",
+ "cybercash_encr",
+ "cybermut_creerformulairecm",
+ "cybermut_creerreponsecm",
+ "cybermut_testmac",
+ "cyrus_authenticate",
+ "cyrus_bind",
+ "cyrus_close",
+ "cyrus_connect",
+ "cyrus_query",
+ "cyrus_unbind",
+ "data",
+ "date",
+ "dba_close",
+ "dba_delete",
+ "dba_exists",
+ "dba_fetch",
+ "dba_firstkey",
+ "dba_handlers",
+ "dba_insert",
+ "dba_list",
+ "dba_nextkey",
+ "dba_open",
+ "dba_optimize",
+ "dba_popen",
+ "dba_replace",
+ "dbase_add_record",
+ "dbase_close",
+ "dbase_create",
+ "dbase_delete_record",
+ "dbase_get_record",
+ "dbase_get_record_with_names",
+ "dbase_numfields",
+ "dbase_numrecords",
+ "dbase_open",
+ "dbase_pack",
+ "dbase_replace_record",
+ "dba_sync",
+ "dblist",
+ "dbmclose",
+ "dbmdelete",
+ "dbmexists",
+ "dbmfetch",
+ "dbmfirstkey",
+ "dbminsert",
+ "dbmnextkey",
+ "dbmopen",
+ "dbmreplace",
+ "dbplus_add",
+ "dbplus_aql",
+ "dbplus_chdir",
+ "dbplus_close",
+ "dbplus_curr",
+ "dbplus_errcode",
+ "dbplus_errno",
+ "dbplus_find",
+ "dbplus_first",
+ "dbplus_flush",
+ "dbplus_freealllocks",
+ "dbplus_freelock",
+ "dbplus_freerlocks",
+ "dbplus_getlock",
+ "dbplus_getunique",
+ "dbplus_info",
+ "dbplus_last",
+ "dbplus_lockrel",
+ "dbplus_next",
+ "dbplus_open",
+ "dbplus_prev",
+ "dbplus_rchperm",
+ "dbplus_rcreate",
+ "dbplus_rcrtexact",
+ "dbplus_rcrtlike",
+ "dbplus_resolve",
+ "dbplus_restorepos",
+ "dbplus_rkeys",
+ "dbplus_ropen",
+ "dbplus_rquery",
+ "dbplus_rrename",
+ "dbplus_rsecindex",
+ "dbplus_runlink",
+ "dbplus_rzap",
+ "dbplus_savepos",
+ "dbplus_setindex",
+ "dbplus_setindexbynumber",
+ "dbplus_sql",
+ "dbplus_tcl",
+ "dbplus_tremove",
+ "dbplus_undo",
+ "dbplus_undoprepare",
+ "dbplus_unlockrel",
+ "dbplus_unselect",
+ "dbplus_update",
+ "dbplus_xlockrel",
+ "dbplus_xunlockrel",
+ "dbstat",
+ "dbx_close",
+ "dbx_compare",
+ "dbx_connect",
+ "dbx_error",
+ "dbx_escape_string",
+ "dbx_query",
+ "dbx_sort",
+ "dcgettext",
+ "dcngettext",
+ "dcstat",
+ "deaggregate",
+ "debug_backtrace",
+ "debugger_off",
+ "debugger_on",
+ "decbin",
+ "dechex",
+ "declare",
+ "decoct",
+ "DEFAULT_INCLUDE_PATH",
+ "define",
+ "defined",
+ "define_syslog_variables",
+ "deg2rad",
+ "delete",
+ "description",
+ "dgettext",
+ "die",
+ "dio_close",
+ "dio_fcntl",
+ "dio_open",
+ "dio_read",
+ "dio_seek",
+ "dio_stat",
+ "dio_tcsetattr",
+ "dio_truncate",
+ "dio_write",
+ "dir",
+ "dirname",
+ "disk_free_space",
+ "diskfreespace",
+ "disk_total_space",
+ "dl",
+ "dngettext",
+ "dns_check_record",
+ "dns_get_mx",
+ "dns_get_record",
+ "do",
+ "doctype",
+ "document_element",
+ "DOCUMENT_ROOT",
+ "domxml_new_doc",
+ "domxml_open_file",
+ "domxml_open_mem",
+ "domxml_version",
+ "domxml_xmltree",
+ "domxml_xslt_stylesheet",
+ "domxml_xslt_stylesheet_doc",
+ "domxml_xslt_stylesheet_file",
+ "dotnet_load",
+ "doubleval",
+ "drawCurve",
+ "drawCurveTo",
+ "drawLine",
+ "drawLineTo",
+ "dstanchors",
+ "dstofsrcanchors",
+ "dump_file",
+ "dump_mem",
+ "dump_node",
+ "each",
+ "E_ALL",
+ "easter_date",
+ "easter_days",
+ "ebcdic2ascii",
+ "echo",
+ "E_COMPILE_ERROR",
+ "E_COMPILE_WARNING",
+ "E_CORE_ERROR",
+ "E_CORE_WARNING",
+ "E_ERROR",
+ "else",
+ "elseif",
+ "empty",
+ "end",
+ "endfor",
+ "endforeach",
+ "endif",
+ "endswitch",
+ "endwhile",
+ "E_NOTICE",
+ "entities",
+ "_ENV",
+ "E_PARSE",
+ "ereg",
+ "eregi",
+ "eregi_replace",
+ "ereg_replace",
+ "error_log",
+ "error_reporting",
+ "escapeshellarg",
+ "escapeshellcmd",
+ "E_USER_ERROR",
+ "E_USER_NOTICE",
+ "E_USER_WARNING",
+ "eval",
+ "E_WARNING",
+ "exec",
+ "exif_imagetype",
+ "exif_read_data",
+ "exif_thumbnail",
+ "exit",
+ "exp",
+ "explode",
+ "expm1",
+ "extension_loaded",
+ "extract",
+ "ezmlm_hash",
+ "FALSE",
+ "fbsql_affected_rows",
+ "fbsql_autocommit",
+ "fbsql_change_user",
+ "fbsql_close",
+ "fbsql_commit",
+ "fbsql_connect",
+ "fbsql_create_blob",
+ "fbsql_create_clob",
+ "fbsql_create_db",
+ "fbsql_database",
+ "fbsql_database_password",
+ "fbsql_data_seek",
+ "fbsql_db_query",
+ "fbsql_db_status",
+ "fbsql_drop_db",
+ "fbsql_errno",
+ "fbsql_error",
+ "fbsql_fetch_array",
+ "fbsql_fetch_assoc",
+ "fbsql_fetch_field",
+ "fbsql_fetch_lengths",
+ "fbsql_fetch_object",
+ "fbsql_fetch_row",
+ "fbsql_field_flags",
+ "fbsql_field_len",
+ "fbsql_field_name",
+ "fbsql_field_seek",
+ "fbsql_field_table",
+ "fbsql_field_type",
+ "fbsql_free_result",
+ "fbsql_get_autostart_info",
+ "fbsql_hostname",
+ "fbsql_insert_id",
+ "fbsql_list_dbs",
+ "fbsql_list_fields",
+ "fbsql_list_tables",
+ "fbsql_next_result",
+ "fbsql_num_fields",
+ "fbsql_num_rows",
+ "fbsql_password",
+ "fbsql_pconnect",
+ "fbsql_query",
+ "fbsql_read_blob",
+ "fbsql_read_clob",
+ "fbsql_result",
+ "fbsql_rollback",
+ "fbsql_select_db",
+ "fbsql_set_lob_mode",
+ "fbsql_set_transaction",
+ "fbsql_start_db",
+ "fbsql_stop_db",
+ "fbsql_tablename",
+ "fbsql_username",
+ "fbsql_warnings",
+ "fclose",
+ "fdf_add_doc_javascript",
+ "fdf_add_template",
+ "fdf_close",
+ "fdf_create",
+ "fdf_errno",
+ "fdf_error",
+ "fdf_get_ap",
+ "fdf_get_attachment",
+ "fdf_get_encoding",
+ "fdf_get_file",
+ "fdf_get_status",
+ "fdf_get_value",
+ "fdf_get_version",
+ "fdf_header",
+ "fdf_next_field_name",
+ "fdf_open",
+ "fdf_open_string",
+ "fdf_save",
+ "fdf_save_string",
+ "fdf_set_ap",
+ "fdf_set_encoding",
+ "fdf_set_file",
+ "fdf_set_flags",
+ "fdf_set_javascript_action",
+ "fdf_set_opt",
+ "fdf_set_status",
+ "fdf_set_submit_form_action",
+ "fdf_set_target_frame",
+ "fdf_set_value",
+ "fdf_set_version",
+ "feof",
+ "fflush",
+ "fgetc",
+ "fgetcsv",
+ "fgets",
+ "fgetss",
+ "file",
+ "__FILE__",
+ "fileatime",
+ "filectime",
+ "file_exists",
+ "file_get_contents",
+ "filegroup",
+ "fileinode",
+ "filemtime",
+ "fileowner",
+ "fileperms",
+ "filepro",
+ "filepro_fieldcount",
+ "filepro_fieldname",
+ "filepro_fieldtype",
+ "filepro_fieldwidth",
+ "filepro_retrieve",
+ "filepro_rowcount",
+ "_FILES",
+ "filesize",
+ "filetype",
+ "find",
+ "first_child",
+ "floatval",
+ "flock",
+ "floor",
+ "flush",
+ "fmod",
+ "fnmatch",
+ "fopen",
+ "for",
+ "foreach",
+ "fpassthru",
+ "fprintf",
+ "fputs",
+ "fread",
+ "frenchtojd",
+ "fribidi_log2vis",
+ "fscanf",
+ "fseek",
+ "fsockopen",
+ "fstat",
+ "ftell",
+ "ftok",
+ "ftp_cdup",
+ "ftp_chdir",
+ "ftp_close",
+ "ftp_connect",
+ "ftp_delete",
+ "ftp_exec",
+ "ftp_fget",
+ "ftp_fput",
+ "ftp_get",
+ "ftp_get_option",
+ "ftp_login",
+ "ftp_mdtm",
+ "ftp_mkdir",
+ "ftp_nb_continue",
+ "ftp_nb_fget",
+ "ftp_nb_fput",
+ "ftp_nb_get",
+ "ftp_nb_put",
+ "ftp_nlist",
+ "ftp_pasv",
+ "ftp_put",
+ "ftp_pwd",
+ "ftp_quit",
+ "ftp_rawlist",
+ "ftp_rename",
+ "ftp_rmdir",
+ "ftp_set_option",
+ "ftp_site",
+ "ftp_size",
+ "ftp_ssl_connect",
+ "ftp_systype",
+ "ftruncate",
+ "ftstat",
+ "func_get_arg",
+ "func_get_args",
+ "func_num_args",
+ "function",
+ "function_exists",
+ "fwrite",
+ "GATEWAY_INTERFACE",
+ "gd_info",
+ "_GET",
+ "getallheaders",
+ "get_attribute",
+ "get_attribute_node",
+ "get_browser",
+ "get_cfg_var",
+ "get_class",
+ "get_class_methods",
+ "get_class_vars",
+ "get_content",
+ "get_current_user",
+ "getcwd",
+ "getdate",
+ "get_declared_classes",
+ "get_defined_constants",
+ "get_defined_functions",
+ "get_defined_vars",
+ "get_element_by_id",
+ "get_elements_by_tagname",
+ "getenv",
+ "get_extension_funcs",
+ "getHeight",
+ "gethostbyaddr",
+ "gethostbyname",
+ "gethostbynamel",
+ "get_html_translation_table",
+ "getimagesize",
+ "get_included_files",
+ "get_include_path",
+ "getlastmod",
+ "get_loaded_extensions",
+ "get_magic_quotes_gpc",
+ "get_magic_quotes_runtime",
+ "get_meta_tags",
+ "getmxrr",
+ "getmygid",
+ "getmyinode",
+ "getmypid",
+ "getmyuid",
+ "get_object_vars",
+ "getopt",
+ "get_parent_class",
+ "getprotobyname",
+ "getprotobynumber",
+ "getrandmax",
+ "get_required_files",
+ "get_resource_type",
+ "getrusage",
+ "getservbyname",
+ "getservbyport",
+ "getshape1",
+ "getshape2",
+ "gettext",
+ "gettimeofday",
+ "gettype",
+ "getwidth",
+ "getWidth",
+ "glob",
+ "global",
+ "GLOBALS",
+ "gmdate",
+ "gmmktime",
+ "gmp_abs",
+ "gmp_add",
+ "gmp_and",
+ "gmp_clrbit",
+ "gmp_cmp",
+ "gmp_com",
+ "gmp_div",
+ "gmp_divexact",
+ "gmp_div_q",
+ "gmp_div_qr",
+ "gmp_div_r",
+ "gmp_fact",
+ "gmp_gcd",
+ "gmp_gcdext",
+ "gmp_hamdist",
+ "gmp_init",
+ "gmp_intval",
+ "gmp_invert",
+ "gmp_jacobi",
+ "gmp_legendre",
+ "gmp_mod",
+ "gmp_mul",
+ "gmp_neg",
+ "gmp_or",
+ "gmp_perfect_square",
+ "gmp_popcount",
+ "gmp_pow",
+ "gmp_powm",
+ "gmp_prob_prime",
+ "gmp_random",
+ "gmp_scan0",
+ "gmp_scan1",
+ "gmp_setbit",
+ "gmp_sign",
+ "gmp_sqrt",
+ "gmp_sqrtrm",
+ "gmp_strval",
+ "gmp_sub",
+ "gmp_xor",
+ "gmstrftime",
+ "gregoriantojd",
+ "gzclose",
+ "gzcompress",
+ "gzdeflate",
+ "gzencode",
+ "gzeof",
+ "gzfile",
+ "gzgetc",
+ "gzgets",
+ "gzgetss",
+ "gzinflate",
+ "gzopen",
+ "gzpassthru",
+ "gzputs",
+ "gzread",
+ "gzrewind",
+ "gzseek",
+ "gztell",
+ "gzuncompress",
+ "gzwrite",
+ "has_attribute",
+ "has_attributess",
+ "has_child_nodes",
+ "header",
+ "headers_sent",
+ "hebrev",
+ "hebrevc",
+ "hexdec",
+ "highlight_file",
+ "highlight_string",
+ "html_dump_mem",
+ "htmlentities",
+ "html_entity_decode",
+ "htmlspecialchars",
+ "HTTP_ACCEPT",
+ "HTTP_ACCEPT_CHARSET",
+ "HTTP_ACCEPT_LANGUAGE",
+ "HTTP_CONNECTION",
+ "HTTP_COOKIE_VARS",
+ "HTTP_ENCODING",
+ "HTTP_ENV_VARS",
+ "HTTP_GET_VARS",
+ "HTTP_HOST",
+ "HTTP_POST_FILES",
+ "HTTP_POST_VARS",
+ "HTTP_RAW_POST_DATA",
+ "HTTP_REFERER",
+ "HTTP_SERVER_VARS",
+ "HTTP_SESSION_VARS",
+ "HTTP_STATE_VARS",
+ "HTTP_USER_AGENT",
+ "hw_api_attribute",
+ "hw_api_content",
+ "hwapi_hgcsp",
+ "hw_api_object",
+ "hw_Array2Objrec",
+ "hw_changeobject",
+ "hw_Children",
+ "hw_ChildrenObj",
+ "hw_Close",
+ "hw_Connect",
+ "hw_connection_info",
+ "hw_Cp",
+ "hw_Deleteobject",
+ "hw_DocByAnchor",
+ "hw_DocByAnchorObj",
+ "hw_Document_Attributes",
+ "hw_Document_BodyTag",
+ "hw_Document_Content",
+ "hw_Document_SetContent",
+ "hw_Document_Size",
+ "hw_dummy",
+ "hw_EditText",
+ "hw_Error",
+ "hw_ErrorMsg",
+ "hw_Free_Document",
+ "hw_GetAnchors",
+ "hw_GetAnchorsObj",
+ "hw_GetAndLock",
+ "hw_GetChildColl",
+ "hw_GetChildCollObj",
+ "hw_GetChildDocColl",
+ "hw_GetChildDocCollObj",
+ "hw_GetObject",
+ "hw_GetObjectByQuery",
+ "hw_GetObjectByQueryColl",
+ "hw_GetObjectByQueryCollObj",
+ "hw_GetObjectByQueryObj",
+ "hw_GetParents",
+ "hw_GetParentsObj",
+ "hw_getrellink",
+ "hw_GetRemote",
+ "hw_GetRemoteChildren",
+ "hw_GetSrcByDestObj",
+ "hw_GetText",
+ "hw_getusername",
+ "hw_Identify",
+ "hw_InCollections",
+ "hw_Info",
+ "hw_InsColl",
+ "hw_InsDoc",
+ "hw_insertanchors",
+ "hw_InsertDocument",
+ "hw_InsertObject",
+ "hw_mapid",
+ "hw_Modifyobject",
+ "hw_Mv",
+ "hw_New_Document",
+ "hw_Objrec2Array",
+ "hw_Output_Document",
+ "hw_pConnect",
+ "hw_PipeDocument",
+ "hw_Root",
+ "hw_setlinkroot",
+ "hw_stat",
+ "hwstat",
+ "hw_Unlock",
+ "hw_Who",
+ "hypot",
+ "ibase_blob_add",
+ "ibase_blob_cancel",
+ "ibase_blob_close",
+ "ibase_blob_create",
+ "ibase_blob_echo",
+ "ibase_blob_get",
+ "ibase_blob_import",
+ "ibase_blob_info",
+ "ibase_blob_open",
+ "ibase_close",
+ "ibase_commit",
+ "ibase_connect",
+ "ibase_errmsg",
+ "ibase_execute",
+ "ibase_fetch_object",
+ "ibase_fetch_row",
+ "ibase_field_info",
+ "ibase_free_query",
+ "ibase_free_result",
+ "ibase_num_fields",
+ "ibase_pconnect",
+ "ibase_prepare",
+ "ibase_query",
+ "ibase_rollback",
+ "ibase_timefmt",
+ "ibase_trans",
+ "iconv",
+ "iconv_get_encoding",
+ "iconv_set_encoding",
+ "identify",
+ "if",
+ "ifx_affected_rows",
+ "ifx_blobinfile_mode",
+ "ifx_byteasvarchar",
+ "ifx_close",
+ "ifx_connect",
+ "ifx_copy_blob",
+ "ifx_create_blob",
+ "ifx_create_char",
+ "ifx_do",
+ "ifx_error",
+ "ifx_errormsg",
+ "ifx_fetch_row",
+ "ifx_fieldproperties",
+ "ifx_fieldtypes",
+ "ifx_free_blob",
+ "ifx_free_char",
+ "ifx_free_result",
+ "ifx_get_blob",
+ "ifx_get_char",
+ "ifx_getsqlca",
+ "ifx_htmltbl_result",
+ "ifx_nullformat",
+ "ifx_num_fields",
+ "ifx_num_rows",
+ "ifx_pconnect",
+ "ifx_prepare",
+ "ifx_query",
+ "ifx_textasvarchar",
+ "ifx_update_blob",
+ "ifx_update_char",
+ "ifxus_close_slob",
+ "ifxus_create_slob",
+ "ifxus_free_slob",
+ "ifxus_open_slob",
+ "ifxus_read_slob",
+ "ifxus_seek_slob",
+ "ifxus_tell_slob",
+ "ifxus_write_slob",
+ "ignore_user_abort",
+ "image2wbmp",
+ "imagealphablending",
+ "imagearc",
+ "imagechar",
+ "imagecharup",
+ "imagecolorallocate",
+ "imagecolorallocatealpha",
+ "imagecolorat",
+ "imagecolorclosest",
+ "imagecolorclosestalpha",
+ "imagecolorclosesthwb",
+ "imagecolordeallocate",
+ "imagecolorexact",
+ "imagecolorexactalpha",
+ "imagecolorresolve",
+ "imagecolorresolvealpha",
+ "imagecolorset",
+ "imagecolorsforindex",
+ "imagecolorstotal",
+ "imagecolortransparent",
+ "imagecopy",
+ "imagecopymerge",
+ "imagecopymergegray",
+ "imagecopyresampled",
+ "imagecopyresized",
+ "imagecreate",
+ "imagecreatefromgd",
+ "imagecreatefromgd2",
+ "imagecreatefromgd2part",
+ "imagecreatefromgif",
+ "imagecreatefromjpeg",
+ "imagecreatefrompng",
+ "imagecreatefromstring",
+ "imagecreatefromwbmp",
+ "imagecreatefromxbm",
+ "imagecreatefromxpm",
+ "imagecreatetruecolor",
+ "imagedashedline",
+ "imagedestroy",
+ "imageellipse",
+ "imagefill",
+ "imagefilledarc",
+ "imagefilledellipse",
+ "imagefilledpolygon",
+ "imagefilledrectangle",
+ "imagefilltoborder",
+ "imagefontheight",
+ "imagefontwidth",
+ "imageftbbox",
+ "imagefttext",
+ "imagegammacorrect",
+ "imagegd",
+ "imagegd2",
+ "imagegif",
+ "imageinterlace",
+ "imagejpeg",
+ "imageline",
+ "imageloadfont",
+ "imagepalettecopy",
+ "imagepng",
+ "imagepolygon",
+ "imagepsbbox",
+ "imagepscopyfont",
+ "imagepsencodefont",
+ "imagepsextendfont",
+ "imagepsfreefont",
+ "imagepsloadfont",
+ "imagepsslantfont",
+ "imagepstext",
+ "imagerectangle",
+ "imagerotate",
+ "imagesetbrush",
+ "imagesetpixel",
+ "imagesetstyle",
+ "imagesetthickness",
+ "imagesettile",
+ "imagestring",
+ "imagestringup",
+ "imagesx",
+ "imagesy",
+ "imagetruecolortopalette",
+ "imagettfbbox",
+ "imagettftext",
+ "imagetypes",
+ "image_type_to_mime_type",
+ "imagewbmp",
+ "imap_8bit",
+ "imap_alerts",
+ "imap_append",
+ "imap_base64",
+ "imap_binary",
+ "imap_body",
+ "imap_bodystruct",
+ "imap_check",
+ "imap_clearflag_full",
+ "imap_close",
+ "imap_createmailbox",
+ "imap_delete",
+ "imap_deletemailbox",
+ "imap_errors",
+ "imap_expunge",
+ "imap_fetchbody",
+ "imap_fetchheader",
+ "imap_fetch_overview",
+ "imap_fetchstructure",
+ "imap_getmailboxes",
+ "imap_get_quota",
+ "imap_get_quotaroot",
+ "imap_getsubscribed",
+ "imap_header",
+ "imap_headerinfo",
+ "imap_headers",
+ "imap_last_error",
+ "imap_list",
+ "imap_listmailbox",
+ "imap_listscan",
+ "imap_listsubscribed",
+ "imap_lsub",
+ "imap_mail",
+ "imap_mailboxmsginfo",
+ "imap_mail_compose",
+ "imap_mail_copy",
+ "imap_mail_move",
+ "imap_mime_header_decode",
+ "imap_msgno",
+ "imap_num_msg",
+ "imap_num_recent",
+ "imap_open",
+ "imap_ping",
+ "imap_qprint",
+ "imap_renamemailbox",
+ "imap_reopen",
+ "imap_rfc822_parse_adrlist",
+ "imap_rfc822_parse_headers",
+ "imap_rfc822_write_address",
+ "imap_scanmailbox",
+ "imap_search",
+ "imap_setacl",
+ "imap_setflag_full",
+ "imap_set_quota",
+ "imap_sort",
+ "imap_status",
+ "imap_subscribe",
+ "imap_thread",
+ "imap_uid",
+ "imap_undelete",
+ "imap_unsubscribe",
+ "imap_utf7_decode",
+ "imap_utf7_encode",
+ "imap_utf8",
+ "implode",
+ "import_request_variables",
+ "in_array",
+ "include",
+ "include_once",
+ "info",
+ "ingres_autocommit",
+ "ingres_close",
+ "ingres_commit",
+ "ingres_connect",
+ "ingres_fetch_array",
+ "ingres_fetch_object",
+ "ingres_fetch_row",
+ "ingres_field_length",
+ "ingres_field_name",
+ "ingres_field_nullable",
+ "ingres_field_precision",
+ "ingres_field_scale",
+ "ingres_field_type",
+ "ingres_num_fields",
+ "ingres_num_rows",
+ "ingres_pconnect",
+ "ingres_query",
+ "ingres_rollback",
+ "ini_alter",
+ "ini_get",
+ "ini_get_all",
+ "ini_restore",
+ "ini_set",
+ "insert",
+ "insertanchor",
+ "insert_before",
+ "insertcollection",
+ "insertdocument",
+ "int",
+ "internal_subset",
+ "intval",
+ "ip2long",
+ "iptcembed",
+ "iptcparse",
+ "ircg_channel_mode",
+ "ircg_disconnect",
+ "ircg_fetch_error_msg",
+ "ircg_get_username",
+ "ircg_html_encode",
+ "ircg_ignore_add",
+ "ircg_ignore_del",
+ "ircg_is_conn_alive",
+ "ircg_join",
+ "ircg_kick",
+ "ircg_lookup_format_messages",
+ "ircg_msg",
+ "ircg_nick",
+ "ircg_nickname_escape",
+ "ircg_nickname_unescape",
+ "ircg_notice",
+ "ircg_part",
+ "ircg_pconnect",
+ "ircg_register_format_messages",
+ "ircg_set_current",
+ "ircg_set_file",
+ "ircg_set_on_die",
+ "ircg_topic",
+ "ircg_whois",
+ "is_a",
+ "is_array",
+ "is_blank_node",
+ "is_bool",
+ "is_callable",
+ "is_dir",
+ "is_double",
+ "is_executable",
+ "is_file",
+ "is_finite",
+ "is_float",
+ "is_infinite",
+ "is_int",
+ "is_integer",
+ "is_link",
+ "is_long",
+ "is_nan",
+ "is_null",
+ "is_numeric",
+ "is_object",
+ "is_readable",
+ "is_real",
+ "is_resource",
+ "is_scalar",
+ "isset",
+ "is_string",
+ "is_subclass_of",
+ "is_uploaded_file",
+ "is_writable",
+ "is_writeable",
+ "java_last_exception_clear",
+ "java_last_exception_get",
+ "jddayofweek",
+ "jdmonthname",
+ "jdtofrench",
+ "jdtogregorian",
+ "jdtojewish",
+ "jdtojulian",
+ "jdtounix",
+ "jewishtojd",
+ "join",
+ "jpeg2wbmp",
+ "juliantojd",
+ "key",
+ "krsort",
+ "ksort",
+ "langdepvalue",
+ "last_child",
+ "lcg_value",
+ "ldap_8859_to_t61",
+ "ldap_add",
+ "ldap_bind",
+ "ldap_close",
+ "ldap_compare",
+ "ldap_connect",
+ "ldap_count_entries",
+ "ldap_delete",
+ "ldap_dn2ufn",
+ "ldap_err2str",
+ "ldap_errno",
+ "ldap_error",
+ "ldap_explode_dn",
+ "ldap_first_attribute",
+ "ldap_first_entry",
+ "ldap_first_reference",
+ "ldap_free_result",
+ "ldap_get_attributes",
+ "ldap_get_dn",
+ "ldap_get_entries",
+ "ldap_get_option",
+ "ldap_get_values",
+ "ldap_get_values_len",
+ "ldap_list",
+ "ldap_mod_add",
+ "ldap_mod_del",
+ "ldap_modify",
+ "ldap_mod_replace",
+ "ldap_next_attribute",
+ "ldap_next_entry",
+ "ldap_next_reference",
+ "ldap_parse_reference",
+ "ldap_parse_result",
+ "ldap_read",
+ "ldap_rename",
+ "ldap_search",
+ "ldap_set_option",
+ "ldap_set_rebind_proc",
+ "ldap_sort",
+ "ldap_start_tls",
+ "ldap_t61_to_8859",
+ "ldap_unbind",
+ "levenshtein",
+ "__LINE__",
+ "link",
+ "linkinfo",
+ "list",
+ "localeconv",
+ "localtime",
+ "lock",
+ "log",
+ "log10",
+ "log1p",
+ "long2ip",
+ "lstat",
+ "ltrim",
+ "mail",
+ "mailparse_determine_best_xfer_encoding",
+ "mailparse_msg_create",
+ "mailparse_msg_extract_part",
+ "mailparse_msg_extract_part_file",
+ "mailparse_msg_free",
+ "mailparse_msg_get_part",
+ "mailparse_msg_get_part_data",
+ "mailparse_msg_get_structure",
+ "mailparse_msg_parse",
+ "mailparse_msg_parse_file",
+ "mailparse_rfc822_parse_addresses",
+ "mailparse_stream_encode",
+ "mailparse_uudecode_all",
+ "main",
+ "max",
+ "mb_convert_case",
+ "mb_convert_encoding",
+ "mb_convert_kana",
+ "mb_convert_variables",
+ "mb_decode_mimeheader",
+ "mb_decode_numericentity",
+ "mb_detect_encoding",
+ "mb_detect_order",
+ "mb_encode_mimeheader",
+ "mb_encode_numericentity",
+ "mb_ereg",
+ "mb_eregi",
+ "mb_eregi_replace",
+ "mb_ereg_match",
+ "mb_ereg_replace",
+ "mb_ereg_search",
+ "mb_ereg_search_getpos",
+ "mb_ereg_search_getregs",
+ "mb_ereg_search_init",
+ "mb_ereg_search_pos",
+ "mb_ereg_search_regs",
+ "mb_ereg_search_setpos",
+ "mb_get_info",
+ "mb_http_input",
+ "mb_http_output",
+ "mb_internal_encoding",
+ "mb_language",
+ "mb_output_handler",
+ "mb_parse_str",
+ "mb_preferred_mime_name",
+ "mb_regex_encoding",
+ "mb_regex_set_options",
+ "mb_send_mail",
+ "mb_split",
+ "mb_strcut",
+ "mb_strimwidth",
+ "mb_strlen",
+ "mb_strpos",
+ "mb_strrpos",
+ "mb_strtolower",
+ "mb_strtoupper",
+ "mb_strwidth",
+ "mb_substitute_character",
+ "mb_substr",
+ "mb_substr_count",
+ "mcal_append_event",
+ "mcal_close",
+ "mcal_create_calendar",
+ "mcal_date_compare",
+ "mcal_date_valid",
+ "mcal_day_of_week",
+ "mcal_day_of_year",
+ "mcal_days_in_month",
+ "mcal_delete_calendar",
+ "mcal_delete_event",
+ "mcal_event_add_attribute",
+ "mcal_event_init",
+ "mcal_event_set_alarm",
+ "mcal_event_set_category",
+ "mcal_event_set_class",
+ "mcal_event_set_description",
+ "mcal_event_set_end",
+ "mcal_event_set_recur_daily",
+ "mcal_event_set_recur_monthly_mday",
+ "mcal_event_set_recur_monthly_wday",
+ "mcal_event_set_recur_none",
+ "mcal_event_set_recur_weekly",
+ "mcal_event_set_recur_yearly",
+ "mcal_event_set_start",
+ "mcal_event_set_title",
+ "mcal_expunge",
+ "mcal_fetch_current_stream_event",
+ "mcal_fetch_event",
+ "mcal_is_leap_year",
+ "mcal_list_alarms",
+ "mcal_list_events",
+ "mcal_next_recurrence",
+ "mcal_open",
+ "mcal_popen",
+ "mcal_rename_calendar",
+ "mcal_reopen",
+ "mcal_snooze",
+ "mcal_store_event",
+ "mcal_time_valid",
+ "mcal_week_of_year",
+ "mcrypt_cbc",
+ "mcrypt_cfb",
+ "mcrypt_create_iv",
+ "mcrypt_decrypt",
+ "mcrypt_ecb",
+ "mcrypt_enc_get_algorithms_name",
+ "mcrypt_enc_get_block_size",
+ "mcrypt_enc_get_iv_size",
+ "mcrypt_enc_get_key_size",
+ "mcrypt_enc_get_modes_name",
+ "mcrypt_enc_get_supported_key_sizes",
+ "mcrypt_enc_is_block_algorithm",
+ "mcrypt_enc_is_block_algorithm_mode",
+ "mcrypt_enc_is_block_mode",
+ "mcrypt_encrypt",
+ "mcrypt_enc_self_test",
+ "mcrypt_generic",
+ "mcrypt_generic_deinit",
+ "mcrypt_generic_end",
+ "mcrypt_generic_init",
+ "mcrypt_get_block_size",
+ "mcrypt_get_cipher_name",
+ "mcrypt_get_iv_size",
+ "mcrypt_get_key_size",
+ "mcrypt_list_algorithms",
+ "mcrypt_list_modes",
+ "mcrypt_module_close",
+ "mcrypt_module_get_algo_block_size",
+ "mcrypt_module_get_algo_key_size",
+ "mcrypt_module_get_supported_key_sizes",
+ "mcrypt_module_is_block_algorithm",
+ "mcrypt_module_is_block_algorithm_mode",
+ "mcrypt_module_is_block_mode",
+ "mcrypt_module_open",
+ "mcrypt_module_self_test",
+ "mcrypt_ofb",
+ "mcve_adduser",
+ "mcve_adduserarg",
+ "mcve_bt",
+ "mcve_checkstatus",
+ "mcve_chkpwd",
+ "mcve_chngpwd",
+ "mcve_completeauthorizations",
+ "mcve_connect",
+ "mcve_connectionerror",
+ "mcve_deleteresponse",
+ "mcve_deletetrans",
+ "mcve_deleteusersetup",
+ "mcve_deluser",
+ "mcve_destroyconn",
+ "mcve_destroyengine",
+ "mcve_disableuser",
+ "mcve_edituser",
+ "mcve_enableuser",
+ "mcve_force",
+ "mcve_getcell",
+ "mcve_getcellbynum",
+ "mcve_getcommadelimited",
+ "mcve_getheader",
+ "mcve_getuserarg",
+ "mcve_getuserparam",
+ "mcve_gft",
+ "mcve_gl",
+ "mcve_gut",
+ "mcve_initconn",
+ "mcve_initengine",
+ "mcve_initusersetup",
+ "mcve_iscommadelimited",
+ "mcve_liststats",
+ "mcve_listusers",
+ "mcve_maxconntimeout",
+ "mcve_monitor",
+ "mcve_numcolumns",
+ "mcve_numrows",
+ "mcve_override",
+ "mcve_parsecommadelimited",
+ "mcve_ping",
+ "mcve_preauth",
+ "mcve_preauthcompletion",
+ "mcve_qc",
+ "mcve_responseparam",
+ "mcve_return",
+ "mcve_returncode",
+ "mcve_returnstatus",
+ "mcve_sale",
+ "mcve_setblocking",
+ "mcve_setdropfile",
+ "mcve_setip",
+ "mcve_setssl",
+ "mcve_settimeout",
+ "mcve_settle",
+ "mcve_text_avs",
+ "mcve_text_code",
+ "mcve_text_cv",
+ "mcve_transactionauth",
+ "mcve_transactionavs",
+ "mcve_transactionbatch",
+ "mcve_transactioncv",
+ "mcve_transactionid",
+ "mcve_transactionitem",
+ "mcve_transactionssent",
+ "mcve_transactiontext",
+ "mcve_transinqueue",
+ "mcve_transnew",
+ "mcve_transparam",
+ "mcve_transsend",
+ "mcve_ub",
+ "mcve_uwait",
+ "mcve_verifyconnection",
+ "mcve_verifysslcert",
+ "mcve_void",
+ "md5",
+ "md5_file",
+ "mdecrypt_generic",
+ "memory_get_usage",
+ "metaphone",
+ "method_exists",
+ "mhash",
+ "mhash_count",
+ "mhash_get_block_size",
+ "mhash_get_hash_name",
+ "mhash_keygen_s2k",
+ "microtime",
+ "mime_content_type",
+ "mimetype",
+ "min",
+ "ming_setcubicthreshold",
+ "ming_setscale",
+ "ming_useswfversion",
+ "mkdir",
+ "mktime",
+ "money_format",
+ "move",
+ "movePen",
+ "movePenTo",
+ "moveTo",
+ "move_uploaded_file",
+ "msession_connect",
+ "msession_count",
+ "msession_create",
+ "msession_destroy",
+ "msession_disconnect",
+ "msession_find",
+ "msession_get",
+ "msession_get_array",
+ "msession_getdata",
+ "msession_inc",
+ "msession_list",
+ "msession_listvar",
+ "msession_lock",
+ "msession_plugin",
+ "msession_randstr",
+ "msession_set",
+ "msession_set_array",
+ "msession_setdata",
+ "msession_timeout",
+ "msession_uniq",
+ "msession_unlock",
+ "msg_get_queue",
+ "msg_receive",
+ "msg_remove_queue",
+ "msg_send",
+ "msg_set_queue",
+ "msg_stat_queue",
+ "msql",
+ "msql_affected_rows",
+ "msql_close",
+ "msql_connect",
+ "msql_create_db",
+ "msql_createdb",
+ "msql_data_seek",
+ "msql_dbname",
+ "msql_drop_db",
+ "msql_dropdb",
+ "msql_error",
+ "msql_fetch_array",
+ "msql_fetch_field",
+ "msql_fetch_object",
+ "msql_fetch_row",
+ "msql_fieldflags",
+ "msql_fieldlen",
+ "msql_fieldname",
+ "msql_field_seek",
+ "msql_fieldtable",
+ "msql_fieldtype",
+ "msql_free_result",
+ "msql_freeresult",
+ "msql_list_dbs",
+ "msql_listdbs",
+ "msql_list_fields",
+ "msql_listfields",
+ "msql_list_tables",
+ "msql_listtables",
+ "msql_num_fields",
+ "msql_numfields",
+ "msql_num_rows",
+ "msql_numrows",
+ "msql_pconnect",
+ "msql_query",
+ "msql_regcase",
+ "msql_result",
+ "msql_select_db",
+ "msql_selectdb",
+ "msql_tablename",
+ "mssql_bind",
+ "mssql_close",
+ "mssql_connect",
+ "mssql_data_seek",
+ "mssql_execute",
+ "mssql_fetch_array",
+ "mssql_fetch_assoc",
+ "mssql_fetch_batch",
+ "mssql_fetch_field",
+ "mssql_fetch_object",
+ "mssql_fetch_row",
+ "mssql_field_length",
+ "mssql_field_name",
+ "mssql_field_seek",
+ "mssql_field_type",
+ "mssql_free_result",
+ "mssql_free_statement",
+ "mssql_get_last_message",
+ "mssql_guid_string",
+ "mssql_init",
+ "mssql_min_error_severity",
+ "mssql_min_message_severity",
+ "mssql_next_result",
+ "mssql_num_fields",
+ "mssql_num_rows",
+ "mssql_pconnect",
+ "mssql_query",
+ "mssql_result",
+ "mssql_rows_affected",
+ "mssql_select_db",
+ "mt_getrandmax",
+ "mt_rand",
+ "mt_srand",
+ "multColor",
+ "muscat_close",
+ "muscat_get",
+ "muscat_give",
+ "muscat_setup",
+ "muscat_setup_net",
+ "mysql_affected_rows",
+ "mysql_change_user",
+ "mysql_client_encoding",
+ "mysql_close",
+ "mysql_connect",
+ "mysql_create_db",
+ "mysql_data_seek",
+ "mysql_db_name",
+ "mysql_db_query",
+ "mysql_drop_db",
+ "mysql_errno",
+ "mysql_error",
+ "mysql_escape_string",
+ "mysql_fetch_array",
+ "mysql_fetch_assoc",
+ "mysql_fetch_field",
+ "mysql_fetch_lengths",
+ "mysql_fetch_object",
+ "mysql_fetch_row",
+ "mysql_field_flags",
+ "mysql_field_len",
+ "mysql_field_name",
+ "mysql_field_seek",
+ "mysql_field_table",
+ "mysql_field_type",
+ "mysql_free_result",
+ "mysql_get_client_info",
+ "mysql_get_host_info",
+ "mysql_get_proto_info",
+ "mysql_get_server_info",
+ "mysql_info",
+ "mysql_insert_id",
+ "mysql_list_dbs",
+ "mysql_list_fields",
+ "mysql_list_processes",
+ "mysql_list_tables",
+ "mysql_num_fields",
+ "mysql_num_rows",
+ "mysql_pconnect",
+ "mysql_ping",
+ "mysql_query",
+ "mysql_real_escape_string",
+ "mysql_result",
+ "mysql_select_db",
+ "mysql_stat",
+ "mysql_tablename",
+ "mysql_thread_id",
+ "mysql_unbuffered_query",
+ "name",
+ "natcasesort",
+ "natsort",
+ "ncurses_addch",
+ "ncurses_addchnstr",
+ "ncurses_addchstr",
+ "ncurses_addnstr",
+ "ncurses_addstr",
+ "ncurses_assume_default_colors",
+ "ncurses_attroff",
+ "ncurses_attron",
+ "ncurses_attrset",
+ "ncurses_baudrate",
+ "ncurses_beep",
+ "ncurses_bkgd",
+ "ncurses_bkgdset",
+ "ncurses_border",
+ "ncurses_can_change_color",
+ "ncurses_cbreak",
+ "ncurses_clear",
+ "ncurses_clrtobot",
+ "ncurses_clrtoeol",
+ "ncurses_color_set",
+ "ncurses_curs_set",
+ "ncurses_define_key",
+ "ncurses_def_prog_mode",
+ "ncurses_def_shell_mode",
+ "ncurses_delay_output",
+ "ncurses_delch",
+ "ncurses_deleteln",
+ "ncurses_delwin",
+ "ncurses_doupdate",
+ "ncurses_echo",
+ "ncurses_echochar",
+ "ncurses_end",
+ "ncurses_erase",
+ "ncurses_erasechar",
+ "ncurses_filter",
+ "ncurses_flash",
+ "ncurses_flushinp",
+ "ncurses_getch",
+ "ncurses_getmouse",
+ "ncurses_halfdelay",
+ "ncurses_has_colors",
+ "ncurses_has_ic",
+ "ncurses_has_il",
+ "ncurses_has_key",
+ "ncurses_hline",
+ "ncurses_inch",
+ "ncurses_init",
+ "ncurses_init_color",
+ "ncurses_init_pair",
+ "ncurses_insch",
+ "ncurses_insdelln",
+ "ncurses_insertln",
+ "ncurses_insstr",
+ "ncurses_instr",
+ "ncurses_isendwin",
+ "ncurses_keyok",
+ "ncurses_killchar",
+ "ncurses_longname",
+ "ncurses_mouseinterval",
+ "ncurses_mousemask",
+ "ncurses_move",
+ "ncurses_mvaddch",
+ "ncurses_mvaddchnstr",
+ "ncurses_mvaddchstr",
+ "ncurses_mvaddnstr",
+ "ncurses_mvaddstr",
+ "ncurses_mvcur",
+ "ncurses_mvdelch",
+ "ncurses_mvgetch",
+ "ncurses_mvhline",
+ "ncurses_mvinch",
+ "ncurses_mvvline",
+ "ncurses_mvwaddstr",
+ "ncurses_napms",
+ "ncurses_newwin",
+ "ncurses_nl",
+ "ncurses_nocbreak",
+ "ncurses_noecho",
+ "ncurses_nonl",
+ "ncurses_noqiflush",
+ "ncurses_noraw",
+ "ncurses_putp",
+ "ncurses_qiflush",
+ "ncurses_raw",
+ "ncurses_refresh",
+ "ncurses_resetty",
+ "ncurses_savetty",
+ "ncurses_scr_dump",
+ "ncurses_scr_init",
+ "ncurses_scrl",
+ "ncurses_scr_restore",
+ "ncurses_scr_set",
+ "ncurses_slk_attr",
+ "ncurses_slk_attroff",
+ "ncurses_slk_attron",
+ "ncurses_slk_attrset",
+ "ncurses_slk_clear",
+ "ncurses_slk_color",
+ "ncurses_slk_init",
+ "ncurses_slk_noutrefresh",
+ "ncurses_slk_refresh",
+ "ncurses_slk_restore",
+ "ncurses_slk_touch",
+ "ncurses_standend",
+ "ncurses_standout",
+ "ncurses_start_color",
+ "ncurses_termattrs",
+ "ncurses_termname",
+ "ncurses_timeout",
+ "ncurses_typeahead",
+ "ncurses_ungetch",
+ "ncurses_ungetmouse",
+ "ncurses_use_default_colors",
+ "ncurses_use_env",
+ "ncurses_use_extended_names",
+ "ncurses_vidattr",
+ "ncurses_vline",
+ "ncurses_wrefresh",
+ "new",
+ "next",
+ "nextframe",
+ "next_sibling",
+ "ngettext",
+ "nl2br",
+ "nl_langinfo",
+ "node_name",
+ "node_type",
+ "node_value",
+ "notations",
+ "notes_body",
+ "notes_copy_db",
+ "notes_create_db",
+ "notes_create_note",
+ "notes_drop_db",
+ "notes_find_note",
+ "notes_header_info",
+ "notes_list_msgs",
+ "notes_mark_read",
+ "notes_mark_unread",
+ "notes_nav_create",
+ "notes_search",
+ "notes_unread",
+ "notes_version",
+ "NULL",
+ "number_format",
+ "ob_clean",
+ "ob_end_clean",
+ "ob_end_flush",
+ "ob_flush",
+ "ob_get_contents",
+ "ob_get_length",
+ "ob_get_level",
+ "ob_get_status",
+ "ob_gzhandler",
+ "ob_iconv_handler",
+ "ob_implicit_flush",
+ "object",
+ "objectbyanchor",
+ "ob_start",
+ "ocibindbyname",
+ "ocicancel",
+ "OCICollAppend",
+ "ocicollassign",
+ "ocicollassignelem",
+ "ocicollgetelem",
+ "ocicollmax",
+ "ocicollsize",
+ "ocicolltrim",
+ "ocicolumnisnull",
+ "ocicolumnname",
+ "ocicolumnprecision",
+ "ocicolumnscale",
+ "ocicolumnsize",
+ "ocicolumntype",
+ "ocicolumntyperaw",
+ "ocicommit",
+ "ocidefinebyname",
+ "ocierror",
+ "ociexecute",
+ "ocifetch",
+ "ocifetchinto",
+ "ocifetchstatement",
+ "ocifreecollection",
+ "ocifreecursor",
+ "OCIFreeDesc",
+ "ocifreestatement",
+ "ociinternaldebug",
+ "ociloadlob",
+ "ocilogoff",
+ "ocilogon",
+ "ocinewcollection",
+ "ocinewcursor",
+ "ocinewdescriptor",
+ "ocinlogon",
+ "ocinumcols",
+ "ociparse",
+ "ociplogon",
+ "ociresult",
+ "ocirollback",
+ "ocirowcount",
+ "ocisavelob",
+ "ocisavelobfile",
+ "ociserverversion",
+ "ocisetprefetch",
+ "ocistatementtype",
+ "ociwritelobtofile",
+ "octdec",
+ "odbc_autocommit",
+ "odbc_binmode",
+ "odbc_close",
+ "odbc_close_all",
+ "odbc_columnprivileges",
+ "odbc_columns",
+ "odbc_commit",
+ "odbc_connect",
+ "odbc_cursor",
+ "odbc_data_source",
+ "odbc_do",
+ "odbc_error",
+ "odbc_errormsg",
+ "odbc_exec",
+ "odbc_execute",
+ "odbc_fetch_array",
+ "odbc_fetch_into",
+ "odbc_fetch_object",
+ "odbc_fetch_row",
+ "odbc_field_len",
+ "odbc_field_name",
+ "odbc_field_num",
+ "odbc_field_precision",
+ "odbc_field_scale",
+ "odbc_field_type",
+ "odbc_foreignkeys",
+ "odbc_free_result",
+ "odbc_gettypeinfo",
+ "odbc_longreadlen",
+ "odbc_next_result",
+ "odbc_num_fields",
+ "odbc_num_rows",
+ "odbc_pconnect",
+ "odbc_prepare",
+ "odbc_primarykeys",
+ "odbc_procedurecolumns",
+ "odbc_procedures",
+ "odbc_result",
+ "odbc_result_all",
+ "odbc_rollback",
+ "odbc_setoption",
+ "odbc_specialcolumns",
+ "odbc_statistics",
+ "odbc_tableprivileges",
+ "odbc_tables",
+ "opendir",
+ "openlog",
+ "openssl_csr_export",
+ "openssl_csr_export_to_file",
+ "openssl_csr_new",
+ "openssl_csr_sign",
+ "openssl_error_string",
+ "openssl_free_key",
+ "openssl_get_privatekey",
+ "openssl_get_publickey",
+ "openssl_open",
+ "openssl_pkcs7_decrypt",
+ "openssl_pkcs7_encrypt",
+ "openssl_pkcs7_sign",
+ "openssl_pkcs7_verify",
+ "openssl_pkey_export",
+ "openssl_pkey_export_to_file",
+ "openssl_pkey_get_private",
+ "openssl_pkey_get_public",
+ "openssl_pkey_new",
+ "openssl_private_decrypt",
+ "openssl_private_encrypt",
+ "openssl_public_decrypt",
+ "openssl_public_encrypt",
+ "openssl_seal",
+ "openssl_sign",
+ "openssl_verify",
+ "openssl_x509_check_private_key",
+ "openssl_x509_checkpurpose",
+ "openssl_x509_export",
+ "openssl_x509_export_to_file",
+ "openssl_x509_free",
+ "openssl_x509_parse",
+ "openssl_x509_read",
+ "ora_bind",
+ "ora_close",
+ "ora_columnname",
+ "ora_columnsize",
+ "ora_columntype",
+ "ora_commit",
+ "ora_commitoff",
+ "ora_commiton",
+ "ora_do",
+ "ora_error",
+ "ora_errorcode",
+ "ora_exec",
+ "ora_fetch",
+ "ora_fetch_into",
+ "ora_getcolumn",
+ "ora_logoff",
+ "ora_logon",
+ "ora_numcols",
+ "ora_numrows",
+ "ora_open",
+ "ora_parse",
+ "ora_plogon",
+ "ora_rollback",
+ "ord",
+ "output",
+ "overload",
+ "ovrimos_close",
+ "ovrimos_commit",
+ "ovrimos_connect",
+ "ovrimos_cursor",
+ "ovrimos_exec",
+ "ovrimos_execute",
+ "ovrimos_fetch_into",
+ "ovrimos_fetch_row",
+ "ovrimos_field_len",
+ "ovrimos_field_name",
+ "ovrimos_field_num",
+ "ovrimos_field_type",
+ "ovrimos_free_result",
+ "ovrimos_longreadlen",
+ "ovrimos_num_fields",
+ "ovrimos_num_rows",
+ "ovrimos_prepare",
+ "ovrimos_result",
+ "ovrimos_result_all",
+ "ovrimos_rollback",
+ "owner_document",
+ "pack",
+ "parent_node",
+ "parents",
+ "parse_ini_file",
+ "parse_str",
+ "parse_url",
+ "passthru",
+ "pathinfo",
+ "PATH_TRANSLATED",
+ "pclose",
+ "pcntl_exec",
+ "pcntl_fork",
+ "pcntl_signal",
+ "pcntl_waitpid",
+ "pcntl_wexitstatus",
+ "pcntl_wifexited",
+ "pcntl_wifsignaled",
+ "pcntl_wifstopped",
+ "pcntl_wstopsig",
+ "pcntl_wtermsig",
+ "pdf_add_annotation",
+ "pdf_add_bookmark",
+ "pdf_add_launchlink",
+ "pdf_add_locallink",
+ "pdf_add_note",
+ "pdf_add_outline",
+ "pdf_add_pdflink",
+ "pdf_add_thumbnail",
+ "pdf_add_weblink",
+ "pdf_arc",
+ "pdf_arcn",
+ "pdf_attach_file",
+ "pdf_begin_page",
+ "pdf_begin_pattern",
+ "pdf_begin_template",
+ "pdf_circle",
+ "pdf_clip",
+ "pdf_close",
+ "pdf_close_image",
+ "pdf_closepath",
+ "pdf_closepath_fill_stroke",
+ "pdf_closepath_stroke",
+ "pdf_close_pdi",
+ "pdf_close_pdi_page",
+ "pdf_concat",
+ "pdf_continue_text",
+ "pdf_curveto",
+ "pdf_delete",
+ "pdf_end_page",
+ "pdf_endpath",
+ "pdf_end_pattern",
+ "pdf_end_template",
+ "pdf_fill",
+ "pdf_fill_stroke",
+ "pdf_findfont",
+ "pdf_get_buffer",
+ "pdf_get_font",
+ "pdf_get_fontname",
+ "pdf_get_fontsize",
+ "pdf_get_image_height",
+ "pdf_get_image_width",
+ "pdf_get_majorversion",
+ "pdf_get_minorversion",
+ "pdf_get_parameter",
+ "pdf_get_pdi_parameter",
+ "pdf_get_pdi_value",
+ "pdf_get_value",
+ "pdf_initgraphics",
+ "pdf_lineto",
+ "pdf_makespotcolor",
+ "pdf_moveto",
+ "pdf_new",
+ "pdf_open",
+ "pdf_open_CCITT",
+ "pdf_open_file",
+ "pdf_open_gif",
+ "pdf_open_image",
+ "pdf_open_image_file",
+ "pdf_open_jpeg",
+ "pdf_open_memory_image",
+ "pdf_open_pdi",
+ "pdf_open_pdi_page",
+ "pdf_open_png",
+ "pdf_open_tiff",
+ "pdf_place_image",
+ "pdf_place_pdi_page",
+ "pdf_rect",
+ "pdf_restore",
+ "pdf_rotate",
+ "pdf_save",
+ "pdf_scale",
+ "pdf_set_border_color",
+ "pdf_set_border_dash",
+ "pdf_set_border_style",
+ "pdf_set_char_spacing",
+ "pdf_setcolor",
+ "pdf_setdash",
+ "pdf_set_duration",
+ "pdf_setflat",
+ "pdf_set_font",
+ "pdf_setfont",
+ "pdf_setgray",
+ "pdf_setgray_fill",
+ "pdf_setgray_stroke",
+ "pdf_set_horiz_scaling",
+ "pdf_set_info",
+ "pdf_set_info_author",
+ "pdf_set_info_creator",
+ "pdf_set_info_keywords",
+ "pdf_set_info_subject",
+ "pdf_set_info_title",
+ "pdf_set_leading",
+ "pdf_setlinecap",
+ "pdf_setlinejoin",
+ "pdf_setlinewidth",
+ "pdf_setmatrix",
+ "pdf_setmiterlimit",
+ "pdf_set_parameter",
+ "pdf_setpolydash",
+ "pdf_setrgbcolor",
+ "pdf_setrgbcolor_fill",
+ "pdf_setrgbcolor_stroke",
+ "pdf_set_text_matrix",
+ "pdf_set_text_pos",
+ "pdf_set_text_rendering",
+ "pdf_set_text_rise",
+ "pdf_set_value",
+ "pdf_set_word_spacing",
+ "pdf_show",
+ "pdf_show_boxed",
+ "pdf_show_xy",
+ "pdf_skew",
+ "pdf_stringwidth",
+ "pdf_stroke",
+ "pdf_translate",
+ "PEAR_EXTENSION_DIR",
+ "PEAR_INSTALL_DIR",
+ "pfpro_cleanup",
+ "pfpro_init",
+ "pfpro_process",
+ "pfpro_process_raw",
+ "pfpro_version",
+ "pfsockopen",
+ "pg_affected_rows",
+ "pg_cancel_query",
+ "pg_client_encoding",
+ "pg_close",
+ "pg_connect",
+ "pg_connection_busy",
+ "pg_connection_reset",
+ "pg_connection_status",
+ "pg_convert",
+ "pg_copy_from",
+ "pg_copy_to",
+ "pg_dbname",
+ "pg_delete",
+ "pg_end_copy",
+ "pg_escape_bytea",
+ "pg_escape_string",
+ "pg_fetch_all",
+ "pg_fetch_array",
+ "pg_fetch_assoc",
+ "pg_fetch_object",
+ "pg_fetch_result",
+ "pg_fetch_row",
+ "pg_field_is_null",
+ "pg_field_name",
+ "pg_field_num",
+ "pg_field_prtlen",
+ "pg_field_size",
+ "pg_field_type",
+ "pg_free_result",
+ "pg_get_notify",
+ "pg_get_pid",
+ "pg_get_result",
+ "pg_host",
+ "pg_insert",
+ "pg_last_error",
+ "pg_last_notice",
+ "pg_last_oid",
+ "pg_lo_close",
+ "pg_lo_create",
+ "pg_lo_export",
+ "pg_lo_import",
+ "pg_lo_open",
+ "pg_lo_read",
+ "pg_lo_read_all",
+ "pg_lo_seek",
+ "pg_lo_tell",
+ "pg_lo_unlink",
+ "pg_lo_write",
+ "pg_meta_data",
+ "pg_num_fields",
+ "pg_num_rows",
+ "pg_options",
+ "pg_pconnect",
+ "pg_ping",
+ "pg_port",
+ "pg_put_line",
+ "pg_query",
+ "pg_result_error",
+ "pg_result_seek",
+ "pg_result_status",
+ "pg_select",
+ "pg_send_query",
+ "pg_set_client_encoding",
+ "pg_trace",
+ "pg_tty",
+ "pg_unescape_bytea",
+ "pg_untrace",
+ "pg_update",
+ "PHP_BINDIR",
+ "PHP_CONFIG_FILE_PATH",
+ "phpcredits",
+ "PHP_DATADIR",
+ "PHP_ERRMSG",
+ "PHP_EXTENSION_DIR",
+ "phpinfo",
+ "php_ini_scanned_files",
+ "PHP_LIBDIR",
+ "PHP_LOCALSTATEDIR",
+ "php_logo_guid",
+ "PHP_OS",
+ "PHP_OUTPUT_HANDLER_CONT",
+ "PHP_OUTPUT_HANDLER_END",
+ "PHP_OUTPUT_HANDLER_START",
+ "php_sapi_name",
+ "PHP_SELF",
+ "PHP_SYSCONFDIR",
+ "php_uname",
+ "phpversion",
+ "PHP_VERSION",
+ "pi",
+ "png2wbmp",
+ "popen",
+ "pos",
+ "posix_ctermid",
+ "posix_getcwd",
+ "posix_getegid",
+ "posix_geteuid",
+ "posix_getgid",
+ "posix_getgrgid",
+ "posix_getgrnam",
+ "posix_getgroups",
+ "posix_getlogin",
+ "posix_getpgid",
+ "posix_getpgrp",
+ "posix_getpid",
+ "posix_getppid",
+ "posix_getpwnam",
+ "posix_getpwuid",
+ "posix_getrlimit",
+ "posix_getsid",
+ "posix_getuid",
+ "posix_isatty",
+ "posix_kill",
+ "posix_mkfifo",
+ "posix_setegid",
+ "posix_seteuid",
+ "posix_setgid",
+ "posix_setpgid",
+ "posix_setsid",
+ "posix_setuid",
+ "posix_times",
+ "posix_ttyname",
+ "posix_uname",
+ "_POST",
+ "pow",
+ "prefix",
+ "preg_grep",
+ "preg_match",
+ "preg_match_all",
+ "preg_quote",
+ "preg_replace",
+ "preg_replace_callback",
+ "preg_split",
+ "prev",
+ "previous_sibling",
+ "print",
+ "printer_abort",
+ "printer_close",
+ "printer_create_brush",
+ "printer_create_dc",
+ "printer_create_font",
+ "printer_create_pen",
+ "printer_delete_brush",
+ "printer_delete_dc",
+ "printer_delete_font",
+ "printer_delete_pen",
+ "printer_draw_bmp",
+ "printer_draw_chord",
+ "printer_draw_elipse",
+ "printer_draw_line",
+ "printer_draw_pie",
+ "printer_draw_rectangle",
+ "printer_draw_roundrect",
+ "printer_draw_text",
+ "printer_end_doc",
+ "printer_end_page",
+ "printer_get_option",
+ "printer_list",
+ "printer_logical_fontheight",
+ "printer_open",
+ "printer_select_brush",
+ "printer_select_font",
+ "printer_select_pen",
+ "printer_set_option",
+ "printer_start_doc",
+ "printer_start_page",
+ "printer_write",
+ "printf",
+ "print_r",
+ "private",
+ "proc_close",
+ "process",
+ "proc_open",
+ "protected",
+ "pspell_add_to_personal",
+ "pspell_add_to_session",
+ "pspell_check",
+ "pspell_clear_session",
+ "pspell_config_create",
+ "pspell_config_ignore",
+ "pspell_config_mode",
+ "pspell_config_personal",
+ "pspell_config_repl",
+ "pspell_config_runtogether",
+ "pspell_config_save_repl",
+ "pspell_new",
+ "pspell_new_config",
+ "pspell_new_personal",
+ "pspell_save_wordlist",
+ "pspell_store_replacement",
+ "pspell_suggest",
+ "public",
+ "public_id",
+ "putenv",
+ "qdom_error",
+ "qdom_tree",
+ "QUERY_STRING",
+ "quoted_printable_decode",
+ "quotemeta",
+ "rad2deg",
+ "rand",
+ "range",
+ "rawurldecode",
+ "rawurlencode",
+ "read",
+ "readdir",
+ "read_exif_data",
+ "readfile",
+ "readgzfile",
+ "readline",
+ "readline_add_history",
+ "readline_clear_history",
+ "readline_completion_function",
+ "readline_info",
+ "readline_list_history",
+ "readline_read_history",
+ "readline_write_history",
+ "readlink",
+ "realpath",
+ "reason",
+ "recode",
+ "recode_file",
+ "recode_string",
+ "register_shutdown_function",
+ "register_tick_function",
+ "REMOTE_ADDR",
+ "REMOTE_PORT",
+ "remove",
+ "remove_attribute",
+ "remove_child",
+ "rename",
+ "replace",
+ "replace_child",
+ "replace_node",
+ "_REQUEST",
+ "REQUEST_METHOD",
+ "REQUEST_URI",
+ "require",
+ "require_once",
+ "reset",
+ "restore_error_handler",
+ "restore_include_path",
+ "result_dump_file",
+ "result_dump_mem",
+ "return",
+ "rewind",
+ "rewinddir",
+ "rmdir",
+ "Rotate",
+ "rotateTo",
+ "round",
+ "rsort",
+ "rtrim",
+ "save",
+ "scale",
+ "scaleTo",
+ "SCRIPT_FILENAME",
+ "SCRIPT_NAME",
+ "sem_acquire",
+ "sem_get",
+ "sem_release",
+ "sem_remove",
+ "serialize",
+ "_SERVER",
+ "SERVER_ADMIN",
+ "SERVER_NAME",
+ "SERVER_PORT",
+ "SERVER_PROTOCOL",
+ "SERVER_SIGNATURE",
+ "SERVER_SOFTWARE",
+ "sesam_affected_rows",
+ "sesam_commit",
+ "sesam_connect",
+ "sesam_diagnostic",
+ "sesam_disconnect",
+ "sesam_errormsg",
+ "sesam_execimm",
+ "sesam_fetch_array",
+ "sesam_fetch_result",
+ "sesam_fetch_row",
+ "sesam_field_array",
+ "sesam_field_name",
+ "sesam_free_result",
+ "sesam_num_fields",
+ "sesam_query",
+ "sesam_rollback",
+ "sesam_seek_row",
+ "sesam_settransaction",
+ "_SESSION",
+ "session_cache_expire",
+ "session_cache_limiter",
+ "session_decode",
+ "session_destroy",
+ "session_encode",
+ "session_get_cookie_params",
+ "session_id",
+ "session_is_registered",
+ "session_module_name",
+ "session_name",
+ "session_readonly",
+ "session_register",
+ "session_save_path",
+ "session_set_cookie_params",
+ "session_set_save_handler",
+ "session_start",
+ "session_unregister",
+ "session_unset",
+ "session_write_close",
+ "setAction",
+ "set_attribute",
+ "setbackground",
+ "setbounds",
+ "setcolor",
+ "setColor",
+ "setcommitedversion",
+ "set_content",
+ "setcookie",
+ "setDepth",
+ "setdimension",
+ "setdown",
+ "set_error_handler",
+ "set_file_buffer",
+ "setFont",
+ "setframes",
+ "setHeight",
+ "setHit",
+ "set_include_path",
+ "setindentation",
+ "setLeftFill",
+ "setLeftMargin",
+ "setLine",
+ "setLineSpacing",
+ "setlocale",
+ "set_magic_quotes_runtime",
+ "setMargins",
+ "set_name",
+ "setname",
+ "setName",
+ "set_namespace",
+ "setOver",
+ "setrate",
+ "setRatio",
+ "setRightFill",
+ "setrightMargin",
+ "setSpacing",
+ "set_time_limit",
+ "settype",
+ "setUp",
+ "sha1",
+ "sha1_file",
+ "shell_exec",
+ "shm_attach",
+ "shm_detach",
+ "shm_get_var",
+ "shmop_close",
+ "shmop_delete",
+ "shmop_open",
+ "shmop_read",
+ "shmop_size",
+ "shmop_write",
+ "shm_put_var",
+ "shm_remove",
+ "shm_remove_var",
+ "show_source",
+ "shuffle",
+ "similar_text",
+ "sin",
+ "sinh",
+ "sizeof",
+ "skewX",
+ "skewXTo",
+ "skewY",
+ "skewYTo",
+ "sleep",
+ "snmpget",
+ "snmp_get_quick_print",
+ "snmprealwalk",
+ "snmpset",
+ "snmp_set_quick_print",
+ "snmpwalk",
+ "snmpwalkoid",
+ "socket_accept",
+ "socket_bind",
+ "socket_clear_error",
+ "socket_close",
+ "socket_connect",
+ "socket_create",
+ "socket_create_listen",
+ "socket_create_pair",
+ "socket_get_option",
+ "socket_getpeername",
+ "socket_getsockname",
+ "socket_get_status",
+ "socket_iovec_add",
+ "socket_iovec_alloc",
+ "socket_iovec_delete",
+ "socket_iovec_fetch",
+ "socket_iovec_free",
+ "socket_iovec_set",
+ "socket_last_error",
+ "socket_listen",
+ "socket_read",
+ "socket_readv",
+ "socket_recv",
+ "socket_recvfrom",
+ "socket_recvmsg",
+ "socket_select",
+ "socket_send",
+ "socket_sendmsg",
+ "socket_sendto",
+ "socket_set_blocking",
+ "socket_set_nonblock",
+ "socket_set_option",
+ "socket_set_timeout",
+ "socket_shutdown",
+ "socket_strerror",
+ "socket_write",
+ "socket_writev",
+ "sort",
+ "soundex",
+ "specified",
+ "split",
+ "spliti",
+ "sprintf",
+ "sql_regcase",
+ "sqrt",
+ "srand",
+ "srcanchors",
+ "srcsofdst",
+ "sscanf",
+ "stat",
+ "static",
+ "stdClass",
+ "strcasecmp",
+ "strchr",
+ "strcmp",
+ "strcoll",
+ "strcspn",
+ "stream_context_create",
+ "stream_context_get_options",
+ "stream_context_set_option",
+ "stream_context_set_params",
+ "stream_filter_append",
+ "stream_filter_prepend",
+ "stream_get_filters",
+ "stream_get_meta_data",
+ "stream_get_wrappers",
+ "streammp3",
+ "stream_register_filter",
+ "stream_register_wrapper",
+ "stream_select",
+ "stream_set_blocking",
+ "stream_set_timeout",
+ "stream_set_write_buffer",
+ "strftime",
+ "stripcslashes",
+ "stripslashes",
+ "strip_tags",
+ "stristr",
+ "strlen",
+ "strnatcasecmp",
+ "strnatcmp",
+ "strncasecmp",
+ "strncmp",
+ "str_pad",
+ "strpos",
+ "strrchr",
+ "str_repeat",
+ "str_replace",
+ "strrev",
+ "str_rot13",
+ "strrpos",
+ "str_shuffle",
+ "strspn",
+ "strstr",
+ "strtok",
+ "strtolower",
+ "strtotime",
+ "strtoupper",
+ "strtr",
+ "strval",
+ "str_word_count",
+ "substr",
+ "substr_count",
+ "substr_replace",
+ "SWFAction",
+ "swf_actiongeturl",
+ "swf_actiongotoframe",
+ "swf_actiongotolabel",
+ "swf_actionnextframe",
+ "swf_actionplay",
+ "swf_actionprevframe",
+ "swf_actionsettarget",
+ "swf_actionstop",
+ "swf_actiontogglequality",
+ "swf_actionwaitforframe",
+ "swf_addbuttonrecord",
+ "swf_addcolor",
+ "SWFBitmap",
+ "SWFbutton",
+ "swfbutton_keypress",
+ "swf_closefile",
+ "swf_definebitmap",
+ "swf_definefont",
+ "swf_defineline",
+ "swf_definepoly",
+ "swf_definerect",
+ "swf_definetext",
+ "SWFDisplayItem",
+ "swf_endbutton",
+ "swf_enddoaction",
+ "swf_endshape",
+ "swf_endsymbol",
+ "SWFFill",
+ "SWFFont",
+ "swf_fontsize",
+ "swf_fontslant",
+ "swf_fonttracking",
+ "swf_getbitmapinfo",
+ "swf_getfontinfo",
+ "swf_getframe",
+ "SWFGradient",
+ "swf_labelframe",
+ "swf_lookat",
+ "swf_modifyobject",
+ "SWFMorph",
+ "SWFMovie",
+ "swf_mulcolor",
+ "swf_nextid",
+ "swf_oncondition",
+ "swf_openfile",
+ "swf_ortho",
+ "swf_ortho2",
+ "swf_perspective",
+ "swf_placeobject",
+ "swf_polarview",
+ "swf_popmatrix",
+ "swf_posround",
+ "swf_pushmatrix",
+ "swf_removeobject",
+ "swf_rotate",
+ "swf_scale",
+ "swf_setfont",
+ "swf_setframe",
+ "SWFShape",
+ "swf_shapearc",
+ "swf_shapecurveto",
+ "swf_shapecurveto3",
+ "swf_shapefillbitmapclip",
+ "swf_shapefillbitmaptile",
+ "swf_shapefilloff",
+ "swf_shapefillsolid",
+ "swf_shapelinesolid",
+ "swf_shapelineto",
+ "swf_shapemoveto",
+ "swf_showframe",
+ "SWFSprite",
+ "swf_startbutton",
+ "swf_startdoaction",
+ "swf_startshape",
+ "swf_startsymbol",
+ "SWFText",
+ "SWFTextField",
+ "swf_textwidth",
+ "swf_translate",
+ "swf_viewport",
+ "switch",
+ "sybase_affected_rows",
+ "sybase_close",
+ "sybase_connect",
+ "sybase_data_seek",
+ "sybase_fetch_array",
+ "sybase_fetch_field",
+ "sybase_fetch_object",
+ "sybase_fetch_row",
+ "sybase_field_seek",
+ "sybase_free_result",
+ "sybase_get_last_message",
+ "sybase_min_client_severity",
+ "sybase_min_error_severity",
+ "sybase_min_message_severity",
+ "sybase_min_server_severity",
+ "sybase_num_fields",
+ "sybase_num_rows",
+ "sybase_pconnect",
+ "sybase_query",
+ "sybase_result",
+ "sybase_select_db",
+ "symlink",
+ "syslog",
+ "system",
+ "system_id",
+ "tagname",
+ "tan",
+ "tanh",
+ "target",
+ "tempnam",
+ "textdomain",
+ "time",
+ "title",
+ "tmpfile",
+ "token_get_all",
+ "token_name",
+ "touch",
+ "trigger_error",
+ "trim",
+ "TRUE",
+ "type",
+ "uasort",
+ "ucfirst",
+ "ucwords",
+ "udm_add_search_limit",
+ "udm_alloc_agent",
+ "udm_api_version",
+ "udm_cat_list",
+ "udm_cat_path",
+ "udm_check_charset",
+ "udm_check_stored",
+ "udm_clear_search_limits",
+ "udm_close_stored",
+ "udm_crc32",
+ "udm_errno",
+ "udm_error",
+ "udm_find",
+ "udm_free_agent",
+ "udm_free_ispell_data",
+ "udm_free_res",
+ "udm_get_doc_count",
+ "udm_get_res_field",
+ "udm_get_res_param",
+ "udm_load_ispell_data",
+ "udm_open_stored",
+ "udm_set_agent_param",
+ "uksort",
+ "umask",
+ "uniqid",
+ "unixtojd",
+ "unlink",
+ "unlink_node",
+ "unlock",
+ "unpack",
+ "unregister_tick_function",
+ "unserialize",
+ "unset",
+ "urldecode",
+ "urlencode",
+ "user",
+ "user_error",
+ "userlist",
+ "usleep",
+ "usort",
+ "utf8_decode",
+ "utf8_encode",
+ "value",
+ "values",
+ "var",
+ "var_dump",
+ "var_export",
+ "version_compare",
+ "virtual",
+ "vpopmail_add_alias_domain",
+ "vpopmail_add_alias_domain_ex",
+ "vpopmail_add_domain",
+ "vpopmail_add_domain_ex",
+ "vpopmail_add_user",
+ "vpopmail_alias_add",
+ "vpopmail_alias_del",
+ "vpopmail_alias_del_domain",
+ "vpopmail_alias_get",
+ "vpopmail_alias_get_all",
+ "vpopmail_auth_user",
+ "vpopmail_del_domain",
+ "vpopmail_del_domain_ex",
+ "vpopmail_del_user",
+ "vpopmail_error",
+ "vpopmail_passwd",
+ "vpopmail_set_user_quota",
+ "vprintf",
+ "vsprintf",
+ "w32api_deftype",
+ "w32api_init_dtype",
+ "w32api_invoke_function",
+ "w32api_register_function",
+ "w32api_set_call_method",
+ "wddx_add_vars",
+ "wddx_deserialize",
+ "wddx_packet_end",
+ "wddx_packet_start",
+ "wddx_serialize_value",
+ "wddx_serialize_vars",
+ "while",
+ "wordwrap",
+ "xinclude",
+ "xml_error_string",
+ "xml_get_current_byte_index",
+ "xml_get_current_column_number",
+ "xml_get_current_line_number",
+ "xml_get_error_code",
+ "xml_parse",
+ "xml_parse_into_struct",
+ "xml_parser_create",
+ "xml_parser_create_ns",
+ "xml_parser_free",
+ "xml_parser_get_option",
+ "xml_parser_set_option",
+ "xmlrpc_decode",
+ "xmlrpc_decode_request",
+ "xmlrpc_encode",
+ "xmlrpc_encode_request",
+ "xmlrpc_get_type",
+ "xmlrpc_parse_method_descriptions",
+ "xmlrpc_server_add_introspection_data",
+ "xmlrpc_server_call_method",
+ "xmlrpc_server_create",
+ "xmlrpc_server_destroy",
+ "xmlrpc_server_register_introspection_callback",
+ "xmlrpc_server_register_method",
+ "xmlrpc_set_type",
+ "xml_set_character_data_handler",
+ "xml_set_default_handler",
+ "xml_set_element_handler",
+ "xml_set_end_namespace_decl_handler",
+ "xml_set_external_entity_ref_handler",
+ "xml_set_notation_decl_handler",
+ "xml_set_object",
+ "xml_set_processing_instruction_handler",
+ "xml_set_start_namespace_decl_handler",
+ "xml_set_unparsed_entity_decl_handler",
+ "xpath_eval",
+ "xpath_eval_expression",
+ "xpath_new_context",
+ "xptr_eval",
+ "xptr_new_context",
+ "xslt_create",
+ "xslt_errno",
+ "xslt_error",
+ "xslt_free",
+ "xslt_output_process",
+ "xslt_set_base",
+ "xslt_set_encoding",
+ "xslt_set_error_handler",
+ "xslt_set_log",
+ "xslt_set_sax_handler",
+ "xslt_set_sax_handlers",
+ "xslt_set_scheme_handler",
+ "xslt_set_scheme_handlers",
+ "yaz_addinfo",
+ "yaz_ccl_conf",
+ "yaz_ccl_parse",
+ "yaz_close",
+ "yaz_connect",
+ "yaz_database",
+ "yaz_element",
+ "yaz_errno",
+ "yaz_error",
+ "yaz_get_option",
+ "yaz_hits",
+ "yaz_itemorder",
+ "yaz_present",
+ "yaz_range",
+ "yaz_record",
+ "yaz_scan",
+ "yaz_scan_result",
+ "yaz_schema",
+ "yaz_search",
+ "yaz_set_option",
+ "yaz_sort",
+ "yaz_syntax",
+ "yaz_wait",
+ "yp_all",
+ "yp_cat",
+ "yp_errno",
+ "yp_err_string",
+ "yp_first",
+ "yp_get_default_domain",
+ "yp_master",
+ "yp_match",
+ "yp_next",
+ "yp_order",
+ "zend_logo_guid",
+ "zend_version",
+ "zend_version",
+ "zip_close",
+ "zip_entry_close",
+ "zip_entry_compressedsize",
+ "zip_entry_compressionmethod",
+ "zip_entry_filesize",
+ "zip_entry_name",
+ "zip_entry_open",
+ "zip_entry_read",
+ "zip_open",
+ "zip_read",
+ 0
+ };
+
+PhpWriter::PhpWriter() {
+}
+
+PhpWriter::~PhpWriter() {}
+
+
+void PhpWriter::writeClass(UMLClassifier *c) {
+ if(!c) {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ QString classname = cleanName(c->getName());
+ //find an appropriate name for our file
+ QString fileName = findFileName(c, ".php");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile filephp;
+ if(!openFile(filephp, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream php(&filephp);
+
+ //////////////////////////////
+ //Start generating the code!!
+ /////////////////////////////
+
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".php");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),filephp.name());
+ php<<str<<m_endl;
+ }
+
+
+ //write includes
+ UMLPackageList includes;
+ findObjectsRelated(c,includes);
+ UMLPackage *conc;
+ for(conc = includes.first(); conc ;conc = includes.next()) {
+ QString headerName = findFileName(conc, ".php");
+ if (headerName.isEmpty()) {
+ php << "include '" << headerName << "';" << m_endl;
+ }
+ }
+ php << m_endl;
+
+ //Write class Documentation if there is somthing or if force option
+ if(forceDoc() || !c->getDoc().isEmpty()) {
+ php << m_endl << "/**" << m_endl;
+ php << " * class " << classname << m_endl;
+ php << formatDoc(c->getDoc()," * ");
+ php << " */" << m_endl ;
+ }
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+ UMLAssociation *a;
+
+ //check if class is abstract and / or has abstract methods
+ //FG if(c->getAbstract() && !hasAbstractOps(c))
+ if(c->getAbstract())
+ php << "/******************************* Abstract Class ****************************" << m_endl << " "
+ << classname << " does not have any pure virtual methods, but its author" << m_endl
+ << " defined it as an abstract class, so you should not use it directly." << m_endl
+ << " Inherit from it instead and create only objects from the derived classes" << m_endl
+ << "*****************************************************************************/" << m_endl << m_endl;
+
+ php << "class " << classname << (superclasses.count() > 0 ? " extends ":"");
+ for (UMLClassifier *obj = superclasses.first();
+ obj; obj = superclasses.next()) {
+ php<<cleanName(obj->getName());
+ }
+ php<< m_endl << "{" << m_endl;
+
+ //associations
+ if( forceSections() || !aggregations.isEmpty()) {
+ php<< m_endl << m_indentation << "/** Aggregations: */" << m_endl;
+ for (a = aggregations.first(); a; a = aggregations.next()) {
+ php<< m_endl;
+ //maybe we should parse the string here and take multiplicity into account to decide
+ //which container to use.
+ UMLObject *o = a->getObject(Uml::A);
+ QString typeName = cleanName(o->getName());
+ if (a->getMulti(Uml::A).isEmpty()) {
+ php << m_indentation << "var $m_" << ";" << m_endl;
+ } else {
+ php << m_indentation << "var $m_" << "Vector = array();" << m_endl;
+ }
+ }//end for
+ }
+
+ if( forceSections() || !compositions.isEmpty()) {
+ php<< m_endl << m_indentation << "/** Compositions: */" << m_endl;
+ for (a = compositions.first(); a ; a = compositions.next()) {
+ // see comment on Aggregation about multiplicity...
+ UMLObject *o = a->getObject(Uml::A);
+ QString typeName = cleanName(o->getName());
+ if (a->getMulti(Uml::A).isEmpty()) {
+ php << m_indentation << "var $m_" << ";" << m_endl;
+ } else {
+ php << m_indentation << "var $m_" << "Vector = array();" << m_endl;
+ }
+ }
+ }
+
+ const bool isClass = !c->isInterface();
+
+ //attributes
+ if (isClass)
+ writeAttributes(c, php);
+
+ //operations
+ writeOperations(c,php);
+
+ if (isClass && hasDefaultValueAttr(c)) {
+ UMLAttributeList atl = c->getAttributeList();
+ php << m_endl;
+
+ php << m_indentation << "/**" << m_endl;
+ QString temp = "initAttributes sets all " + classname + " attributes to its default value."
+ " Make sure to call this method within your class constructor";
+ php << formatDoc(temp,m_indentation + " * ");
+ php << m_indentation << " */" << m_endl;
+ php << m_indentation << "function "<<"initAttributes( )" << m_endl;
+ php << m_indentation << "{" << m_endl;
+ for(UMLAttribute* at = atl.first(); at; at = atl.next()) {
+ if(!at->getInitialValue().isEmpty()) {
+ php << m_indentation << m_indentation << "$this->" << cleanName(at->getName()) << " = " <<
+ at->getInitialValue() << ";" << m_endl;
+ }
+ }
+ php << m_indentation << "}" << m_endl;
+ }
+
+ php << m_endl;
+
+ //finish file
+ php << m_endl << "} // end of " << classname << m_endl;
+ php << "?>" << m_endl;
+
+ //close files and notfiy we are done
+ filephp.close();
+ emit codeGenerated(c, true);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+void PhpWriter::writeOperations(UMLClassifier *c, QTextStream &php) {
+
+ //Lists to store operations sorted by scope
+ UMLOperationList oppub,opprot,oppriv;
+
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList opl(c->getOpList());
+ for(UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ QString classname(cleanName(c->getName()));
+
+ //write operations to file
+ if(forceSections() || !oppub.isEmpty()) {
+ php << m_endl;
+ writeOperations(classname,oppub,php);
+ }
+
+ if(forceSections() || !opprot.isEmpty()) {
+ php << m_endl;
+ writeOperations(classname,opprot,php);
+ }
+
+ if(forceSections() || !oppriv.isEmpty()) {
+ php << m_endl;
+ writeOperations(classname,oppriv,php);
+ }
+}
+
+void PhpWriter::writeOperations(QString /* classname */, UMLOperationList &opList, QTextStream &php) {
+ UMLOperation *op;
+ UMLAttribute *at;
+
+ for(op=opList.first(); op ; op=opList.next()) {
+ UMLAttributeList atl = op->getParmList();
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+ for (at = atl.first(); at; at = atl.next())
+ writeDoc |= !at->getDoc().isEmpty();
+
+ if( writeDoc ) //write method documentation
+ {
+ php <<m_indentation << "/**" << m_endl <<formatDoc(op->getDoc(),m_indentation + " * ");
+ php << m_indentation << " *" << m_endl;
+
+ for (at = atl.first(); at; at = atl.next()) //write parameter documentation
+ {
+ if(forceDoc() || !at->getDoc().isEmpty()) {
+ php <<m_indentation << " * @param " + at->getTypeName() + " " + cleanName(at->getName());
+ php << " " + formatDoc(at->getDoc(),"");
+ }
+ }//end for : write parameter documentation
+ php << m_indentation << " * @return " << op->getTypeName() << m_endl;
+ if (op->getAbstract()) php << m_indentation << " * @abstract" << m_endl;
+ if (op->getStatic()) php << m_indentation << " * @static" << m_endl;
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ php << m_indentation << " * @access public" << m_endl;
+ break;
+ case Uml::Visibility::Protected:
+ php << m_indentation << " * @access protected" << m_endl;
+ break;
+ case Uml::Visibility::Private:
+ php << m_indentation << " * @access private" << m_endl;
+ break;
+ default:
+ break;
+ }
+ php <<m_indentation << " */" << m_endl;
+ }//end if : write method documentation
+
+ php << m_indentation << "function " << cleanName(op->getName()) << "(";
+
+ int i= atl.count();
+ int j=0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+ php << " $" << cleanName(at->getName())
+ << (!(at->getInitialValue().isEmpty()) ?
+ (QString(" = ")+at->getInitialValue()) :
+ QString(""))
+ << ((j < i-1)?", ":"");
+ }
+ php <<" )" << m_endl << m_indentation << "{" << m_endl << m_indentation << m_indentation << m_endl << m_indentation << "} // end of member function " + cleanName(op->getName()) + m_endl;
+ php << m_endl;
+ }//end for
+}
+
+void PhpWriter::writeAttributes(UMLClassifier *c, QTextStream &php) {
+ UMLAttributeList atpub, atprot, atpriv, atdefval;
+ atpub.setAutoDelete(false);
+ atprot.setAutoDelete(false);
+ atpriv.setAutoDelete(false);
+ atdefval.setAutoDelete(false);
+
+ //sort attributes by scope and see if they have a default value
+ UMLAttributeList atl = c->getAttributeList();
+ UMLAttribute *at;
+ for(at = atl.first(); at ; at = atl.next()) {
+ if(!at->getInitialValue().isEmpty())
+ atdefval.append(at);
+ switch(at->getVisibility()) {
+ case Uml::Visibility::Public:
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ atpriv.append(at);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(forceSections() || atl.count())
+ php<< m_endl << m_indentation << " /*** Attributes: ***/" << m_endl <<m_endl;
+
+ if(forceSections() || atpub.count()) {
+ writeAttributes(atpub,php);
+ }
+
+ if(forceSections() || atprot.count()) {
+ writeAttributes(atprot,php);
+ }
+
+ if(forceSections() || atpriv.count()) {
+ writeAttributes(atpriv,php);
+ }
+}
+
+
+void PhpWriter::writeAttributes(UMLAttributeList &atList, QTextStream &php) {
+ for (UMLAttribute *at = atList.first(); at ; at = atList.next()) {
+ if (forceDoc() || !at->getDoc().isEmpty()) {
+ php << m_indentation << "/**" << m_endl << formatDoc(at->getDoc(), m_indentation + " * ");
+ switch(at->getVisibility()) {
+ case Uml::Visibility::Public:
+ php << m_indentation << " * @access public" << m_endl;
+ break;
+ case Uml::Visibility::Protected:
+ php << m_indentation << " * @access protected" << m_endl;
+ break;
+ case Uml::Visibility::Private:
+ php << m_indentation << " * @access private" << m_endl;
+ break;
+ default:
+ break;
+ }
+
+ php << m_indentation << " */" << m_endl;
+ }
+ php << m_indentation << "var " << "$" << cleanName(at->getName()) << ";" << m_endl;
+
+ } // end for
+ return;
+}
+
+/**
+ * returns "PHP"
+ */
+Uml::Programming_Language PhpWriter::getLanguage() {
+ return Uml::pl_PHP;
+}
+
+const QStringList PhpWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ for (int i = 0; words[i]; i++)
+ keywords.append(words[i]);
+ }
+
+ return keywords;
+}
+
+#include "phpwriter.moc"
+
diff --git a/umbrello/umbrello/codegenerators/phpwriter.h b/umbrello/umbrello/codegenerators/phpwriter.h
new file mode 100644
index 00000000..a3acb68b
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/phpwriter.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ phpwriter.h - description
+ -------------------
+ begin : Thu Oct 17 2002
+ copyright : (C) 2002 by Heiko Nardmann
+ email : h.nardmann@secunet.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PHPWRITER_H
+#define PHPWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umlattributelist.h"
+#include "../umloperationlist.h"
+
+/**
+ * class PhpWriter is a PHP code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class PhpWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ PhpWriter();
+ virtual ~PhpWriter();
+
+ /**
+ * call this method to generate Php code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "PHP"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * we do not want to write the comment "Private methods" twice
+ */
+ bool bPrivateSectionCommentIsWritten;
+
+ /**
+ * write all operations for a given class
+ *
+ * @param c the concept we are generating code for
+ * @param php output stream for the PHP file
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &php);
+
+ /**
+ * write a list of class operations
+ *
+ * @param classname the name of the class
+ * @param opList the list of operations
+ * @param php output stream for the PHP file
+ */
+ void writeOperations(QString classname, UMLOperationList &opList,
+ QTextStream &php);
+
+ /** write all the attributes of a class
+ * @param c the class we are generating code for
+ * @param php output stream for the PHP file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &php);
+
+ /** write a list of class attributes
+ * @param atList the list of attributes
+ * @param php output stream for the PHP file
+ */
+ void writeAttributes(UMLAttributeList &atList, QTextStream &php);
+};
+
+#endif //PHPWRITER
diff --git a/umbrello/umbrello/codegenerators/pythonwriter.cpp b/umbrello/umbrello/codegenerators/pythonwriter.cpp
new file mode 100644
index 00000000..a5ac2b28
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/pythonwriter.cpp
@@ -0,0 +1,438 @@
+/***************************************************************************
+ pythonwriter.h - description
+ -------------------
+ begin : Sat Dec 21 2002
+ copyright : Vincent Decorges
+ email : vincent.decorges@eivd.ch
+ (C) 2003-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "pythonwriter.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#include "../umldoc.h"
+#include "../umlattributelist.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../classifier.h"
+#include "../attribute.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+
+PythonWriter::PythonWriter() : m_bNeedPass(true) {
+}
+
+PythonWriter::~PythonWriter() {}
+
+void PythonWriter::writeClass(UMLClassifier *c) {
+ if(!c) {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ QString classname = cleanName(c->getName());
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ m_bNeedPass = true;
+
+ //find an appropriate name for our file
+ QString fileName = findFileName(c, ".py");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QChar first = fileName.at(0);
+ //Replace the first letter of the filename because
+ //python class begin with an upper caracter (convention)
+ first = first.upper();
+ fileName = fileName.replace(0, 1, first);
+
+ QFile fileh;
+ if( !openFile(fileh, fileName) ) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream h(&fileh);
+
+ //////////////////////////////
+ //Start generating the code!!
+ /////////////////////////////
+
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+
+ str = getHeadingFile(".py");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"), fileName);
+ str.replace(QRegExp("%filepath%"), fileh.name());
+ h<<str<<m_endl;
+ }
+
+ // generate import statement for superclasses and take packages into account
+ str = cleanName(c->getName());
+ QString pkg = cleanName(c->getPackage());
+ if (!pkg.isEmpty())
+ str.prepend(pkg + '.');
+ QStringList includesList = QStringList(str); //save imported classes
+ int i = superclasses.count();
+ for (UMLClassifier *classifier = superclasses.first();
+ classifier && i; classifier = superclasses.next(), i--) {
+ str = cleanName(classifier->getName());
+ pkg = cleanName(classifier->getPackage());
+ if (!pkg.isEmpty())
+ str.prepend(pkg + '.');
+ includesList.append(str);
+ h << "from " + str + " import *" << m_endl;
+ }
+
+ //write includes and take namespaces into account
+ UMLPackageList includes;
+ findObjectsRelated(c,includes);
+ UMLPackage* conc;
+ for(conc = includes.first(); conc ;conc = includes.next()) {
+ QString headerName = findFileName(conc, ".py");
+ if ( !headerName.isEmpty() ) {
+ headerName.remove(QRegExp(".py$"));
+ first = headerName.at(0);
+ first = first.upper();
+ headerName = headerName.replace(0, 1, first);
+ str = headerName.replace(QChar('/'),QChar('.'));
+ if (includesList.findIndex(str) < 0) // not yet imported
+ h << "from " << str << " import *" << m_endl;
+ }
+ }
+ h<<m_endl;
+
+ h << "class " << classname << (superclasses.count() > 0 ? " (" : "(object)");
+ i = superclasses.count();
+
+ for (UMLClassifier *obj = superclasses.first();
+ obj && i; obj = superclasses.next(), i--) {
+
+ h<<cleanName(obj->getName())<<(i>1?", ":"");
+ }
+
+
+ h<<(superclasses.count() > 0 ? ")":"")<<":"<<m_endl<<m_endl;
+
+ if (forceDoc() || !c->getDoc().isEmpty()) {
+ h << m_indentation << "\"\"\"" << m_endl;
+ h << formatDoc(c->getDoc(), m_indentation + ' ') << m_endl;
+ h << m_indentation << ":version:" << m_endl;
+ h << m_indentation << ":author:" << m_endl;
+ h << m_indentation << "\"\"\"" << m_endl << m_endl;
+ m_bNeedPass = false;
+ }
+
+ // attributes
+ writeAttributes(c->getAttributeList(), h);
+
+ //operations
+ writeOperations(c,h);
+
+ if (m_bNeedPass)
+ h << m_indentation << "pass" << m_endl;
+
+ //finish files
+ h<<m_endl<<m_endl;
+
+ //close files and notfiy we are done
+ fileh.close();
+ emit codeGenerated(c, true);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+void PythonWriter::writeAttributes(UMLAttributeList atList, QTextStream &py) {
+ if (!forceDoc() || atList.count() == 0)
+ return;
+ py << m_indentation << "\"\"\" ATTRIBUTES" << m_endl << m_endl;
+ for (UMLAttribute *at = atList.first(); at; at = atList.next()) {
+ py << formatDoc(at->getDoc(), m_indentation + ' ') << m_endl;
+ Uml::Visibility vis = at->getVisibility();
+ py << m_indentation << cleanName(at->getName()) << " ("
+ << vis.toString() << ")" << m_endl << m_endl ;
+ } // end for
+ py << m_indentation << "\"\"\"" << m_endl << m_endl;
+}
+
+void PythonWriter::writeOperations(UMLClassifier *c, QTextStream &h) {
+
+ //Lists to store operations sorted by scope
+ UMLOperationList oppub,opprot,oppriv;
+
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList opl(c->getOpList());
+ for(UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ QString classname(cleanName(c->getName()));
+
+ //write operations to file
+ if(forceSections() || !oppub.isEmpty()) {
+ writeOperations(classname,oppub,h,PUBLIC);
+ }
+
+ if(forceSections() || !opprot.isEmpty()) {
+ writeOperations(classname,opprot,h,PROTECTED);
+ }
+
+ if(forceSections() || !oppriv.isEmpty()) {
+ writeOperations(classname,oppriv,h,PRIVATE);
+ }
+
+}
+
+void PythonWriter::writeOperations(const QString& /*classname*/, UMLOperationList &opList,
+ QTextStream &h, Access access) {
+ UMLOperation *op;
+ UMLAttribute *at;
+
+ QString sAccess;
+
+ switch (access) {
+
+ case PUBLIC:
+ sAccess = QString("");
+ break;
+ case PRIVATE:
+ sAccess = QString("__");
+ break;
+ case PROTECTED:
+ sAccess = QString("_");
+ break;
+ }
+
+
+ for(op=opList.first(); op ; op=opList.next()) {
+ UMLAttributeList atl = op->getParmList();
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+ for (at = atl.first(); at; at = atl.next())
+ writeDoc |= !at->getDoc().isEmpty();
+
+ h<< m_indentation << "def "<< sAccess + cleanName(op->getName()) << "(self";
+
+ int j=0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+ h << ", " << cleanName(at->getName())
+ << (!(at->getInitialValue().isEmpty()) ?
+ (QString(" = ")+at->getInitialValue()) :
+ QString(""));
+ }
+
+ h<<"):"<<m_endl;
+
+ if( writeDoc ) //write method documentation
+ {
+ h << m_indentation << m_indentation << "\"\"\"" << m_endl;
+ h << formatDoc(op->getDoc(), m_indentation + m_indentation + ' ') << m_endl;
+
+ for (at = atl.first(); at; at = atl.next()) //write parameter documentation
+ {
+ if(forceDoc() || !at->getDoc().isEmpty()) {
+ h<<m_indentation<<m_indentation<<"@param "<<at->getTypeName()<<
+ " " << cleanName(at->getName());
+ h<<" : "<<at->getDoc()<<m_endl;
+ }
+ }//end for : write parameter documentation
+ h<<m_indentation<<m_indentation<<"@return " + op->getTypeName()<<" :"<<m_endl;
+ h<<m_indentation<<m_indentation<<"@author"<<m_endl;
+ h<<m_indentation<<m_indentation<<"\"\"\""<<m_endl;
+ }
+ h<<m_indentation<<m_indentation<<"pass"<<m_endl<<m_endl;
+ m_bNeedPass = false;
+ }//end for
+}
+
+/**
+ * returns "Python"
+ */
+Uml::Programming_Language PythonWriter::getLanguage() {
+ return Uml::pl_Python;
+}
+
+const QStringList PythonWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "abs"
+ << "and"
+ << "apply"
+ << "ArithmeticError"
+ << "assert"
+ << "AssertionError"
+ << "AttributeError"
+ << "break"
+ << "buffer"
+ << "callable"
+ << "chr"
+ << "class"
+ << "classmethod"
+ << "cmp"
+ << "coerce"
+ << "compile"
+ << "complex"
+ << "continue"
+ << "def"
+ << "del"
+ << "delattr"
+ << "DeprecationWarning"
+ << "dict"
+ << "dir"
+ << "divmod"
+ << "elif"
+ << "Ellipsis"
+ << "else"
+ << "EnvironmentError"
+ << "EOFError"
+ << "eval"
+ << "except"
+ << "Exception"
+ << "exec"
+ << "execfile"
+ << "file"
+ << "filter"
+ << "finally"
+ << "float"
+ << "FloatingPointError"
+ << "for"
+ << "from"
+ << "getattr"
+ << "global"
+ << "globals"
+ << "hasattr"
+ << "hash"
+ << "hex"
+ << "id"
+ << "if"
+ << "import"
+ << "__import__"
+ << "ImportError"
+ << "in"
+ << "IndentationError"
+ << "IndexError"
+ << "input"
+ << "int"
+ << "intern"
+ << "IOError"
+ << "is"
+ << "isinstance"
+ << "issubclass"
+ << "iter"
+ << "KeyboardInterrupt"
+ << "KeyError"
+ << "lambda"
+ << "len"
+ << "list"
+ << "locals"
+ << "long"
+ << "LookupError"
+ << "map"
+ << "max"
+ << "MemoryError"
+ << "min"
+ << "NameError"
+ << "None"
+ << "not"
+ << "NotImplemented"
+ << "NotImplementedError"
+ << "object"
+ << "oct"
+ << "open"
+ << "or"
+ << "ord"
+ << "OSError"
+ << "OverflowError"
+ << "OverflowWarning"
+ << "pass"
+ << "pow"
+ << "print"
+ << "property"
+ << "raise"
+ << "range"
+ << "raw_input"
+ << "reduce"
+ << "ReferenceError"
+ << "reload"
+ << "repr"
+ << "return"
+ << "round"
+ << "RuntimeError"
+ << "RuntimeWarning"
+ << "setattr"
+ << "slice"
+ << "StandardError"
+ << "staticmethod"
+ << "StopIteration"
+ << "str"
+ << "super"
+ << "SyntaxError"
+ << "SyntaxWarning"
+ << "SystemError"
+ << "SystemExit"
+ << "TabError"
+ << "try"
+ << "tuple"
+ << "type"
+ << "TypeError"
+ << "UnboundLocalError"
+ << "unichr"
+ << "unicode"
+ << "UnicodeError"
+ << "UserWarning"
+ << "ValueError"
+ << "vars"
+ << "Warning"
+ << "while"
+ << "WindowsError"
+ << "xrange"
+ << "yield"
+ << "ZeroDivisionError"
+ << "zip";
+ }
+
+ return keywords;
+}
+
+#include "pythonwriter.moc"
diff --git a/umbrello/umbrello/codegenerators/pythonwriter.h b/umbrello/umbrello/codegenerators/pythonwriter.h
new file mode 100644
index 00000000..f9e5b31a
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/pythonwriter.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ pythonwriter.h - description
+ -------------------
+ begin : Sat Dec 21 2002
+ author : Vincent Decorges
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2003-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef PYTHONWRITER_H
+#define PYTHONWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umlattributelist.h"
+#include "../umloperationlist.h"
+
+enum Access {PRIVATE, PUBLIC, PROTECTED};
+
+/**
+ * class PythonWriter is a python code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class PythonWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ PythonWriter();
+ virtual ~PythonWriter();
+
+ /**
+ * call this method to generate C++ code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "Python"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * write all attributes for a given class
+ *
+ * @param c the concept we are generating code for
+ * @param py output stream for the header file
+ */
+ void writeAttributes(UMLAttributeList atList, QTextStream &py);
+
+ /**
+ * write all operations for a given class
+ *
+ * @param c the concept we are generating code for
+ * @param h output stream for the header file
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &h);
+
+ /**
+ * write a list of class operations
+ *
+ * @param classname the name of the class
+ * @param opList the list of operations
+ * @param h output stream for the header file
+ */
+ void writeOperations(const QString& classname, UMLOperationList &opList,
+ QTextStream &h, Access access);
+
+ bool m_bNeedPass; ///< True as long as no "pass" has been written
+};
+
+#endif //PYTHONWRITER
diff --git a/umbrello/umbrello/codegenerators/rubyclassdeclarationblock.cpp b/umbrello/umbrello/codegenerators/rubyclassdeclarationblock.cpp
new file mode 100644
index 00000000..cae5d322
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubyclassdeclarationblock.cpp
@@ -0,0 +1,147 @@
+/***************************************************************************
+ rubyclassdeclarationblock.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#include "rubyclassdeclarationblock.h"
+#include "rubycodedocumentation.h"
+#include "rubycodegenerator.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+RubyClassDeclarationBlock::RubyClassDeclarationBlock
+ ( RubyClassifierCodeDocument * parentDoc, const QString &startText, const QString &endText, const QString &comment)
+ : OwnedHierarchicalCodeBlock(parentDoc->getParentClassifier(), parentDoc, startText, endText, comment)
+{
+ init(parentDoc, comment);
+}
+
+RubyClassDeclarationBlock::~RubyClassDeclarationBlock ( ) { }
+
+//
+// Methods
+//
+
+/**
+ * Save the XMI representation of this object
+ */
+void RubyClassDeclarationBlock::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "rubyclassdeclarationblock" );
+
+ setAttributesOnNode(doc, blockElement);
+
+ root.appendChild( blockElement );
+}
+
+/**
+ * load params from the appropriate XMI element node.
+ */
+void RubyClassDeclarationBlock::loadFromXMI ( QDomElement & root )
+{
+ setAttributesFromNode(root);
+}
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * update the start and end text for this ownedhierarchicalcodeblock.
+ */
+void RubyClassDeclarationBlock::updateContent ( )
+{
+
+ RubyClassifierCodeDocument *parentDoc = dynamic_cast<RubyClassifierCodeDocument*>(getParentDocument());
+ UMLClassifier *c = parentDoc->getParentClassifier();
+ CodeGenerationPolicy * p = UMLApp::app()->getCommonPolicy();
+ QString endLine = p->getNewLineEndingChars();
+ bool isInterface = parentDoc->parentIsInterface(); // a little shortcut
+ QString RubyClassName = parentDoc->getRubyClassName(c->getName());
+ bool forceDoc = p->getCodeVerboseDocumentComments();
+
+ // COMMENT
+ QString comment = c->getDoc();
+ comment.replace("@ref ", "");
+ comment.replace("@see", "_See_");
+ comment.replace("@short", "_Summary_");
+ comment.replace("@author", "_Author_");
+
+ if (isInterface)
+ getComment()->setText("Module " + RubyClassName + endLine + comment);
+ else
+ getComment()->setText("Class " + RubyClassName + endLine + comment);
+
+ if(forceDoc || !c->getDoc().isEmpty())
+ getComment()->setWriteOutText(true);
+ else
+ getComment()->setWriteOutText(false);
+
+
+ // Now set START/ENDING Text
+ QString startText = "";
+
+ if (parentDoc->parentIsInterface()) {
+ startText.append("module ");
+ } else {
+ startText.append("class ");
+ }
+
+ UMLClassifierList superclasses = c->findSuperClassConcepts(UMLClassifier::CLASS);
+ UMLClassifierList superinterfaces = c->findSuperClassConcepts(UMLClassifier::INTERFACE);
+
+ // write out inheritance
+ startText.append(RubyClassName);
+
+ int i = 0;
+ for (UMLClassifier * concept= superclasses.first(); concept; concept = superclasses.next()) {
+ if (i == 0) {
+ startText.append(QString(" < ") + RubyCodeGenerator::cppToRubyType(concept->getName()) + endLine);
+ } else {
+ // After the first superclass name in the list, assume the classes
+ // are ruby modules that can be mixed in,
+ startText.append("include " + RubyCodeGenerator::cppToRubyType(concept->getName()) + endLine);
+ }
+ i++;
+ }
+
+ // Write out the interfaces we 'implement'. Are these modules to be mixed in, in Ruby?
+ for (UMLClassifier * concept= superinterfaces.first(); concept; concept = superinterfaces.next()) {
+ startText.append(QString("include ") + RubyCodeGenerator::cppToRubyType(concept->getName()) + endLine);
+ }
+
+ // Set the header and end text for the hier.codeblock
+ setStartText(startText);
+}
+
+void RubyClassDeclarationBlock::init (RubyClassifierCodeDocument *parentDoc, const QString &comment)
+{
+
+ setComment(new RubyCodeDocumentation(parentDoc));
+ getComment()->setText(comment);
+
+ setEndText("end");
+
+ updateContent();
+
+}
+
+
+#include "rubyclassdeclarationblock.moc"
diff --git a/umbrello/umbrello/codegenerators/rubyclassdeclarationblock.h b/umbrello/umbrello/codegenerators/rubyclassdeclarationblock.h
new file mode 100644
index 00000000..a7732662
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubyclassdeclarationblock.h
@@ -0,0 +1,74 @@
+
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Jul 16 2003
+ */
+
+#ifndef RUBYCLASSDECLARATIONBLOCK_H
+#define RUBYCLASSDECLARATIONBLOCK_H
+
+#include <qstring.h>
+
+/***************************************************************************
+ rubyclassdeclarationblock.h
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+#include "rubyclassifiercodedocument.h"
+#include "../ownedhierarchicalcodeblock.h"
+
+class RubyClassDeclarationBlock : public OwnedHierarchicalCodeBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ explicit RubyClassDeclarationBlock ( RubyClassifierCodeDocument * parentDoc, const QString &start = "", const QString &endText = "end", const QString &comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyClassDeclarationBlock ( );
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * load params from the appropriate XMI element node.
+ */
+ virtual void loadFromXMI ( QDomElement & root );
+
+protected:
+
+ /**
+ * Update the start/end text of this codeblock.
+ */
+ void updateContent ( );
+
+private:
+
+ void init (RubyClassifierCodeDocument * parent, const QString &comment);
+
+};
+
+#endif // RUBYCLASSDECLARATIONBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/rubyclassifiercodedocument.cpp b/umbrello/umbrello/codegenerators/rubyclassifiercodedocument.cpp
new file mode 100644
index 00000000..1c136df8
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubyclassifiercodedocument.cpp
@@ -0,0 +1,646 @@
+/***************************************************************************
+ rubyclassifiercodedocument.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/**
+ We carve the Ruby document up into sections as follows:
+
+ * header
+ * class declaration
+ * guts of the class (e.g. accessor methods, operations, dependant classes)
+*/
+
+// own header
+#include "rubyclassifiercodedocument.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "rubycodegenerator.h"
+#include "rubycodecomment.h"
+#include "rubyclassdeclarationblock.h"
+#include "rubycodeclassfielddeclarationblock.h"
+#include "rubycodeoperation.h"
+#include "codegen_utils.h"
+#include "../classifier.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+RubyClassifierCodeDocument::RubyClassifierCodeDocument ( UMLClassifier * concept )
+ : ClassifierCodeDocument (concept) {
+ init();
+}
+
+RubyClassifierCodeDocument::~RubyClassifierCodeDocument ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+// Make it easier on ourselves
+RubyCodeGenerationPolicy * RubyClassifierCodeDocument::getRubyPolicy() {
+ CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
+ RubyCodeGenerationPolicy * policy = dynamic_cast<RubyCodeGenerationPolicy*>(pe);
+ return policy;
+}
+
+/**
+ * Get the dialog widget which allows user interaction with the object parameters.
+ * @return CodeDocumentDialog
+ */
+/*
+CodeDocumentDialog RubyClassifierCodeDocument::getDialog ( ) {
+
+}
+*/
+
+// We overwritten by Ruby language implementation to get lowercase path
+QString RubyClassifierCodeDocument::getPath ( )
+{
+
+ QString path = getPackage();
+
+ // Replace all white spaces with blanks
+ path.simplifyWhiteSpace();
+
+ // Replace all blanks with underscore
+ path.replace(QRegExp(" "), "_");
+
+ path.replace(QRegExp("\\."),"/");
+ path.replace(QRegExp("::"), "/");
+
+ path.lower();
+
+ return path;
+
+}
+
+
+// Other methods
+//
+
+QString RubyClassifierCodeDocument::getRubyClassName (const QString &name) {
+ CodeGenerator *g = UMLApp::app()->getGenerator();
+ return Codegen_Utils::capitalizeFirstLetter(g->cleanName(name));
+}
+
+// Initialize this ruby classifier code document
+void RubyClassifierCodeDocument::init ( ) {
+
+ setFileExtension(".rb");
+
+ //initCodeClassFields(); // this is dubious because it calls down to
+ // CodeGenFactory::newCodeClassField(this)
+ // but "this" is still in construction at that time.
+
+ classDeclCodeBlock = 0;
+ publicBlock = 0;
+ protectedBlock = 0;
+ privateBlock = 0;
+ pubConstructorBlock = 0;
+ protConstructorBlock = 0;
+ privConstructorBlock = 0;
+ pubOperationsBlock = 0;
+ privOperationsBlock = 0;
+ protOperationsBlock = 0;
+
+ // this will call updateContent() as well as other things that sync our document.
+ synchronize();
+}
+
+/**
+ * @param op
+ */
+// in the vanilla version, we just tack all operations on the end
+// of the document
+bool RubyClassifierCodeDocument::addCodeOperation (CodeOperation * op )
+{
+ Uml::Visibility scope = op->getParentOperation()->getVisibility();
+ if(!op->getParentOperation()->isConstructorOperation())
+ {
+ switch (scope) {
+ default:
+ case Uml::Visibility::Public:
+ return pubOperationsBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Protected:
+ return protOperationsBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Private:
+ return privOperationsBlock->addTextBlock(op);
+ break;
+ }
+ } else {
+ switch (scope) {
+ default:
+ case Uml::Visibility::Public:
+ return pubConstructorBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Protected:
+ return protConstructorBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Private:
+ return privConstructorBlock->addTextBlock(op);
+ break;
+ }
+ }
+}
+
+// Sigh. NOT optimal. The only reason that we need to have this
+// is so we can create the RubyClassDeclarationBlock.
+// would be better if we could create a handler interface that each
+// codeblock used so all we have to do here is add the handler
+// for "rubyclassdeclarationblock"
+void RubyClassifierCodeDocument::loadChildTextBlocksFromNode ( QDomElement & root)
+{
+
+ QDomNode tnode = root.firstChild();
+ QDomElement telement = tnode.toElement();
+ bool loadCheckForChildrenOK = false;
+ while( !telement.isNull() ) {
+ QString nodeName = telement.tagName();
+
+ if( nodeName == "textblocks" ) {
+
+ QDomNode node = telement.firstChild();
+ QDomElement element = node.toElement();
+
+ // if there is nothing to begin with, then we don't worry about it
+ loadCheckForChildrenOK = element.isNull() ? true : false;
+
+ while( !element.isNull() ) {
+ QString name = element.tagName();
+
+ if( name == "codecomment" ) {
+ CodeComment * block = new RubyCodeComment(this);
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"loadFromXMI : unable to add codeComment to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeaccessormethod" ||
+ name == "ccfdeclarationcodeblock"
+ ) {
+ QString acctag = element.attribute("tag","");
+ // search for our method in the
+ TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
+ if(!tb || !addTextBlock(tb))
+ {
+ kError()<<"loadFromXMI : unable to add codeclassfield child method to:"<<this<<endl;
+ // DON'T delete
+ } else
+ loadCheckForChildrenOK= true;
+
+ } else
+ if( name == "codeblock" ) {
+ CodeBlock * block = newCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"loadFromXMI : unable to add codeBlock to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeblockwithcomments" ) {
+ CodeBlockWithComments * block = newCodeBlockWithComments();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"loadFromXMI : unable to add codeBlockwithcomments to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "header" ) {
+ // do nothing.. this is treated elsewhere
+ } else
+ if( name == "hierarchicalcodeblock" ) {
+ HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeoperation" ) {
+ // find the code operation by id
+ QString id = element.attribute("parent_id","-1");
+ UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
+ UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
+ if(op) {
+ CodeOperation * block = new RubyCodeOperation(this, op);
+ block->loadFromXMI(element);
+ if(addTextBlock(block))
+ loadCheckForChildrenOK= true;
+ else
+ {
+ kError()<<"Unable to add codeoperation to:"<<this<<endl;
+ block->deleteLater();
+ }
+ } else
+ kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
+ } else
+ if( name == "rubyclassdeclarationblock" )
+ {
+ RubyClassDeclarationBlock * block = getClassDecl();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add ruby code declaration block to:"<<this<<endl;
+ // DON'T delete.
+ // block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ }
+ // This last item is only needed for extreme debugging conditions
+ // (E.g. making new codeclassdocument loader)
+ // else
+ // kDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"<<endl;
+
+ node = element.nextSibling();
+ element = node.toElement();
+ }
+ break;
+ }
+
+ tnode = telement.nextSibling();
+ telement = tnode.toElement();
+ }
+
+ if(!loadCheckForChildrenOK)
+ {
+ CodeDocument * test = dynamic_cast<CodeDocument*>(this);
+ if(test)
+ {
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
+ } else {
+ HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
+ if(hb)
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
+ else
+ kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
+ }
+ }
+
+
+}
+
+QString RubyClassifierCodeDocument::scopeToRubyDecl(Uml::Visibility scope)
+{
+ QString scopeString;
+ switch(scope)
+ {
+ case Uml::Visibility::Public:
+ scopeString = "public";
+ break;
+ case Uml::Visibility::Protected:
+ scopeString = "protected";
+ break;
+ case Uml::Visibility::Private:
+ default:
+ scopeString = "private";
+ break;
+ }
+ return scopeString;
+}
+
+RubyClassDeclarationBlock * RubyClassifierCodeDocument::getClassDecl()
+{
+ if(!classDeclCodeBlock)
+ {
+ classDeclCodeBlock = new RubyClassDeclarationBlock (this);
+ classDeclCodeBlock->setTag("ClassDeclBlock");
+ }
+ return classDeclCodeBlock;
+}
+
+void RubyClassifierCodeDocument::resetTextBlocks()
+{
+
+ // all special pointers to text blocks need to be zero'd out
+ operationsBlock = 0;
+ constructorBlock = 0;
+ classDeclCodeBlock = 0;
+
+ // now do traditional release of text blocks.
+ ClassifierCodeDocument::resetTextBlocks();
+}
+
+// This method will cause the class to rebuild its text representation.
+// based on the parent classifier object.
+// For any situation in which this is called, we are either building the code
+// document up, or replacing/regenerating the existing auto-generated parts. As
+// such, we will want to insert everything we resonablely will want
+// during creation. We can set various parts of the document (esp. the
+// comments) to appear or not, as needed.
+void RubyClassifierCodeDocument::updateContent( )
+{
+ // Gather info on the various fields and parent objects of this class...
+ UMLClassifier * c = getParentClassifier();
+ RubyCodeGenerator * gen = dynamic_cast<RubyCodeGenerator*>(UMLApp::app()->getGenerator());
+
+ // first, set the global flag on whether or not to show classfield info
+ // This depends on whether or not we have attribute/association classes
+ CodeClassFieldList * cfList = getCodeClassFieldList();
+ for(CodeClassField * field = cfList->first(); field; field = cfList->next())
+ if(field->parentIsAttribute())
+ field->setWriteOutMethods(gen->getAutoGenerateAttribAccessors());
+ else
+ field->setWriteOutMethods(gen->getAutoGenerateAssocAccessors());
+
+ // attribute-based ClassFields
+ // we do it this way to have the static fields sorted out from regular ones
+ CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public );
+ CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public );
+ CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected );
+ CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected );
+ CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private );
+ CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private);
+
+ // association-based ClassFields
+ // don't care if they are static or not..all are lumped together
+ CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Public);
+ CodeClassFieldList publicAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Public);
+ CodeClassFieldList publicCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Public );
+
+ CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Protected);
+ CodeClassFieldList protAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Protected);
+ CodeClassFieldList protCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Protected);
+
+ CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Private);
+ CodeClassFieldList privAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Private);
+ CodeClassFieldList privCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Private);
+
+ bool isInterface = parentIsInterface();
+ bool hasOperationMethods = c->getOpList().last() ? true : false;
+ CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();
+ QString endLine = pol->getNewLineEndingChars(); // a shortcut..so we don't have to call this all the time
+
+ //
+ // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
+ //
+
+
+ // CLASS DECLARATION BLOCK
+ //
+
+ // get the declaration block. If its not already present, add it too
+ RubyClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
+ addTextBlock(myClassDeclCodeBlock); // note: wont add if already present
+
+ // declare public, protected and private methods, attributes (fields).
+ // set the start text ONLY if this is the first time we created the objects.
+ bool createdPublicBlock = publicBlock == 0 ? true : false;
+ publicBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("publicBlock","Public Items",0);
+ if (createdPublicBlock)
+ publicBlock->setStartText("public");
+
+ bool createdProtBlock = protectedBlock == 0 ? true : false;
+ protectedBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("protectedBlock","Protected Items",0);
+ if(createdProtBlock)
+ protectedBlock->setStartText("protected");
+
+ bool createdPrivBlock = privateBlock == 0 ? true : false;
+ privateBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("privateBlock","Private Items",0);
+ if(createdPrivBlock)
+ privateBlock->setStartText("private");
+
+ // NOW create document in sections..
+ // now we want to populate the body of our class
+ // our layout is the following general groupings of code blocks:
+
+ // start ruby classifier document
+
+ // header comment
+
+ // class declaration
+
+ // section:
+
+ // section:
+ // - methods section comment
+
+ // sub-section: constructor ops
+ // - constructor method section comment
+ // - constructor methods (0+ codeblocks)
+
+ // sub-section: accessors
+ // - accessor method section comment
+ // - static accessor methods (0+ codeblocks)
+ // - non-static accessor methods (0+ codeblocks)
+
+ // sub-section: non-constructor ops
+ // - operation method section comment
+ // - operations (0+ codeblocks)
+
+ // end class declaration
+
+ // end ruby classifier document
+
+
+ // Q: Why use the more complicated scheme of arranging code blocks within codeblocks?
+ // A: This will allow us later to preserve the format of our document so that if
+ // codeblocks are added, they may be easily added in the correct place, rather than at
+ // the end of the document, or by using a difficult algorithm to find the location of
+ // the last appropriate code block sibling (which may not exist.. for example user adds
+ // a constructor operation, but there currently are no constructor code blocks
+ // within the document).
+
+
+ //
+ // METHODS section
+ //
+
+ // get/create the method codeblock
+ // public methods
+ HierarchicalCodeBlock * pubMethodsBlock = publicBlock->getHierarchicalCodeBlock("pubMethodsBlock", "", 1);
+ CodeComment * pubMethodsComment = pubMethodsBlock->getComment();
+ bool forceDoc = pol->getCodeVerboseDocumentComments();
+ // set conditions for showing this comment
+ if (!forceDoc && !hasClassFields() && !hasOperationMethods)
+ pubMethodsComment->setWriteOutText(false);
+ else
+ pubMethodsComment->setWriteOutText(true);
+
+ // protected methods
+ HierarchicalCodeBlock * protMethodsBlock = protectedBlock->getHierarchicalCodeBlock("protMethodsBlock", "", 1);
+ CodeComment * protMethodsComment = protMethodsBlock->getComment();
+ // set conditions for showing this comment
+ if (!forceDoc && !hasClassFields() && !hasOperationMethods)
+ protMethodsComment->setWriteOutText(false);
+ else
+ protMethodsComment->setWriteOutText(true);
+
+ // private methods
+ HierarchicalCodeBlock * privMethodsBlock = privateBlock->getHierarchicalCodeBlock("privMethodsBlock", "", 1);
+ CodeComment * privMethodsComment = privMethodsBlock->getComment();
+ // set conditions for showing this comment
+ if (!forceDoc && !hasClassFields() && !hasOperationMethods)
+ privMethodsComment->setWriteOutText(false);
+ else
+ privMethodsComment->setWriteOutText(true);
+
+ // METHODS sub-section : constructor methods
+ //
+
+ // public
+ pubConstructorBlock = pubMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
+ // special condiions for showing comment: only when autogenerateding empty constructors
+ // Although, we *should* check for other constructor methods too
+ CodeComment * pubConstComment = pubConstructorBlock->getComment();
+ if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
+ pubConstComment->setWriteOutText(false);
+ else
+ pubConstComment->setWriteOutText(true);
+
+ // protected
+ protConstructorBlock = protMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
+ // special condiions for showing comment: only when autogenerateding empty constructors
+ // Although, we *should* check for other constructor methods too
+ CodeComment * protConstComment = protConstructorBlock->getComment();
+ if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
+ protConstComment->setWriteOutText(false);
+ else
+ protConstComment->setWriteOutText(true);
+
+ // private
+ privConstructorBlock = privMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
+ // special condiions for showing comment: only when autogenerateding empty constructors
+ // Although, we *should* check for other constructor methods too
+ CodeComment * privConstComment = privConstructorBlock->getComment();
+ if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
+ privConstComment->setWriteOutText(false);
+ else
+ privConstComment->setWriteOutText(true);
+
+ // get/create the accessor codeblock
+ // public
+ HierarchicalCodeBlock * pubAccessorBlock = pubMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
+ // set conditions for showing section comment
+ CodeComment * pubAccessComment = pubAccessorBlock->getComment();
+ if (!forceDoc && !hasClassFields())
+ pubAccessComment->setWriteOutText(false);
+ else
+ pubAccessComment->setWriteOutText(true);
+
+ // protected
+ HierarchicalCodeBlock * protAccessorBlock = protMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
+ // set conditions for showing section comment
+ CodeComment * protAccessComment = protAccessorBlock->getComment();
+ if (!forceDoc && !hasClassFields())
+ protAccessComment->setWriteOutText(false);
+ else
+ protAccessComment->setWriteOutText(true);
+
+ // private
+ HierarchicalCodeBlock * privAccessorBlock = privMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
+ // set conditions for showing section comment
+ CodeComment * privAccessComment = privAccessorBlock->getComment();
+ if (!forceDoc && !hasClassFields())
+ privAccessComment->setWriteOutText(false);
+ else
+ privAccessComment->setWriteOutText(true);
+
+ // now, 2 sub-sub sections in accessor block
+ // add/update accessor methods for attributes
+ HierarchicalCodeBlock * pubStaticAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubStaticAccessorMethods", "", 1);
+ HierarchicalCodeBlock * pubRegularAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubRegularAccessorMethods", "", 1);
+ pubStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
+ pubRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
+
+ HierarchicalCodeBlock * protStaticAccessors = protAccessorBlock->getHierarchicalCodeBlock("protStaticAccessorMethods", "", 1);
+ HierarchicalCodeBlock * protRegularAccessors = protAccessorBlock->getHierarchicalCodeBlock("protRegularAccessorMethods", "", 1);
+ protStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
+ protRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
+
+ HierarchicalCodeBlock * privStaticAccessors = privAccessorBlock->getHierarchicalCodeBlock("privStaticAccessorMethods", "", 1);
+ HierarchicalCodeBlock * privRegularAccessors = privAccessorBlock->getHierarchicalCodeBlock("privRegularAccessorMethods", "", 1);
+ privStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
+ privRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
+ // now add in accessors as appropriate
+
+ // public stuff
+ pubStaticAccessors->addCodeClassFieldMethods(staticPublicAttribClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(publicAttribClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(publicPlainAssocClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(publicAggregationClassFields);
+ pubRegularAccessors->addCodeClassFieldMethods(publicCompositionClassFields);
+
+ // protected stuff
+ protStaticAccessors->addCodeClassFieldMethods(staticProtectedAttribClassFields);
+ protRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
+ protRegularAccessors->addCodeClassFieldMethods(protPlainAssocClassFields);
+ protRegularAccessors->addCodeClassFieldMethods(protAggregationClassFields);
+ protRegularAccessors->addCodeClassFieldMethods(protCompositionClassFields);
+
+ // private stuff
+ privStaticAccessors->addCodeClassFieldMethods(staticPrivateAttribClassFields);
+ privRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
+ privRegularAccessors->addCodeClassFieldMethods(privPlainAssocClassFields);
+ privRegularAccessors->addCodeClassFieldMethods(privAggregationClassFields);
+ privRegularAccessors->addCodeClassFieldMethods(privCompositionClassFields);
+
+ // METHODS subsection : Operation methods (which aren't constructors)
+ //
+
+ // setup/get/create the operations codeblock
+
+ // public
+ pubOperationsBlock = pubMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
+ // set conditions for showing section comment
+ CodeComment * pubOcomment = pubOperationsBlock->getComment();
+ if (!forceDoc && !hasOperationMethods )
+ pubOcomment->setWriteOutText(false);
+ else
+ pubOcomment->setWriteOutText(true);
+
+ //protected
+ protOperationsBlock = protMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
+ // set conditions for showing section comment
+ CodeComment * protOcomment = protOperationsBlock->getComment();
+ if (!forceDoc && !hasOperationMethods )
+ protOcomment->setWriteOutText(false);
+ else
+ protOcomment->setWriteOutText(true);
+
+ //private
+ privOperationsBlock = privMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
+ // set conditions for showing section comment
+ CodeComment * privOcomment = privOperationsBlock->getComment();
+ if (!forceDoc && !hasOperationMethods )
+ privOcomment->setWriteOutText(false);
+ else
+ privOcomment->setWriteOutText(true);
+
+}
+
+
+#include "rubyclassifiercodedocument.moc"
diff --git a/umbrello/umbrello/codegenerators/rubyclassifiercodedocument.h b/umbrello/umbrello/codegenerators/rubyclassifiercodedocument.h
new file mode 100644
index 00000000..c5f89d07
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubyclassifiercodedocument.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ rubyclassdeclarationblock.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+
+#ifndef RUBYCLASSIFIERCODEDOCUMENT_H
+#define RUBYCLASSIFIERCODEDOCUMENT_H
+
+#include <qstring.h>
+
+#include "../codeclassfieldlist.h"
+#include "../classifiercodedocument.h"
+#include "../classifier.h"
+#include "../hierarchicalcodeblock.h"
+#include "classifierinfo.h"
+#include "rubycodeclassfield.h"
+#include "rubycodeoperation.h"
+
+class RubyClassDeclarationBlock;
+class RubyCodeGenerationPolicy;
+
+/**
+ * class RubyClassifierCodeDocument
+ * A Ruby UMLClassifier Code Document.
+ */
+
+class RubyClassifierCodeDocument : public ClassifierCodeDocument
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructor
+ */
+ RubyClassifierCodeDocument (UMLClassifier * classifier);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyClassifierCodeDocument ( );
+
+ /**
+ * Get the dialog widget which allows user interaction with the object parameters.
+ * @return CodeDocumentDialog
+ */
+ //CodeDocumentDialog getDialog ( );
+
+ QString scopeToRubyDecl(Uml::Visibility scope);
+
+ // Make it easier on ourselves
+ RubyCodeGenerationPolicy * getRubyPolicy();
+
+ QString getRubyClassName (const QString &name);
+
+ QString getPath();
+
+ /** add a code operation to this ruby classifier code document.
+ * @return bool which is true IF the code operation was added successfully
+ */
+ bool addCodeOperation (CodeOperation * op );
+
+protected:
+
+ // reset/clear our inventory of textblocks in this document
+ void resetTextBlocks();
+
+ /**
+ * need to overwrite this for ruby since we need to pick up the
+ * ruby class declaration block.
+ */
+ virtual void loadChildTextBlocksFromNode ( QDomElement & root);
+
+ void addOrUpdateCodeClassFieldMethodsInCodeBlock(CodeClassFieldList &list, RubyClassDeclarationBlock * codeBlock);
+
+ bool forceDoc ();
+
+ void updateContent();
+
+private:
+
+ RubyClassDeclarationBlock * classDeclCodeBlock;
+ HierarchicalCodeBlock * constructorBlock;
+ HierarchicalCodeBlock * operationsBlock;
+
+ HierarchicalCodeBlock * publicBlock;
+ HierarchicalCodeBlock * privateBlock;
+ HierarchicalCodeBlock * protectedBlock;
+
+// HierarchicalCodeBlock * namespaceBlock;
+
+ HierarchicalCodeBlock * pubConstructorBlock;
+ HierarchicalCodeBlock * protConstructorBlock;
+ HierarchicalCodeBlock * privConstructorBlock;
+
+ HierarchicalCodeBlock * pubOperationsBlock;
+ HierarchicalCodeBlock * privOperationsBlock;
+ HierarchicalCodeBlock * protOperationsBlock;
+
+ ClassifierInfo * info;
+
+ void init ( );
+ RubyClassDeclarationBlock * getClassDecl();
+
+
+};
+
+#endif // RUBYCLASSIFIERCODEDOCUMENT_H
diff --git a/umbrello/umbrello/codegenerators/rubycodeaccessormethod.cpp b/umbrello/umbrello/codegenerators/rubycodeaccessormethod.cpp
new file mode 100644
index 00000000..a3f55c44
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeaccessormethod.cpp
@@ -0,0 +1,233 @@
+/***************************************************************************
+ rubycodeaccessormethod.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "rubycodeaccessormethod.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "../attribute.h"
+#include "../codegenerator.h"
+#include "../classifiercodedocument.h"
+#include "../umlobject.h"
+#include "../umlrole.h"
+#include "../uml.h"
+#include "codegen_utils.h"
+#include "rubyclassifiercodedocument.h"
+#include "rubycodegenerationpolicy.h"
+#include "rubycodegenerator.h"
+#include "rubycodeclassfield.h"
+#include "rubycodedocumentation.h"
+
+// Constructors/Destructors
+//
+
+RubyCodeAccessorMethod::RubyCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type)
+ : CodeAccessorMethod ( field )
+{
+ setType(type);
+
+ // lets use full-blown comment
+ RubyClassifierCodeDocument *rccd = dynamic_cast<RubyClassifierCodeDocument*>(field->getParentDocument());
+ setComment(new RubyCodeDocumentation(rccd));
+}
+
+RubyCodeAccessorMethod::~RubyCodeAccessorMethod ( ) { }
+
+// Other methods
+//
+
+void RubyCodeAccessorMethod::setAttributesOnNode ( QDomDocument & doc, QDomElement & blockElement)
+{
+
+ // set super-class attributes
+ CodeAccessorMethod::setAttributesOnNode(doc, blockElement);
+
+ // set local attributes now
+}
+
+void RubyCodeAccessorMethod::setAttributesFromNode( QDomElement & root)
+{
+
+ // set attributes from superclass method the XMI
+ CodeAccessorMethod::setAttributesFromNode(root);
+
+ // load local stuff
+
+}
+
+void RubyCodeAccessorMethod::updateContent( )
+{
+
+ CodeClassField * parentField = getParentClassField();
+ RubyCodeClassField * rubyfield = dynamic_cast<RubyCodeClassField*>(parentField);
+ QString fieldName = rubyfield->getFieldName();
+ QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
+
+ QString text = "";
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ {
+ int maxOccurs = rubyfield->maximumListOccurances();
+ QString fieldType = rubyfield->getTypeName();
+ QString indent = getIndentation();
+ if(maxOccurs > 0)
+ text += "if "+fieldName+".size() < "+ QString::number(maxOccurs)+' '+endLine+indent;
+ text += fieldName+".push(value)";
+ if(maxOccurs > 0)
+ {
+ text += endLine+"else"+endLine;
+ text += indent + "puts(\"ERROR: Can't add"+fieldType+" to "+fieldName+", minimum number of items reached.\")"+endLine+"end"+endLine;
+ }
+ break;
+ }
+ case CodeAccessorMethod::GET:
+// text = "return "+fieldName;
+ break;
+ case CodeAccessorMethod::LIST:
+ text = "return "+fieldName;
+ break;
+ case CodeAccessorMethod::REMOVE:
+ {
+ int minOccurs = rubyfield->minimumListOccurances();
+ RubyClassifierCodeDocument * rubydoc = dynamic_cast<RubyClassifierCodeDocument*>(rubyfield->getParentDocument());
+ QString fieldType = rubyfield->getTypeName();
+ QString indent = getIndentation();
+
+ if(minOccurs > 0)
+ text += "if "+fieldName+".size() >= "+ QString::number(minOccurs)+endLine+indent;
+ text += fieldName+".delete(value)";
+ if(minOccurs > 0)
+ {
+ text += endLine+"else"+endLine;
+ text += indent + "puts(\"ERROR: Cant remove"+fieldType+" from "+fieldName+", minimum number of items reached.\")"+endLine+"end"+endLine;
+ }
+ break;
+ }
+ case CodeAccessorMethod::SET:
+// text = fieldName+" = value";
+ break;
+ default:
+ // do nothing
+ break;
+ }
+
+ setText(text);
+
+}
+
+void RubyCodeAccessorMethod::updateMethodDeclaration()
+{
+
+ RubyCodeClassField * rubyfield = dynamic_cast<RubyCodeClassField*>(getParentClassField());
+ RubyClassifierCodeDocument * rubydoc = dynamic_cast<RubyClassifierCodeDocument*>(rubyfield->getParentDocument());
+
+ // gather defs
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ CodeGenerationPolicy::ScopePolicy scopePolicy = p->getAttributeAccessorScope();
+ QString strVis = rubydoc->scopeToRubyDecl(rubyfield->getVisibility());
+ QString fieldName = RubyCodeGenerator::cppToRubyName(rubyfield->getFieldName());
+ QString fieldType = RubyCodeGenerator::cppToRubyType(rubyfield->getTypeName());
+ QString objectType = rubyfield->getListObjectType();
+ if(objectType.isEmpty())
+ objectType = fieldName;
+ QString endLine = p->getNewLineEndingChars();
+
+ QString description = getParentObject()->getDoc();
+ description.replace(QRegExp("m_[npb](?=[A-Z])"), "");
+ description.replace("m_", "");
+ description.replace(QRegExp("[\\n\\r]+[\\t ]*"), endLine);
+
+ // set scope of this accessor appropriately..if its an attribute,
+ // we need to be more sophisticated
+ if(rubyfield->parentIsAttribute())
+ switch (scopePolicy) {
+ case CodeGenerationPolicy::Public:
+ case CodeGenerationPolicy::Private:
+ case CodeGenerationPolicy::Protected:
+ strVis = rubydoc->scopeToRubyDecl((Uml::Visibility::Value) scopePolicy);
+ break;
+ default:
+ case CodeGenerationPolicy::FromParent:
+ // do nothing..already have taken parent value
+ break;
+ }
+
+ // some variables we will need to populate
+ QString headerText = "";
+ QString methodReturnType = "";
+ QString methodName = "";
+ QString methodParams = "";
+
+ switch(getType()) {
+ case CodeAccessorMethod::ADD:
+ methodName = "add" + Codegen_Utils::capitalizeFirstLetter(fieldType);
+ methodReturnType = "";
+ methodParams = objectType+" value ";
+ headerText = "Add an object of type "+objectType+" to the Array "+fieldName+endLine+description+endLine+"@return nil";
+ setStartMethodText("def "+ methodName + '(' + methodParams + ')');
+ setEndMethodText("end");
+ break;
+ case CodeAccessorMethod::GET:
+ headerText = "Get the value of " + fieldName + endLine + description;
+ setStartMethodText(QString("attr_reader :") + fieldName);
+ setEndMethodText("");
+ break;
+ case CodeAccessorMethod::LIST:
+ methodName = "get" + Codegen_Utils::capitalizeFirstLetter(fieldType)+"List";
+ methodReturnType = "";
+ headerText = "Get the list of "+fieldName+endLine+description+endLine+"_returns_ List of "+fieldName;
+ setStartMethodText("def "+ methodName + '(' + methodParams + ')');
+ setEndMethodText("end");
+ break;
+ case CodeAccessorMethod::REMOVE:
+ methodName = "remove" + Codegen_Utils::capitalizeFirstLetter(fieldType);
+ methodReturnType = "";
+ methodParams = objectType+" value ";
+ headerText = "Remove an object of type "+objectType+" from the List "+fieldName+endLine+description;
+ setStartMethodText("def "+ methodName + '(' + methodParams + ')');
+ setEndMethodText("end");
+ break;
+ case CodeAccessorMethod::SET:
+ headerText = "Set the value of " + fieldName + endLine + description;
+ setStartMethodText(QString("attr_writer :") + fieldName);
+ setEndMethodText("");
+ break;
+ default:
+ // do nothing..no idea what this is
+ kWarning()<<"Warning: can't generate RubyCodeAccessorMethod for type: "<<getType()<<endl;
+ break;
+ }
+
+ // set header once.
+ if (getComment()->getText().isEmpty())
+ getComment()->setText(headerText);
+
+}
+
+void RubyCodeAccessorMethod::update()
+{
+ updateMethodDeclaration();
+ updateContent();
+}
+
+#include "rubycodeaccessormethod.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodeaccessormethod.h b/umbrello/umbrello/codegenerators/rubycodeaccessormethod.h
new file mode 100644
index 00000000..7eb9c892
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeaccessormethod.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ rubycodeaccessormethod.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Oct 2 2003
+ */
+
+#ifndef RUBYCODEACCESSORMETHOD_H
+#define RUBYCODEACCESSORMETHOD_H
+
+#include <qstring.h>
+
+#include "../codeaccessormethod.h"
+#include "rubycodeclassfield.h"
+
+class RubyCodeAccessorMethod : public CodeAccessorMethod
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ RubyCodeAccessorMethod ( CodeClassField * field, CodeAccessorMethod::AccessorType type);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeAccessorMethod ( );
+
+ /**
+ * Must be called before this object is usable
+ */
+ void update();
+
+protected:
+
+ /** set attributes of the node that represents this class
+ * in the XMI document.
+ */
+ virtual void setAttributesOnNode ( QDomDocument & doc, QDomElement & blockElement);
+
+ /** set the class attributes of this object from
+ * the passed element node.
+ */
+ virtual void setAttributesFromNode ( QDomElement & element);
+
+ virtual void updateMethodDeclaration();
+ virtual void updateContent();
+
+private:
+
+};
+
+#endif // RUBYCODEACCESSORMETHOD_H
diff --git a/umbrello/umbrello/codegenerators/rubycodeclassfield.cpp b/umbrello/umbrello/codegenerators/rubycodeclassfield.cpp
new file mode 100644
index 00000000..35438abd
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeclassfield.cpp
@@ -0,0 +1,113 @@
+/***************************************************************************
+ rubycodeclassfield.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "rubycodeclassfield.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "rubycodecomment.h"
+#include "rubycodegenerator.h"
+
+#include "../attribute.h"
+#include "../umlobject.h"
+#include "../umlrole.h"
+#include "../uml.h"
+
+#include "rubyclassifiercodedocument.h"
+
+// Constructors/Destructors
+//
+
+RubyCodeClassField::RubyCodeClassField (ClassifierCodeDocument * parentDoc, UMLRole * role)
+ : CodeClassField(parentDoc, role)
+{
+
+}
+
+RubyCodeClassField::RubyCodeClassField (ClassifierCodeDocument * parentDoc, UMLAttribute * attrib)
+ : CodeClassField(parentDoc, attrib)
+{
+
+}
+
+RubyCodeClassField::~RubyCodeClassField ( ) { }
+
+//
+// Methods
+//
+
+// Other methods
+//
+
+QString RubyCodeClassField::getFieldName() {
+ if (parentIsAttribute())
+ {
+ UMLAttribute * at = (UMLAttribute*) getParentObject();
+ return cleanName(at->getName());
+ }
+ else
+ {
+ UMLRole * role = (UMLRole*) getParentObject();
+ QString roleName = role->getName();
+ if(fieldIsSingleValue()) {
+ return roleName.replace(0, 1, roleName.left(1).lower());
+ } else {
+ return roleName.lower() + "Array";
+ }
+ }
+}
+
+
+QString RubyCodeClassField::getInitialValue() {
+
+ if (parentIsAttribute())
+ {
+ UMLAttribute * at = dynamic_cast<UMLAttribute*>( getParentObject() );
+ if (at) {
+ return fixInitialStringDeclValue(at->getInitialValue(), getTypeName());
+ } else {
+ kError() << "RubyodeClassField::getInitialValue: parent object is not a UMLAttribute"
+ << endl;
+ return "";
+ }
+ return fixInitialStringDeclValue(at->getInitialValue(), getTypeName());
+ }
+ else
+ {
+ if(fieldIsSingleValue()) {
+ // FIX : IF the multiplicity is "1" then we should init a new object here, if its 0 or 1,
+ // then we can just return 'empty' string (minor problem).
+ return QString("");
+ } else {
+ return RubyCodeGenerator::getListFieldClassName()+".new()";
+ }
+ }
+
+}
+
+QString RubyCodeClassField::getTypeName ( )
+{
+ return RubyCodeGenerator::cppToRubyType(CodeClassField::getTypeName());
+}
+
+#include "rubycodeclassfield.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodeclassfield.h b/umbrello/umbrello/codegenerators/rubycodeclassfield.h
new file mode 100644
index 00000000..384f0b5d
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeclassfield.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ rubycodeclassfield.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODECLASSFIELD_H
+#define RUBYCODECLASSFIELD_H
+
+#include <qstring.h>
+
+#include "../codeclassfield.h"
+
+class ClassifierCodeDocument;
+
+class RubyCodeClassField : public CodeClassField
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructors
+ */
+ RubyCodeClassField (ClassifierCodeDocument * parentDoc, UMLRole * role);
+ RubyCodeClassField (ClassifierCodeDocument * parentDoc, UMLAttribute * attrib);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeClassField ( );
+
+ QString getFieldType();
+ QString getFieldName();
+ QString getInitialValue();
+
+ QString getTypeName ( );
+protected:
+
+private:
+
+ // void initDeclCodeBlock ();
+
+};
+
+#endif // RUBYCODECLASSFIELD_H
diff --git a/umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.cpp b/umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.cpp
new file mode 100644
index 00000000..380c05e0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.cpp
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * *
+ * 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) 2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#include "rubycodeclassfielddeclarationblock.h"
+
+#include "rubycodeclassfield.h"
+#include "rubyclassifiercodedocument.h"
+#include "rubycodegenerationpolicy.h"
+#include "../classifier.h"
+#include "../umlrole.h"
+#include "../codegenerator.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+RubyCodeClassFieldDeclarationBlock::RubyCodeClassFieldDeclarationBlock ( CodeClassField * parent )
+ : CodeClassFieldDeclarationBlock ( parent )
+{
+ setOverallIndentationLevel(1);
+ updateContent();
+}
+
+RubyCodeClassFieldDeclarationBlock::~RubyCodeClassFieldDeclarationBlock ( ) { }
+
+//
+// Methods
+//
+
+
+
+// Other methods
+//
+
+/**
+ */
+void RubyCodeClassFieldDeclarationBlock::updateContent( )
+{
+
+ CodeClassField * cf = getParentClassField();
+ ClassifierCodeDocument * doc = cf->getParentDocument();
+ RubyCodeClassField * rcf = dynamic_cast<RubyCodeClassField*>(cf);
+ RubyClassifierCodeDocument* rdoc = dynamic_cast<RubyClassifierCodeDocument*>(doc);
+ CodeGenerationPolicy * p = UMLApp::app()->getCommonPolicy();
+ CodeGenerationPolicy::ScopePolicy scopePolicy = p->getAssociationFieldScope();
+
+ // Set the comment
+ QString notes = getParentObject()->getDoc();
+ getComment()->setText(notes);
+
+ // Set the body
+ QString staticValue = getParentObject()->getStatic() ? "static " : "";
+ QString scopeStr = rdoc->scopeToRubyDecl(getParentObject()->getVisibility());
+
+ // IF this is from an association, then scope taken as appropriate to policy
+ if(!rcf->parentIsAttribute())
+ {
+ switch (scopePolicy) {
+ case CodeGenerationPolicy::Public:
+ case CodeGenerationPolicy::Private:
+ case CodeGenerationPolicy::Protected:
+ scopeStr = rdoc->scopeToRubyDecl((Uml::Visibility::Value) scopePolicy);
+ break;
+ default:
+ case CodeGenerationPolicy::FromParent:
+ // do nothing here... will leave as from parent object
+ break;
+ }
+ }
+
+ QString typeName = rcf->getTypeName();
+ QString fieldName = rcf->getFieldName();
+ QString initialV = rcf->getInitialValue();
+
+ if (!cf->parentIsAttribute() && !cf->fieldIsSingleValue())
+ typeName = "Array";
+
+ QString body = staticValue+scopeStr+' '+typeName+' '+fieldName;
+ if (!initialV.isEmpty())
+ body.append(" = " + initialV);
+ else if (!cf->parentIsAttribute())
+ {
+ UMLRole * role = dynamic_cast<UMLRole*>(cf->getParentObject());
+ if (role->getObject()->getBaseType() == Uml::ot_Interface)
+ {
+ // do nothing.. can't instanciate an interface
+ } else {
+
+ // FIX?: IF a constructor method exists in the classifiercodedoc
+ // of the parent Object, then we can use that instead (if its empty).
+ if(cf->fieldIsSingleValue())
+ {
+ if(!typeName.isEmpty())
+ body.append(" = " + typeName + ".new()");
+ } else
+ body.append(" = []");
+ }
+ }
+
+ setText(body);
+
+}
+
+#include "rubycodeclassfielddeclarationblock.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.h b/umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.h
new file mode 100644
index 00000000..c3e18a68
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeclassfielddeclarationblock.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ rubycodeclassfielddeclarationblock.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODECLASSFIELDDECLARATIONBLOCK_H
+#define RUBYCODECLASSFIELDDECLARATIONBLOCK_H
+
+#include <qstring.h>
+
+#include "../codeclassfielddeclarationblock.h"
+
+class RubyCodeClassFieldDeclarationBlock : public CodeClassFieldDeclarationBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructor
+ */
+ RubyCodeClassFieldDeclarationBlock ( CodeClassField * parent );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeClassFieldDeclarationBlock ( );
+
+protected:
+
+ // this will be called by syncToParent whenever the parent object is "modified"
+ void updateContent ( );
+
+private:
+
+
+};
+
+#endif // RUBYCODECLASSFIELDDECLARATIONBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/rubycodecomment.cpp b/umbrello/umbrello/codegenerators/rubycodecomment.cpp
new file mode 100644
index 00000000..46374128
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodecomment.cpp
@@ -0,0 +1,85 @@
+/***************************************************************************
+ rubycodecomment.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#include "rubycodecomment.h"
+#include <qregexp.h>
+
+// Constructors/Destructors
+//
+
+RubyCodeComment::RubyCodeComment(CodeDocument * doc, const QString & text)
+ : CodeComment(doc, text)
+{
+
+}
+
+RubyCodeComment::~RubyCodeComment( ) { }
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+
+// Public attribute accessor methods
+//
+
+// Other methods
+//
+
+QString RubyCodeComment::getNewEditorLine( int amount ) {
+ QString line = getIndentationString(amount) + "# ";
+ return line;
+}
+
+/** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+QString RubyCodeComment::unformatText(const QString & text, const QString & indent)
+{
+ // remove leading or trailing comment stuff
+ QString mytext = TextBlock::unformatText(text, indent);
+
+ // now leading hash
+ mytext.remove(QRegExp("^#\\s*"));
+ return mytext;
+}
+
+/**
+ * @return QString
+ */
+QString RubyCodeComment::toString( )
+{
+ QString output = "";
+
+ // simple output method
+ if (getWriteOutText()) {
+ QString indent = getIndentationString();
+ QString endLine = getNewLineEndingChars();
+ output.append(formatMultiLineText(getText(), indent + "# ", endLine + endLine));
+ }
+
+ return output;
+}
+
+
+#include "rubycodecomment.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodecomment.h b/umbrello/umbrello/codegenerators/rubycodecomment.h
new file mode 100644
index 00000000..35fb87a8
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodecomment.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ rubycodecomment.h
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODECOMMENT_H
+#define RUBYCODECOMMENT_H
+
+#include <qstring.h>
+#include "../codecomment.h"
+
+/**
+ * class RubyCodeComment
+ * A Ruby code comment. There are two styles of comments:
+ * these are simply started with a hash and no terminating
+ * characters, or delimited by '=begin' and '=end' tags at the
+ * start of lines
+ */
+
+class RubyCodeComment : virtual public CodeComment
+{
+ Q_OBJECT
+public:
+ /**
+ * Constructors
+ */
+ explicit RubyCodeComment ( CodeDocument * doc, const QString & text = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeComment ( );
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+ /** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+ virtual QString unformatText ( const QString & text, const QString & indent = "" );
+
+ /** a special version here because we want to not only indent
+ * the new line, but to add the "#" as well.
+ */
+ virtual QString getNewEditorLine ( int amount );
+
+protected:
+
+private:
+
+};
+
+#endif // RUBYCODECOMMENT_H
diff --git a/umbrello/umbrello/codegenerators/rubycodedocumentation.cpp b/umbrello/umbrello/codegenerators/rubycodedocumentation.cpp
new file mode 100644
index 00000000..6c69530a
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodedocumentation.cpp
@@ -0,0 +1,145 @@
+/***************************************************************************
+ rubycodedocumentation.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "rubycodedocumentation.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "rubyclassifiercodedocument.h"
+#include "rubycodegenerationpolicy.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+RubyCodeDocumentation::RubyCodeDocumentation ( RubyClassifierCodeDocument * doc, const QString & text )
+ : CodeComment ((CodeDocument*) doc, text)
+{
+
+}
+
+RubyCodeDocumentation::~RubyCodeDocumentation ( ) { }
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * Save the XMI representation of this object
+ */
+void RubyCodeDocumentation::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "rubycodedocumentation" );
+ setAttributesOnNode(doc, blockElement); // as we added no additional fields to this class we may
+ // just use parent TextBlock method
+ root.appendChild( blockElement );
+}
+
+/**
+ * @return QString
+ */
+QString RubyCodeDocumentation::toString ( )
+{
+
+ QString output = "";
+
+ // simple output method
+ if(getWriteOutText())
+ {
+ bool useHashOutput = true;
+
+ // need to figure out output type from ruby policy
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ useHashOutput = false;
+
+ QString indent = getIndentationString();
+ QString endLine = getNewLineEndingChars();
+ QString body = getText();
+ if( useHashOutput)
+ {
+ if(!body.isEmpty())
+ output.append(formatMultiLineText (body, indent +"# ", endLine));
+ } else {
+ output.append("=begin rdoc"+endLine);
+ output.append(formatMultiLineText (body, indent +' ', endLine));
+ output.append("=end"+endLine);
+ }
+ }
+
+ return output;
+}
+
+QString RubyCodeDocumentation::getNewEditorLine ( int amount )
+{
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ return getIndentationString(amount) + ' ';
+ else
+ return getIndentationString(amount) + "# ";
+}
+
+int RubyCodeDocumentation::firstEditableLine() {
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ return 1;
+ return 0;
+}
+
+int RubyCodeDocumentation::lastEditableLine() {
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ {
+ return -1; // very last line is NOT editable
+ }
+ return 0;
+}
+
+/** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+QString RubyCodeDocumentation::unformatText ( const QString & text , const QString & indent)
+{
+
+ QString mytext = TextBlock::unformatText(text, indent);
+ CodeGenerationPolicy *p = UMLApp::app()->getCommonPolicy();
+ // remove leading or trailing comment stuff
+ mytext.remove(QRegExp('^'+indent));
+ if(p->getCommentStyle() == CodeGenerationPolicy::MultiLine)
+ {
+ mytext.remove(QRegExp("^=begin\\s*(rdoc)?\\s*\n?"));
+ mytext.remove(QRegExp("^=end\\s*\n?$"));
+ } else
+ mytext.remove(QRegExp("^#\\s*"));
+
+ return mytext;
+}
+
+
+#include "rubycodedocumentation.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodedocumentation.h b/umbrello/umbrello/codegenerators/rubycodedocumentation.h
new file mode 100644
index 00000000..72908f78
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodedocumentation.h
@@ -0,0 +1,97 @@
+/***************************************************************************
+ rubycodedocumentation.h
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODEDOCUMENTATION_H
+#define RUBYCODEDOCUMENTATION_H
+
+#include <qstring.h>
+#include "../codecomment.h"
+
+class RubyClassifierCodeDocument;
+
+/**
+ * class RubyCodeDocumentation
+ * A Ruby code comment. There is only a single styles of comments:
+ * these are simply started with a hash and no terminating
+ * characters
+ */
+
+class RubyCodeDocumentation : virtual public CodeComment
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructors
+ */
+ explicit RubyCodeDocumentation ( RubyClassifierCodeDocument * doc, const QString & text = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeDocumentation ( );
+
+ // Public attributes
+ //
+
+ // Other
+ //
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+ /** UnFormat a long text string. Typically, this means removing
+ * the indentaion (linePrefix) and/or newline chars from each line.
+ */
+ virtual QString unformatText ( const QString & text, const QString & indent = "" );
+
+ /** a special version here because we want to not only indent
+ * the new line, but to add the "# " sequence as well.
+ */
+ virtual QString getNewEditorLine ( int amount );
+
+ /** Ush. These are terrifically bad and must one day go away.
+ * Both methods indicate the range of lines in this textblock
+ * which may be edited by the codeeditor (assuming that any are
+ * actually editable). The default case is no lines are editable.
+ * The line numbering starts with '0' and a '-1' means no line
+ * qualifies.
+ */
+ virtual int firstEditableLine();
+ virtual int lastEditableLine();
+
+
+protected:
+
+private:
+
+};
+
+#endif // RUBYCODEDOCUMENTATION_H
diff --git a/umbrello/umbrello/codegenerators/rubycodegenerationformbase.ui b/umbrello/umbrello/codegenerators/rubycodegenerationformbase.ui
new file mode 100644
index 00000000..14bcf0f2
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodegenerationformbase.ui
@@ -0,0 +1,248 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>RubyCodeGenerationFormBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>462</width>
+ <height>376</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="2" column="0">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Auto-Generate Methods</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>m_generateConstructors</cstring>
+ </property>
+ <property name="text">
+ <string>Empty constructor methods</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>m_generateAssocAccessors</cstring>
+ </property>
+ <property name="text">
+ <string>Association accessor methods</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>m_generateAttribAccessors</cstring>
+ </property>
+ <property name="text">
+ <string>Attribute accessor methods</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox" row="0" column="1">
+ <item>
+ <property name="text">
+ <string>Public</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Private</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Protected</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>From Parent Object</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_accessorScopeCB</cstring>
+ </property>
+ <property name="currentItem">
+ <number>3</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Default attribute accessor scope:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Default association field scope:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <item>
+ <property name="text">
+ <string>Public</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Private</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Protected</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>From Parent Role</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_assocFieldScopeCB</cstring>
+ </property>
+ <property name="currentItem">
+ <number>3</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Documentation</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Style:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>Hash (#)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Begin-End (=begin =end)</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_SelectCommentStyle</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p align="center"&gt;Ruby Code Generation&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/umbrello/umbrello/codegenerators/rubycodegenerationpolicy.cpp b/umbrello/umbrello/codegenerators/rubycodegenerationpolicy.cpp
new file mode 100644
index 00000000..1a01421a
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodegenerationpolicy.cpp
@@ -0,0 +1,170 @@
+/***************************************************************************
+ rubycodegenerationpolicy.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "rubycodegenerationpolicy.h"
+// qt/kde includes
+#include <kconfig.h>
+// app includes
+#include "rubycodegenerationpolicypage.h"
+#include "rubycodegenerator.h"
+#include "../uml.h"
+
+const bool RubyCodeGenerationPolicy::DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS = true;
+const bool RubyCodeGenerationPolicy::DEFAULT_AUTO_GEN_ASSOC_ACCESSORS = true;
+
+// Constructors/Destructors
+//
+
+RubyCodeGenerationPolicy::RubyCodeGenerationPolicy(KConfig *config)
+{
+ init();
+ setDefaults(config,false);
+}
+
+RubyCodeGenerationPolicy::~RubyCodeGenerationPolicy ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+// Public attribute accessor methods
+//
+
+/**
+ * Set the value of m_autoGenerateAttribAccessors
+ * @param new_var the new value
+ */
+void RubyCodeGenerationPolicy::setAutoGenerateAttribAccessors( bool var ) {
+ m_autoGenerateAttribAccessors = var;
+ m_commonPolicy->emitModifiedCodeContentSig();
+}
+
+/**
+ * Set the value of m_autoGenerateAssocAccessors
+ * @param new_var the new value
+ */
+void RubyCodeGenerationPolicy::setAutoGenerateAssocAccessors( bool var ) {
+ m_autoGenerateAssocAccessors = var;
+ m_commonPolicy->emitModifiedCodeContentSig();
+}
+
+/**
+ * Get the value of m_autoGenerateAttribAccessors
+ * @return the value of m_autoGenerateAttribAccessors
+ */
+bool RubyCodeGenerationPolicy::getAutoGenerateAttribAccessors( ){
+ return m_autoGenerateAttribAccessors;
+}
+
+/**
+ * Get the value of m_autoGenerateAssocAccessors
+ * @return the value of m_autoGenerateAssocAccessors
+ */
+bool RubyCodeGenerationPolicy::getAutoGenerateAssocAccessors( ){
+ return m_autoGenerateAssocAccessors;
+}
+
+// Other methods
+//
+
+void RubyCodeGenerationPolicy::writeConfig ( KConfig * config )
+{
+ // @todo do we need to call CodeGenerationPolicy::writeConfig ???
+
+ // write ONLY the Ruby specific stuff
+ config->setGroup("Ruby Code Generation");
+
+ config->writeEntry("autoGenAccessors",getAutoGenerateAttribAccessors());
+ config->writeEntry("autoGenAssocAccessors",getAutoGenerateAssocAccessors());
+}
+
+void RubyCodeGenerationPolicy::setDefaults ( CodeGenPolicyExt * clone, bool emitUpdateSignal )
+{
+
+ RubyCodeGenerationPolicy * rclone;
+ if (!clone)
+ return;
+
+ // NOW block signals for ruby param setting
+ blockSignals(true); // we need to do this because otherwise most of these
+ // settors below will each send the modifiedCodeContent() signal
+ // needlessly (we can just make one call at the end).
+
+
+ // now do ruby-specific stuff IF our clone is also a RubyCodeGenerationPolicy object
+ if((rclone = dynamic_cast<RubyCodeGenerationPolicy*>(clone)))
+ {
+ setAutoGenerateAttribAccessors(rclone->getAutoGenerateAttribAccessors());
+ setAutoGenerateAssocAccessors(rclone->getAutoGenerateAssocAccessors());
+ }
+
+ blockSignals(false); // "as you were citizen"
+
+ if(emitUpdateSignal)
+ m_commonPolicy->emitModifiedCodeContentSig();
+
+}
+
+void RubyCodeGenerationPolicy::setDefaults( KConfig * config, bool emitUpdateSignal )
+{
+
+ if(!config)
+ return;
+
+ // call the superclass to init default stuff
+ m_commonPolicy->setDefaults(config, false);
+
+ // NOW block signals (because call to super-class method will leave value at "true")
+ blockSignals(true); // we need to do this because otherwise most of these
+ // settors below will each send the modifiedCodeContent() signal
+ // needlessly (we can just make one call at the end).
+
+ // now do ruby specific stuff
+ config -> setGroup("Ruby Code Generation");
+
+ setAutoGenerateAttribAccessors(config->readBoolEntry("autoGenAccessors",DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS));
+ setAutoGenerateAssocAccessors(config->readBoolEntry("autoGenAssocAccessors",DEFAULT_AUTO_GEN_ASSOC_ACCESSORS));
+
+ blockSignals(false); // "as you were citizen"
+
+ if(emitUpdateSignal)
+ m_commonPolicy->emitModifiedCodeContentSig();
+}
+
+
+/**
+ * Create a new dialog interface for this object.
+ * @return dialog object
+ */
+CodeGenerationPolicyPage * RubyCodeGenerationPolicy::createPage ( QWidget *parent, const char *name ) {
+ return new RubyCodeGenerationPolicyPage ( parent, name, this );
+}
+
+void RubyCodeGenerationPolicy::init() {
+ m_commonPolicy = UMLApp::app()->getCommonPolicy();
+ m_autoGenerateAttribAccessors = DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS;
+ m_autoGenerateAssocAccessors = DEFAULT_AUTO_GEN_ASSOC_ACCESSORS;
+}
+
+
+#include "rubycodegenerationpolicy.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodegenerationpolicy.h b/umbrello/umbrello/codegenerators/rubycodegenerationpolicy.h
new file mode 100644
index 00000000..aa1a7146
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodegenerationpolicy.h
@@ -0,0 +1,117 @@
+/***************************************************************************
+ rubycodegenerationpolicy.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2005-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODEGENERATIONPOLICY_H
+#define RUBYCODEGENERATIONPOLICY_H
+
+#include <qstring.h>
+#include "codegenpolicyext.h"
+#include "../codegenerationpolicy.h"
+
+class KConfig;
+class CodeGenerationPolicyPage;
+
+class RubyCodeGenerationPolicy : public CodeGenPolicyExt
+{
+ Q_OBJECT
+public:
+
+ static const bool DEFAULT_AUTO_GEN_ATTRIB_ACCESSORS;
+ static const bool DEFAULT_AUTO_GEN_ASSOC_ACCESSORS;
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Constructors
+ */
+ RubyCodeGenerationPolicy (KConfig * config = 0);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeGenerationPolicy ( );
+
+ // Public attributes
+ //
+
+
+ // Public attribute accessor methods
+ //
+
+ /**
+ * Set the value of m_autoGenerateAttribAccessors
+ * @param var the new value
+ */
+ void setAutoGenerateAttribAccessors ( bool var );
+
+ /**
+ * Get the value of m_autoGenerateAttribAccessors
+ * @return value the boolean value of m_autoGenerateAttribAccessors
+ */
+ bool getAutoGenerateAttribAccessors( );
+
+ /**
+ * Set the value of m_autoGenerateAssocAccessors
+ * @param var the new value
+ */
+ void setAutoGenerateAssocAccessors ( bool var );
+
+ /**
+ * Get the value of m_autoGenerateAssocAccessors
+ * @return value the boolean value of m_autoGenerateAssocAccessors
+ */
+ bool getAutoGenerateAssocAccessors( );
+
+ /**
+ * set the defaults for this code generator from the passed generator.
+ */
+ virtual void setDefaults (CodeGenPolicyExt * defaults, bool emitUpdateSignal = true);
+
+ /**
+ * set the defaults from a config file for this code generator from the passed KConfig pointer.
+ */
+ virtual void setDefaults(KConfig * config, bool emitUpdateSignal = true);
+
+ /**
+ * write Default params to passed KConfig pointer.
+ */
+ virtual void writeConfig (KConfig * config);
+
+ /**
+ * Create a new dialog interface for this object.
+ * @return dialog object
+ */
+ CodeGenerationPolicyPage * createPage ( QWidget *parent = 0, const char * name = 0);
+
+protected:
+
+ /**
+ */
+ void init ( );
+
+private:
+
+ CodeGenerationPolicy *m_commonPolicy;
+ bool m_autoGenerateAttribAccessors;
+ bool m_autoGenerateAssocAccessors;
+
+};
+
+#endif // RUBYCODEGENERATIONPOLICY_H
diff --git a/umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.cpp b/umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.cpp
new file mode 100644
index 00000000..1e9080c9
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.cpp
@@ -0,0 +1,75 @@
+/***************************************************************************
+ rubycodegenerationpolicypage.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "rubycodegenerationpolicypage.h"
+// qt/kde includes
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <kdebug.h>
+#include <klocale.h>
+// app includes
+#include "rubycodegenerationformbase.h"
+#include "../codegenerationpolicy.h"
+#include "../uml.h"
+
+RubyCodeGenerationPolicyPage::RubyCodeGenerationPolicyPage( QWidget *parent, const char *name, RubyCodeGenerationPolicy * policy )
+ : CodeGenerationPolicyPage(parent, name, policy)
+{
+ CodeGenerationPolicy *common = UMLApp::app()->getCommonPolicy();
+ form = new RubyCodeGenerationFormBase(this);
+ form->m_SelectCommentStyle->setCurrentItem((int)(common->getCommentStyle()));
+ form->m_generateConstructors->setChecked(common->getAutoGenerateConstructors());
+ form->m_generateAttribAccessors->setChecked(policy->getAutoGenerateAttribAccessors());
+ form->m_generateAssocAccessors->setChecked(policy->getAutoGenerateAssocAccessors());
+ form->m_accessorScopeCB->setCurrentItem((common->getAttributeAccessorScope() - 200));
+ form->m_assocFieldScopeCB->setCurrentItem((common->getAssociationFieldScope() - 200));
+}
+
+RubyCodeGenerationPolicyPage::~RubyCodeGenerationPolicyPage()
+{
+}
+
+void RubyCodeGenerationPolicyPage::apply()
+{
+ CodeGenerationPolicy *common = UMLApp::app()->getCommonPolicy();
+
+ // now do our ruby-specific configs
+ RubyCodeGenerationPolicy * parent = (RubyCodeGenerationPolicy*) m_parentPolicy;
+
+ // block signals so we don't cause too many update content calls to code documents
+ parent->blockSignals(true);
+
+ common->setCommentStyle((CodeGenerationPolicy::CommentStyle) form->m_SelectCommentStyle->currentItem());
+ common->setAttributeAccessorScope((CodeGenerationPolicy::ScopePolicy) (form->m_accessorScopeCB->currentItem()+200));
+ common->setAssociationFieldScope((CodeGenerationPolicy::ScopePolicy) (form->m_assocFieldScopeCB->currentItem()+200));
+ common->setAutoGenerateConstructors(form->m_generateConstructors->isChecked());
+ parent->setAutoGenerateAttribAccessors(form->m_generateAttribAccessors->isChecked());
+ parent->setAutoGenerateAssocAccessors(form->m_generateAssocAccessors->isChecked());
+
+ parent->blockSignals(false);
+
+ // now send out modified code content signal
+ common->emitModifiedCodeContentSig();
+
+}
+
+
+#include "rubycodegenerationpolicypage.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.h b/umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.h
new file mode 100644
index 00000000..6fc06aed
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodegenerationpolicypage.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ rubycodegenerationpolicypage.h
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2005-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODEGENERATIONPOLICYPAGE_H
+#define RUBYCODEGENERATIONPOLICYPAGE_H
+
+#include "../dialogs/codegenerationpolicypage.h"
+#include "rubycodegenerationformbase.h"
+
+#include "rubycodegenerationpolicy.h"
+
+/**
+ * @author Brian Thomas
+ */
+
+class RubyCodeGenerationPolicyPage : public CodeGenerationPolicyPage {
+ Q_OBJECT
+public:
+
+ explicit RubyCodeGenerationPolicyPage (QWidget *parent=0, const char *name=0, RubyCodeGenerationPolicy * policy = 0);
+
+ virtual ~RubyCodeGenerationPolicyPage();
+
+protected:
+
+ RubyCodeGenerationFormBase * form;
+
+public slots:
+
+ void apply();
+
+};
+
+#endif
+
diff --git a/umbrello/umbrello/codegenerators/rubycodegenerator.cpp b/umbrello/umbrello/codegenerators/rubycodegenerator.cpp
new file mode 100644
index 00000000..3e20ce50
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodegenerator.cpp
@@ -0,0 +1,186 @@
+/***************************************************************************
+ rubycodegenerator.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "rubycodegenerator.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+// local includes
+#include "rubycodecomment.h"
+#include "codeviewerdialog.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+RubyCodeGenerator::RubyCodeGenerator (QDomElement & elem )
+ : CodeGenerator(elem)
+{
+}
+
+RubyCodeGenerator::RubyCodeGenerator ()
+{
+}
+
+RubyCodeGenerator::~RubyCodeGenerator ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+// return our language
+Uml::Programming_Language RubyCodeGenerator::getLanguage() {
+ return Uml::pl_Ruby;
+}
+
+// In the Java version, we make the ANT build file also available.
+CodeViewerDialog * RubyCodeGenerator::getCodeViewerDialog ( QWidget* parent, CodeDocument *doc,
+ Settings::CodeViewerState state)
+{
+ CodeViewerDialog *dialog = new CodeViewerDialog(parent, doc, state);
+ return dialog;
+}
+
+
+RubyCodeGenerationPolicy * RubyCodeGenerator::getRubyPolicy() {
+ return dynamic_cast<RubyCodeGenerationPolicy*>(UMLApp::app()->getPolicyExt());
+}
+
+bool RubyCodeGenerator::getAutoGenerateAttribAccessors ( )
+{
+ return getRubyPolicy()->getAutoGenerateAttribAccessors ();
+}
+
+bool RubyCodeGenerator::getAutoGenerateAssocAccessors ( )
+{
+ return getRubyPolicy()->getAutoGenerateAssocAccessors ();
+}
+
+QString RubyCodeGenerator::getListFieldClassName () {
+ return QString("Array");
+}
+
+// Other methods
+//
+
+QString RubyCodeGenerator::cppToRubyType(const QString &typeStr) {
+ QString type = cleanName(typeStr);
+ type.replace("const ", "");
+ type.replace(QRegExp("[*&\\s]"), "");
+ type.replace(QRegExp("[<>]"), "_");
+ type.replace("QStringList", "Array");
+ type.replace(QRegExp("^string$"),"String");
+ type.replace("QString", "String");
+ type.replace("bool", "true|false");
+ type.replace(QRegExp("^(uint|int|ushort|short|ulong|long)$"), "Integer");
+ type.replace(QRegExp("^(float|double)$"), "Float");
+ type.replace(QRegExp("^Q(?=[A-Z])"), "Qt::");
+ type.replace(QRegExp("^K(?!(DE|Parts|IO)"), "KDE::");
+
+ return type;
+}
+
+QString RubyCodeGenerator::cppToRubyName(const QString &nameStr) {
+ QString name = cleanName(nameStr);
+ name.replace(QRegExp("^m_"), "");
+ name.replace(QRegExp("^[pbn](?=[A-Z])"), "");
+ name = name.mid(0, 1).lower() + name.mid(1);
+ return name;
+}
+
+/**
+ * @return ClassifierCodeDocument
+ * @param classifier
+ */
+CodeDocument * RubyCodeGenerator::newClassifierCodeDocument ( UMLClassifier * c)
+{
+ RubyClassifierCodeDocument * doc = new RubyClassifierCodeDocument(c);
+ doc->initCodeClassFields();
+ return doc;
+}
+
+/* These initializations are done in CodeGenFactory::createObject()
+void RubyCodeGenerator::initFields() {
+ UMLApp::app()->setPolicyExt ( new RubyCodeGenerationPolicy(UMLApp::app()->getConfig()) );
+ // load Classifier documents from parent document
+ initFromParentDocument();
+}
+ */
+
+const QStringList RubyCodeGenerator::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "__FILE__"
+ << "__LINE__"
+ << "BEGIN"
+ << "END"
+ << "alias"
+ << "and"
+ << "begin"
+ << "break"
+ << "case"
+ << "class"
+ << "def"
+ << "defined?"
+ << "do"
+ << "else"
+ << "elsif"
+ << "end"
+ << "ensure"
+ << "false"
+ << "for"
+ << "if"
+ << "in"
+ << "module"
+ << "next"
+ << "nil"
+ << "not"
+ << "or"
+ << "redo"
+ << "rescue"
+ << "retry"
+ << "return"
+ << "self"
+ << "super"
+ << "then"
+ << "true"
+ << "undef"
+ << "unless"
+ << "until"
+ << "when"
+ << "while"
+ << "yield";
+ }
+
+ return keywords;
+}
+
+#include "rubycodegenerator.moc"
+
diff --git a/umbrello/umbrello/codegenerators/rubycodegenerator.h b/umbrello/umbrello/codegenerators/rubycodegenerator.h
new file mode 100644
index 00000000..9cc878f0
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodegenerator.h
@@ -0,0 +1,129 @@
+/***************************************************************************
+ rubycodegenerator.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODEGENERATOR_H
+#define RUBYCODEGENERATOR_H
+
+#include <qstring.h>
+#include "../codeviewerstate.h"
+#include "../codegenerator.h"
+#include "../codeblockwithcomments.h"
+#include "../umldoc.h"
+
+#include "classifierinfo.h"
+#include "rubyclassifiercodedocument.h"
+
+#include "rubycodegenerationpolicy.h"
+
+class CodeViewerDialog;
+
+class RubyCodeGenerator : public CodeGenerator
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ RubyCodeGenerator ();
+ RubyCodeGenerator (QDomElement & element);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeGenerator ( );
+
+ // Public attributes
+ //
+
+
+ // Public attribute accessor methods
+ //
+
+ /**
+ * A utility method to get the rubyCodeGenerationPolicy()->getAutoGenerateAttribAccessors() value.
+ */
+ bool getAutoGenerateAttribAccessors( );
+
+ /**
+ * A utility method to get the rubyCodeGenerationPolicy()->getAutoGenerateAssocAccessors() value.
+ */
+ bool getAutoGenerateAssocAccessors( );
+
+ /**
+ * Get the list variable class name to use. For Ruby, we have set this to "Array".
+ */
+ static QString getListFieldClassName();
+
+ /** Get the editing dialog for this code document
+ */
+ virtual CodeViewerDialog * getCodeViewerDialog( QWidget* parent, CodeDocument * doc,
+ Settings::CodeViewerState state);
+
+ // Other methods
+ //
+
+ /**
+ * Utility function for getting the ruby code generation policy.
+ */
+ RubyCodeGenerationPolicy * getRubyPolicy();
+
+ /**
+ * @return ClassifierCodeDocument
+ * @param classifier
+ */
+ CodeDocument * newClassifierCodeDocument (UMLClassifier * classifier);
+
+ // return "Ruby"
+ Uml::Programming_Language getLanguage();
+
+ /**
+ * Convert a C++ type such as 'int' or 'QWidget' to
+ * ruby types Integer and Qt::Widget
+ *
+ * @param cppType the C++ type to be converted
+ */
+ static QString cppToRubyType(const QString &cppType);
+
+ /**
+ * Convert C++ names such as 'm_foobar' or pFoobar to
+ * just 'foobar' for ruby
+ *
+ * @param cppName the C++ name to be converted
+ */
+ static QString cppToRubyName(const QString &cppName);
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+protected:
+
+ /** create the codeblock that will represent the class declaration
+ * for this classifier
+ */
+ CodeBlockWithComments * createClassDecl ( UMLClassifier *c, ClassifierInfo *info, RubyClassifierCodeDocument * doc);
+
+};
+
+#endif // RUBYCODEGENERATOR_H
diff --git a/umbrello/umbrello/codegenerators/rubycodeoperation.cpp b/umbrello/umbrello/codegenerators/rubycodeoperation.cpp
new file mode 100644
index 00000000..6f16fb96
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeoperation.cpp
@@ -0,0 +1,226 @@
+/***************************************************************************
+ rubycodeoperation.cpp
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "rubycodeoperation.h"
+
+// qt/kde includes
+#include <qregexp.h>
+
+// local includes
+#include "rubyclassifiercodedocument.h"
+#include "rubycodedocumentation.h"
+#include "rubycodegenerator.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+RubyCodeOperation::RubyCodeOperation ( RubyClassifierCodeDocument * doc, UMLOperation *parent, const QString & body, const QString & comment )
+ : CodeOperation (doc, parent, body, comment)
+{
+ // lets not go with the default comment and instead use
+ // full-blown ruby documentation object instead
+ setComment(new RubyCodeDocumentation(doc));
+
+ // these things never change..
+ setOverallIndentationLevel(1);
+
+ updateMethodDeclaration();
+ updateContent();
+
+}
+
+RubyCodeOperation::~RubyCodeOperation ( ) { }
+
+// Other methods
+//
+
+// we basically want to update the doc and start text of this method
+void RubyCodeOperation::updateMethodDeclaration()
+{
+
+ CodeDocument * doc = getParentDocument();
+ RubyClassifierCodeDocument * rubydoc = dynamic_cast<RubyClassifierCodeDocument*>(doc);
+ UMLClassifier *c = rubydoc->getParentClassifier();
+ UMLOperation * o = getParentOperation();
+ bool isInterface = rubydoc->getParentClassifier()->isInterface();
+ QString endLine = getNewLineEndingChars();
+
+ // now, the starting text.
+ QString strVis = rubydoc->scopeToRubyDecl(o->getVisibility());
+ // no return type for constructors
+ QString fixedReturn = RubyCodeGenerator::cppToRubyType(o->getTypeName());
+ QString returnType = o->isConstructorOperation() ? QString("") : (fixedReturn + QString(" "));
+ QString methodName = o->getName();
+
+ QString RubyClassName = rubydoc->getRubyClassName(c->getName());
+
+ // Skip destructors, and operator methods which
+ // can't be defined in ruby
+ if ( methodName.startsWith("~")
+ || QRegExp("operator\\s*(=|--|\\+\\+|!=)$").exactMatch(methodName) )
+ {
+ getComment()->setText("");
+ return;
+ }
+
+ if (RubyClassName == methodName) {
+ methodName = "initialize";
+ }
+
+ methodName.replace(QRegExp("operator\\s*"), "");
+ methodName = methodName.mid(0, 1).lower() + methodName.mid(1);
+
+ QString paramStr = QString("");
+ QStringList commentedParams;
+
+ // assemble parameters
+ UMLAttributeList list = getParentOperation()->getParmList();
+ int nrofParam = list.count();
+ int paramNum = 0;
+ for(UMLAttribute* parm = list.first(); parm; parm = list.next())
+ {
+ QString paramName = RubyCodeGenerator::cppToRubyName(parm->getName());
+ paramStr += paramName;
+ if (! parm->getInitialValue().isEmpty()) {
+ paramStr += QString(" = ") + RubyCodeGenerator::cppToRubyType(parm->getInitialValue());
+ }
+ paramNum++;
+
+ if (paramNum != nrofParam )
+ paramStr += ", ";
+ }
+
+ QString startText;
+ if (isInterface) {
+ // Assume 'isInterface' means a module in Ruby, so
+ // generate module methods
+ startText = "def "+ RubyClassName + '.' + methodName + '(' + paramStr +')';
+ } else {
+ startText = "def "+ methodName + '(' + paramStr +')';
+ }
+
+ startText += "";
+ setEndMethodText("end");
+
+ setStartMethodText(startText);
+
+ // Lastly, for text content generation, we fix the comment on the
+ // operation, IF the codeop is autogenerated & currently empty
+ QString comment = o->getDoc();
+
+ if (comment.isEmpty()) {
+ if (getContentType() == CodeBlock::AutoGenerated) {
+ UMLAttributeList parameters = o->getParmList();
+ for(UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) {
+ comment += endLine + "* _" + iterator.current()->getName() + "_ ";
+ comment += (' ' + iterator.current()->getDoc().replace( QRegExp("[\\n\\r]+[\\t ]*"),
+ endLine + " " ) );
+ }
+ // add a returns statement too
+ if(!returnType.isEmpty() && !QRegExp("^void\\s*$").exactMatch(returnType))
+ comment += endLine + "* _returns_ " + returnType + ' ';
+ getComment()->setText(comment);
+ }
+ } else {
+ comment.replace(QRegExp("[\\n\\r]+ *"), endLine);
+ comment.replace(QRegExp("[\\n\\r]+\\t*"), endLine);
+
+ comment.replace(" m_", " ");
+ comment.replace(QRegExp("\\s[npb](?=[A-Z])"), " ");
+ QRegExp re_params("@param (\\w)(\\w*)");
+ int pos = re_params.search(comment);
+ while (pos != -1) {
+ comment.replace( re_params.cap(0),
+ QString("@param _") + re_params.cap(1).lower() + re_params.cap(2) + '_' );
+ commentedParams.append(re_params.cap(1).lower() + re_params.cap(2));
+
+ pos += re_params.matchedLength() + 3;
+ pos = re_params.search(comment, pos);
+ }
+
+ UMLAttributeList parameters = o->getParmList();
+ for (UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) {
+ // Only write an individual @param entry if one hasn't been found already
+ // in the main doc comment
+ if (commentedParams.contains(RubyCodeGenerator::cppToRubyName(iterator.current()->getName())) == 0) {
+ comment += (endLine + "@param _" + RubyCodeGenerator::cppToRubyName(iterator.current()->getName()) + '_');
+ if (iterator.current()->getDoc().isEmpty()) {
+ comment += (' ' + RubyCodeGenerator::cppToRubyType(iterator.current()->getTypeName()));
+ } else {
+ comment += (' ' + iterator.current()->getDoc().replace(QRegExp("[\\n\\r]+[\\t ]*"), endLine + " "));
+ }
+ }
+ }
+
+ comment.replace("@ref ", "");
+ comment.replace("@param", "*");
+ comment.replace("@return", "* _returns_");
+
+ // All lines after the first one starting with '*' in the doc comment
+ // must be indented correctly. If they aren't a list
+ // item starting with '*', then indent the text with
+ // two spaces, ' ', to line up with the list item.
+ pos = comment.find(endLine + '*');
+ if (pos != -1) {
+ pos += endLine.length() + 1;
+ pos = comment.find(endLine, pos);
+ }
+
+ while (pos > 0) {
+ pos += endLine.length();
+ if (comment[pos] != '*') {
+ comment.insert(pos, " ");
+ pos += 2;
+ }
+
+ pos = comment.find(endLine, pos);
+ }
+
+ QString typeStr = RubyCodeGenerator::cppToRubyType(o->getTypeName());
+ if ( !typeStr.isEmpty()
+ && !QRegExp("^void\\s*$").exactMatch(typeStr)
+ && comment.contains("_returns_") == 0 )
+ {
+ comment += endLine + "* _returns_ " + typeStr;
+ }
+
+ getComment()->setText(comment);
+ }
+
+ // In Java, for interfaces..we DONT write out non-public
+ // method declarations. And for Ruby modules?
+ if (isInterface) {
+ UMLOperation * o = getParentOperation();
+ if(o->getVisibility() != Uml::Visibility::Public)
+ setWriteOutText(false);
+ }
+
+}
+
+int RubyCodeOperation::lastEditableLine() {
+ ClassifierCodeDocument * doc = dynamic_cast<ClassifierCodeDocument*>(getParentDocument());
+ if(doc->parentIsInterface())
+ return -1; // very last line is NOT editable as its a one-line declaration w/ no body in
+ // an interface.
+ return 0;
+}
+
+#include "rubycodeoperation.moc"
diff --git a/umbrello/umbrello/codegenerators/rubycodeoperation.h b/umbrello/umbrello/codegenerators/rubycodeoperation.h
new file mode 100644
index 00000000..c8e8cea4
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubycodeoperation.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ rubycodeoperation.h
+ Derived from the Java code generator by thomas
+
+ begin : Thur Jul 21 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYCODEOPERATION_H
+#define RUBYCODEOPERATION_H
+
+#include <qstring.h>
+#include "../codeoperation.h"
+
+class RubyClassifierCodeDocument;
+
+class RubyCodeOperation : virtual public CodeOperation
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ RubyCodeOperation ( RubyClassifierCodeDocument * doc, UMLOperation * op, const QString & body = "", const QString & comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~RubyCodeOperation ( );
+
+ virtual int lastEditableLine();
+
+protected:
+
+ void updateMethodDeclaration();
+
+};
+
+#endif // RUBYCODEOPERATION_H
diff --git a/umbrello/umbrello/codegenerators/rubywriter.cpp b/umbrello/umbrello/codegenerators/rubywriter.cpp
new file mode 100644
index 00000000..aa9a5271
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubywriter.cpp
@@ -0,0 +1,448 @@
+/***************************************************************************
+ rubywriter.h - description
+ -------------------
+ begin : Sat Dec 21 2002
+ copyright : Vincent Decorges
+ email : vincent.decorges@eivd.ch
+ (C) 2003-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "rubywriter.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#include "classifierinfo.h"
+#include "../umldoc.h"
+#include "../umlattributelist.h"
+#include "../association.h"
+#include "../attribute.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+
+RubyWriter::RubyWriter() {
+}
+
+RubyWriter::~RubyWriter() {}
+
+void RubyWriter::writeClass(UMLClassifier *c) {
+ if(!c) {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ QString classname = cleanName(c->getName());
+
+ UMLClassifierList superclasses = c->getSuperClasses();
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+
+ //find an appropriate name for our file
+ QString fileName = findFileName(c, ".rb");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile fileh;
+ if( !openFile(fileh, fileName) ) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ QTextStream h(&fileh);
+
+ // preparations
+ classifierInfo = new ClassifierInfo(c);
+ classifierInfo->fileName = fileName;
+ classifierInfo->className = cleanName(c->getName());
+
+ //////////////////////////////
+ //Start generating the code!!
+ /////////////////////////////
+
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+
+ str = getHeadingFile(".rb");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"), fileName);
+ str.replace(QRegExp("%filepath%"), fileh.name());
+ h<<str<<m_endl;
+ }
+
+ if(forceDoc() || !c->getDoc().isEmpty()) {
+ QString docStr = c->getDoc();
+ docStr.replace(QRegExp("\\n"), "\n# ");
+ docStr.replace("@ref ", "");
+ docStr.replace("@see", "_See_");
+ docStr.replace("@short", "_Summary_");
+ docStr.replace("@author", "_Author_");
+ h<<"#"<<m_endl;
+ h<<"# "<<docStr<<m_endl;
+ h<<"#"<<m_endl<<m_endl;
+ }
+
+ // write inheritances out
+ UMLClassifier *concept;
+
+ h<< "class " << cppToRubyType(classname) << (superclasses.count() > 0 ? " < ":"");
+
+ int i = 0;
+ for (concept = superclasses.first(); concept; concept = superclasses.next()) {
+ if (i == 0) {
+ h << cppToRubyType(concept->getName()) << m_endl;
+ } else {
+ // Assume ruby modules that can be mixed in, after the first
+ // superclass name in the list
+ h << m_indentation << "include "<< cppToRubyType(concept->getName()) << m_endl;
+ }
+ i++;
+ }
+
+ h << m_endl;
+
+ // write comment for sub-section IF needed
+ if (forceDoc() || classifierInfo->hasAccessorMethods) {
+ h << m_indentation << "#" << m_endl;
+ h << m_indentation << "# Accessor Methods" << m_endl;
+ h << m_indentation << "#" << m_endl << m_endl;
+
+ // Accessor methods for attributes
+ writeAttributeMethods(&(classifierInfo->atpub), Uml::Visibility::Public, h);
+ writeAttributeMethods(&(classifierInfo->atprot), Uml::Visibility::Protected, h);
+ writeAttributeMethods(&(classifierInfo->atpriv), Uml::Visibility::Private, h);
+ h << m_endl;
+ }
+
+ //operations
+ writeOperations(c, h);
+
+ //finish files
+ h << "end" << m_endl << m_endl;
+
+ //close files and notfiy we are done
+ fileh.close();
+ emit codeGenerated(c, true);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// Helper Methods
+
+QString RubyWriter::cppToRubyType(const QString &typeStr) {
+ QString type = cleanName(typeStr);
+ type.replace("const ", "");
+ type.replace(QRegExp("[*&\\s]"), "");
+ type.replace(QRegExp("[<>]"), "_");
+ type.replace("QStringList", "Array");
+ type.replace("QString", "String");
+ type.replace("bool", "true|false");
+ type.replace(QRegExp("^(uint|int|ushort|short|ulong|long)$"), "Integer");
+ type.replace(QRegExp("^(float|double)$"), "Float");
+ type.replace(QRegExp("^Q(?=[A-Z])"), "Qt::");
+ type.replace(QRegExp("^K(?!(DE|Parts|IO)"), "KDE::");
+
+ return type;
+}
+
+QString RubyWriter::cppToRubyName(const QString &nameStr) {
+ QString name = cleanName(nameStr);
+ name.replace(QRegExp("^m_"), "");
+ name.replace(QRegExp("^[pbn](?=[A-Z])"), "");
+ name = name.mid(0, 1).lower() + name.mid(1);
+ return name;
+}
+
+void RubyWriter::writeOperations(UMLClassifier *c,QTextStream &h) {
+
+ //Lists to store operations sorted by scope
+ UMLOperationList oppub,opprot,oppriv;
+
+ oppub.setAutoDelete(false);
+ opprot.setAutoDelete(false);
+ oppriv.setAutoDelete(false);
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList opl(c->getOpList());
+ for(UMLOperation *op = opl.first(); op ; op = opl.next()) {
+ switch(op->getVisibility()) {
+ case Uml::Visibility::Public:
+ oppub.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ opprot.append(op);
+ break;
+ case Uml::Visibility::Private:
+ oppriv.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ QString classname(cleanName(c->getName()));
+
+ //write operations to file
+ if(forceSections() || !oppub.isEmpty()) {
+ writeOperations(classname, oppub, Uml::Visibility::Public, h);
+ }
+
+ if(forceSections() || !opprot.isEmpty()) {
+ writeOperations(classname, opprot, Uml::Visibility::Protected, h);
+ }
+
+ if(forceSections() || !oppriv.isEmpty()) {
+ writeOperations(classname, oppriv, Uml::Visibility::Private, h);
+ }
+
+}
+
+void RubyWriter::writeOperations(const QString &classname, UMLOperationList &opList,
+ Uml::Visibility permitScope, QTextStream &h)
+{
+ UMLOperation *op;
+ UMLAttribute *at;
+
+ switch (permitScope) {
+ case Uml::Visibility::Public:
+ h << m_indentation << "public" << m_endl << m_endl;
+ break;
+ case Uml::Visibility::Protected:
+ h << m_indentation << "protected" << m_endl << m_endl;
+ break;
+ case Uml::Visibility::Private:
+ h << m_indentation << "private" << m_endl << m_endl;
+ break;
+ default:
+ break;
+ }
+
+ for (op=opList.first(); op ; op=opList.next()) {
+ QString methodName = cleanName(op->getName());
+ QStringList commentedParams;
+
+ // Skip destructors, and operator methods which
+ // can't be defined in ruby
+ if ( methodName.startsWith("~")
+ || methodName == "operator ="
+ || methodName == "operator --"
+ || methodName == "operator ++"
+ || methodName == "operator !=" )
+ {
+ continue;
+ }
+
+ if (methodName == classname) {
+ methodName = "initialize";
+ }
+
+ methodName.replace("operator ", "");
+ methodName = methodName.mid(0, 1).lower() + methodName.mid(1);
+
+ UMLAttributeList atl = op->getParmList();
+ //write method doc if we have doc || if at least one of the params has doc
+ bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
+ // Always write out the docs for ruby as the type of the
+ // arguments and return value of the methods is useful
+ writeDoc = true;
+// for (at = atl.first(); at; at = atl.next())
+// writeDoc |= !at->getDoc().isEmpty();
+
+ if (writeDoc) {
+ h << m_indentation << "#" << m_endl;
+ QString docStr = op->getDoc();
+
+ docStr.replace(QRegExp("[\\n\\r]+ *"), m_endl);
+ docStr.replace(QRegExp("[\\n\\r]+\\t*"), m_endl);
+
+ docStr.replace(" m_", " ");
+ docStr.replace(QRegExp("\\s[npb](?=[A-Z])"), " ");
+ QRegExp re_params("@param (\\w)(\\w*)");
+ int pos = re_params.search(docStr);
+ while (pos != -1) {
+ docStr.replace( re_params.cap(0),
+ QString("@param _") + re_params.cap(1).lower() + re_params.cap(2) + '_' );
+ commentedParams.append(re_params.cap(1).lower() + re_params.cap(2));
+
+ pos += re_params.matchedLength() + 3;
+ pos = re_params.search(docStr, pos);
+ }
+
+ docStr.replace("\n", QString("\n") + m_indentation + "# ");
+
+ // Write parameter documentation
+ for (at = atl.first(); at ; at = atl.next()) {
+ // Only write an individual @param entry if one hasn't been found already
+ // in the main doc comment
+ if (commentedParams.contains(cppToRubyName(at->getName())) == 0) {
+ docStr += (m_endl + m_indentation + "# @param _" + cppToRubyName(at->getName()) + '_');
+ if (at->getDoc().isEmpty()) {
+ docStr += (' ' + cppToRubyType(at->getTypeName()));
+ } else {
+ docStr += (' ' + at->getDoc().replace(QRegExp("[\\n\\r]+[\\t ]*"), m_endl + " "));
+ }
+ }
+ }
+
+ docStr.replace("@ref ", "");
+ docStr.replace("@param", "*");
+ docStr.replace("@return", "* _returns_");
+
+ // All lines after the first '# *' in the doc comment
+ // must be indented correctly. If they aren't a list
+ // item starting with '# *', then indent the text with
+ // three spaces, '# ', to line up with the list item.
+ pos = docStr.find("# *");
+ QRegExp re_linestart("# (?!\\*)");
+ pos = re_linestart.search(docStr, pos);
+ while (pos > 0) {
+ docStr.insert(pos + 1, " ");
+
+ pos += re_linestart.matchedLength() + 2;
+ pos = re_linestart.search(docStr, pos);
+ }
+
+ h << m_indentation << "# "<< docStr << m_endl;
+
+ QString typeStr = cppToRubyType(op->getTypeName());
+ if (!typeStr.isEmpty() && typeStr != "void" && docStr.contains("_returns_") == 0) {
+ h << m_indentation << "# * _returns_ " << typeStr << m_endl;
+ }
+ }
+
+ h<< m_indentation << "def " + methodName << "(";
+
+ int j=0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+ QString nameStr = cppToRubyName(at->getName());
+ if (j > 0) {
+ h << ", " << nameStr;
+ } else {
+ h << nameStr;
+ }
+ h << (!(at->getInitialValue().isEmpty()) ?
+ (QString(" = ") + cppToRubyType(at->getInitialValue())) :
+ QString(""));
+ }
+
+ h <<")" << m_endl;
+
+ h << m_indentation << m_indentation << m_endl;
+
+ h << m_indentation << "end" << m_endl << m_endl;
+
+ }//end for
+
+}
+
+// this is for writing file attribute methods
+//
+void RubyWriter::writeAttributeMethods(UMLAttributeList *attribs,
+ Uml::Visibility visibility, QTextStream &stream)
+{
+ // return now if NO attributes to work on
+ if (attribs->count() == 0 || visibility == Uml::Visibility::Private)
+ return;
+
+ UMLAttribute *at;
+ for(at=attribs->first(); at; at=attribs->next())
+ {
+ QString varName = cppToRubyName(cleanName(at->getName()));
+
+ writeSingleAttributeAccessorMethods(varName, at->getDoc(), stream);
+ }
+
+}
+
+void RubyWriter::writeSingleAttributeAccessorMethods(
+ const QString &fieldName,
+ const QString &descr,
+ QTextStream &h)
+{
+ QString description = descr;
+ description.replace(QRegExp("m_[npb](?=[A-Z])"), "");
+ description.replace("m_", "");
+ description.replace("\n", QString("\n") + m_indentation + "# ");
+
+ if (!description.isEmpty()) {
+ h << m_indentation << "# " << description << m_endl;
+ }
+
+ h << m_indentation << "attr_accessor :" << fieldName << m_endl << m_endl;
+
+ return;
+}
+
+/**
+ * returns "Ruby"
+ */
+Uml::Programming_Language RubyWriter::getLanguage() {
+ return Uml::pl_Ruby;
+}
+
+const QStringList RubyWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "__FILE__"
+ << "__LINE__"
+ << "BEGIN"
+ << "END"
+ << "alias"
+ << "and"
+ << "begin"
+ << "break"
+ << "case"
+ << "class"
+ << "def"
+ << "defined?"
+ << "do"
+ << "else"
+ << "elsif"
+ << "end"
+ << "ensure"
+ << "false"
+ << "for"
+ << "if"
+ << "in"
+ << "module"
+ << "next"
+ << "nil"
+ << "not"
+ << "or"
+ << "redo"
+ << "rescue"
+ << "retry"
+ << "return"
+ << "self"
+ << "super"
+ << "then"
+ << "true"
+ << "undef"
+ << "unless"
+ << "until"
+ << "when"
+ << "while"
+ << "yield";
+ }
+
+ return keywords;
+}
+
+#include "rubywriter.moc"
diff --git a/umbrello/umbrello/codegenerators/rubywriter.h b/umbrello/umbrello/codegenerators/rubywriter.h
new file mode 100644
index 00000000..8f1547ad
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/rubywriter.h
@@ -0,0 +1,113 @@
+/***************************************************************************
+ rubywriter.h - description
+ -------------------
+ begin : Mon Jul 18 2005
+ author : Richard Dale
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef RUBYWRITER_H
+#define RUBYWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umloperationlist.h"
+#include "../umlattributelist.h"
+
+#include <qstringlist.h>
+
+class ClassifierInfo;
+
+/**
+ * class RubyWriter is a ruby code generator for UMLClassifier objects
+ * Just call writeClass and feed it a UMLClassifier;
+ */
+class RubyWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ RubyWriter();
+ virtual ~RubyWriter();
+
+ /**
+ * call this method to generate C++ code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "Ruby"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+ /**
+ * Convert a C++ type such as 'int' or 'QWidget' to
+ * ruby types Integer and Qt::Widget
+ *
+ * @param cppType the C++ type to be converted
+ */
+ QString cppToRubyType(const QString &cppType);
+
+ /**
+ * Convert C++ names such as 'm_foobar' or pFoobar to
+ * just 'foobar' for ruby
+ *
+ * @param cppName the C++ name to be converted
+ */
+ QString cppToRubyName(const QString &cppName);
+
+ /**
+ * calls @ref writeSingleAttributeAccessorMethods() on each of the attributes in attribs list.
+ */
+ void writeAttributeMethods(UMLAttributeList *attribs,
+ Uml::Visibility visibility, QTextStream &stream);
+
+
+ /**
+ * write all method declarations, for attributes and associations
+ * for the given permitted scope.
+ */
+ void writeSingleAttributeAccessorMethods(const QString &fieldName,
+ const QString &description,
+ QTextStream &h);
+
+ /**
+ * write all operations for a given class
+ *
+ * @param c the concept we are generating code for
+ * @param h output stream for the header file
+ */
+ void writeOperations(UMLClassifier *c, QTextStream &h);
+
+ /**
+ * write a list of class operations
+ *
+ * @param classname the name of the class
+ * @param opList the list of operations
+ * @param h output stream for the header file
+ */
+ void writeOperations(const QString &classname, UMLOperationList &opList,
+ Uml::Visibility permitScope, QTextStream &h);
+
+ /**
+ * Summary information about current classifier.
+ */
+ ClassifierInfo * classifierInfo;
+};
+
+#endif //RUBYWRITER
diff --git a/umbrello/umbrello/codegenerators/simplecodegenerator.cpp b/umbrello/umbrello/codegenerators/simplecodegenerator.cpp
new file mode 100644
index 00000000..98477f15
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/simplecodegenerator.cpp
@@ -0,0 +1,292 @@
+/***************************************************************************
+ * *
+ * 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-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Sep Mon 1 2003
+ */
+
+// own header
+#include "simplecodegenerator.h"
+// system includes
+#include <cstdlib> //to get the user name
+// qt includes
+#include <qdatetime.h>
+#include <qregexp.h>
+#include <qdir.h>
+// kde includes
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kdialog.h>
+#include <kapplication.h>
+// app includes
+#include "../dialogs/overwritedialogue.h"
+#include "../model_utils.h"
+#include "../attribute.h"
+#include "../umloperationlist.h"
+#include "../umlattributelist.h"
+#include "../classifier.h"
+#include "../codedocument.h"
+#include "../codegenerationpolicy.h"
+#include "../operation.h"
+#include "../umldoc.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+SimpleCodeGenerator::SimpleCodeGenerator (bool createDirHierarchyForPackages /* =true */)
+{
+ m_indentLevel = 0;
+ UMLDoc * parentDoc = UMLApp::app()->getDocument();
+ parentDoc->disconnect(this); // disconnect from UMLDoc.. we arent planning to be synced at all
+ m_createDirHierarchyForPackages = createDirHierarchyForPackages;
+ initFields(parentDoc);
+}
+
+SimpleCodeGenerator::~SimpleCodeGenerator ( ) { }
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+
+// Other methods
+//
+
+QString SimpleCodeGenerator::getIndent ()
+{
+ QString myIndent;
+ for (int i = 0 ; i < m_indentLevel ; i++)
+ myIndent.append(m_indentation);
+ return myIndent;
+}
+
+QString SimpleCodeGenerator::findFileName(UMLPackage* concept, const QString &ext) {
+
+ //if we already know to which file this class was written/should be written, just return it.
+ if (m_fileMap.contains(concept))
+ return m_fileMap[concept];
+
+ //else, determine the "natural" file name
+ QString name;
+ // Get the package name
+ QString package = concept->getPackage(".");
+
+ // Replace all white spaces with blanks
+ package.simplifyWhiteSpace();
+
+ // Replace all blanks with underscore
+ package.replace(QRegExp(" "), "_");
+
+ // Convert all "::" to "/" : Platform-specific path separator
+ // package.replace(QRegExp("::"), "/");
+
+ // if package is given add this as a directory to the file name
+ if (!package.isEmpty() && m_createDirHierarchyForPackages) {
+ name = package + '.' + concept->getName();
+ name.replace(QRegExp("\\."),"/");
+ package.replace(QRegExp("\\."), "/");
+ package = '/' + package;
+ } else {
+ name = concept->getFullyQualifiedName("-");
+ }
+
+ if (! UMLApp::app()->activeLanguageIsCaseSensitive()) {
+ package = package.lower();
+ name = name.lower();
+ }
+
+ // if a package name exists check the existence of the package directory
+ if (!package.isEmpty() && m_createDirHierarchyForPackages) {
+ QDir pathDir(UMLApp::app()->getCommonPolicy()->getOutputDirectory().absPath() + package);
+ // does our complete output directory exist yet? if not, try to create it
+ if (!pathDir.exists())
+ {
+ QStringList dirs = QStringList::split("/",pathDir.absPath());
+ QString currentDir = "";
+
+ QStringList::iterator end(dirs.end());
+ for (QStringList::iterator dir(dirs.begin()); dir != end; ++dir)
+ {
+ currentDir += '/' + *dir;
+ if (! (pathDir.exists(currentDir)
+ || pathDir.mkdir(currentDir) ) )
+ {
+ KMessageBox::error(0, i18n("Cannot create the folder:\n") +
+ pathDir.absPath() + i18n("\nPlease check the access rights"),
+ i18n("Cannot Create Folder"));
+ return NULL;
+ }
+ }
+ }
+ }
+
+
+ name.simplifyWhiteSpace();
+ name.replace(QRegExp(" "),"_");
+
+ QString extension = ext.simplifyWhiteSpace();
+ extension.replace(' ', '_');
+
+ return overwritableName(concept, name, extension);
+}
+
+QString SimpleCodeGenerator::overwritableName(UMLPackage* concept, const QString &name, const QString &ext) {
+ //check if a file named "name" with extension "ext" already exists
+ CodeGenerationPolicy *commonPolicy = UMLApp::app()->getCommonPolicy();
+ QDir outputDir = commonPolicy->getOutputDirectory();
+ QString filename = name + ext;
+ if(!outputDir.exists(filename)) {
+ m_fileMap.insert(concept,filename);
+ return filename; //if not, "name" is OK and we have not much to to
+ }
+
+ int suffix;
+ OverwriteDialogue overwriteDialogue( filename, outputDir.absPath(),
+ m_applyToAllRemaining, kapp -> mainWidget() );
+ switch(commonPolicy->getOverwritePolicy()) { //if it exists, check the OverwritePolicy we should use
+ case CodeGenerationPolicy::Ok: //ok to overwrite file
+ break;
+ case CodeGenerationPolicy::Ask: //ask if we can overwrite
+ switch(overwriteDialogue.exec()) {
+ case KDialogBase::Yes: //overwrite file
+ if ( overwriteDialogue.applyToAllRemaining() ) {
+ commonPolicy->setOverwritePolicy(CodeGenerationPolicy::Ok);
+ } else {
+ m_applyToAllRemaining = false;
+ }
+ break;
+ case KDialogBase::No: //generate similar name
+ suffix = 1;
+ while (1) {
+ filename = name + "__" + QString::number(suffix) + ext;
+ if (!outputDir.exists(filename))
+ break;
+ suffix++;
+ }
+ if ( overwriteDialogue.applyToAllRemaining() ) {
+ commonPolicy->setOverwritePolicy(CodeGenerationPolicy::Never);
+ } else {
+ m_applyToAllRemaining = false;
+ }
+ break;
+ case KDialogBase::Cancel: //don't output anything
+ if ( overwriteDialogue.applyToAllRemaining() ) {
+ commonPolicy->setOverwritePolicy(CodeGenerationPolicy::Cancel);
+ } else {
+ m_applyToAllRemaining = false;
+ }
+ return NULL;
+ break;
+ }
+
+ break;
+ case CodeGenerationPolicy::Never: //generate similar name
+ suffix = 1;
+ while (1) {
+ filename = name + "__" + QString::number(suffix) + ext;
+ if (!outputDir.exists(filename))
+ break;
+ suffix++;
+ }
+ break;
+ case CodeGenerationPolicy::Cancel: //don't output anything
+ return NULL;
+ break;
+ }
+
+ m_fileMap.insert(concept, filename);
+ return filename;
+}
+
+
+bool SimpleCodeGenerator::hasDefaultValueAttr(UMLClassifier *c) {
+ UMLAttributeList atl = c->getAttributeList();
+ for(UMLAttribute *at = atl.first(); at; at = atl.next())
+ if(!at->getInitialValue().isEmpty())
+ return true;
+ return false;
+}
+
+bool SimpleCodeGenerator::hasAbstractOps(UMLClassifier *c) {
+ UMLOperationList opl(c->getOpList());
+ for(UMLOperation *op = opl.first(); op ; op = opl.next())
+ if(op->getAbstract())
+ return true;
+ return false;
+}
+
+/**
+ * @return ClassifierCodeDocument
+ * @param classifier
+ * @param this This package generator object.
+ */
+CodeDocument * SimpleCodeGenerator::newClassifierCodeDocument(UMLClassifier* /*classifier*/)
+{
+ return (CodeDocument*)NULL;
+}
+
+// write all concepts in project to file
+void SimpleCodeGenerator::writeCodeToFile ( ) {
+ m_fileMap.clear(); // need to do this, else just keep getting same directory to write to.
+ UMLClassifierList concepts = m_doc->getClassesAndInterfaces();
+ for (UMLClassifier *c = concepts.first(); c; c = concepts.next()) {
+ if (! Model_Utils::isCommonDataType(c->getName()))
+ this->writeClass(c); // call the writer for each class.
+ }
+}
+
+// write only selected concepts to file
+void SimpleCodeGenerator::writeCodeToFile ( UMLClassifierList & concepts) {
+ m_fileMap.clear(); // ??
+ for (UMLClassifier *c = concepts.first(); c; c = concepts.next())
+ this->writeClass(c); // call the writer for each class.
+}
+
+void SimpleCodeGenerator::initFields ( UMLDoc * parentDoc ) {
+
+ // load Classifier documents from parent document
+ // initFromParentDocument();
+
+ m_fileMap.clear();
+ m_applyToAllRemaining = true;
+ m_doc = parentDoc;
+
+ // this really is just being used to sync the internal params
+ // to the codegenpolicy as there are no code documents to really sync.
+ syncCodeToDocument();
+}
+
+// a little method to provide some compatability between
+// the newer codegenpolicy object and the older class fields.
+void SimpleCodeGenerator::syncCodeToDocument() {
+
+ CodeGenerationPolicy *policy = UMLApp::app()->getCommonPolicy();
+
+ m_indentation = policy->getIndentation();
+ m_endl = policy->getNewLineEndingChars();
+
+}
+
+
+// override parent method
+void SimpleCodeGenerator::initFromParentDocument( )
+{
+ // Do nothing
+}
+
+
+#include "simplecodegenerator.moc"
diff --git a/umbrello/umbrello/codegenerators/simplecodegenerator.h b/umbrello/umbrello/codegenerators/simplecodegenerator.h
new file mode 100644
index 00000000..d75a0660
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/simplecodegenerator.h
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Sep Mon 1 2003
+ *
+ * copyright (C) 2004
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ */
+
+
+#ifndef SIMPLECODEGENERATOR_H
+#define SIMPLECODEGENERATOR_H
+
+#include <qstringlist.h>
+#include <qstring.h>
+#include <qmap.h>
+
+#include "../codegenerator.h"
+#include "../umlnamespace.h"
+
+class UMLDoc;
+
+/**
+ * A simple code generator interface designed to work with
+ * the existing codewriters.
+ */
+class SimpleCodeGenerator : public CodeGenerator
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ SimpleCodeGenerator (bool createDirHierarchyForPackages = true);
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~SimpleCodeGenerator ( );
+
+ // Public attribute accessor methods
+ //
+
+ void writeCodeToFile ( UMLClassifierList & concepts);
+ void writeCodeToFile ( );
+
+ /**
+ * call this method to generate code for a UMLClassifier
+ * @param c the class you want to generate code for.
+ */
+ virtual void writeClass(UMLClassifier *c) = 0;
+
+ /**
+ * This is implemented only because we HAVE to.
+ * @return ClassifierCodeDocument
+ * @param classifier
+ */
+ CodeDocument * newClassifierCodeDocument (UMLClassifier * classifier);
+
+protected:
+
+ // compatability methods..
+ QString findFileName(UMLPackage* concept, const QString &ext);
+ QString overwritableName(UMLPackage* concept, const QString &name, const QString &ext);
+ bool hasDefaultValueAttr(UMLClassifier *c);
+ bool hasAbstractOps(UMLClassifier *c);
+
+ /**
+ * Returns the current indent string based on m_indentLevel and m_indentation.
+ */
+ QString getIndent ();
+
+ /**
+ * Maps UMLObjects to filenames. Used for finding out which file
+ * each class was written to.
+ */
+ QMap<UMLPackage*,QString> m_fileMap;
+
+ // the parent document
+ UMLDoc *m_doc;
+
+ /**
+ * For some code generators, it does not make much sense to create a
+ * directory for each package because that would lead to a rather
+ * sparsely populated directory tree (maximum of just one source file
+ * per directory.)
+ */
+ bool m_createDirHierarchyForPackages;
+
+ /* Old Attributes writers will look for */
+ QString m_indentation;
+ int m_indentLevel;
+ QString m_endl;
+
+ // override parent method..we need special handling
+ void initFromParentDocument( );
+
+private:
+
+ void initFields ( UMLDoc * doc) ;
+
+public slots:
+
+ void syncCodeToDocument ( );
+
+};
+
+#endif // SIMPLECODEGENERATOR_H
diff --git a/umbrello/umbrello/codegenerators/sqlwriter.cpp b/umbrello/umbrello/codegenerators/sqlwriter.cpp
new file mode 100644
index 00000000..f01e8bbe
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/sqlwriter.cpp
@@ -0,0 +1,394 @@
+/***************************************************************************
+ begin : 10.02.2003
+ copyright : (C) 2003 Nikolaus Gradwohl
+ email : guru@local-guru.net
+ (C) 2004-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "sqlwriter.h"
+
+#include <kdebug.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#include "../classifier.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+#include "../association.h"
+#include "../attribute.h"
+
+SQLWriter::SQLWriter() {
+}
+
+SQLWriter::~SQLWriter() {}
+
+void SQLWriter::writeClass(UMLClassifier *c) {
+
+ if(!c) {
+ kDebug()<<"Cannot write class of NULL concept!" << endl;
+ return;
+ }
+
+ const bool isClass = !c->isInterface();
+ QString classname = cleanName(c->getName());
+
+ //find an appropriate name for our file
+ QString fileName = findFileName(c, ".sql");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QFile file;
+ if( !openFile(file, fileName) ) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ //Start generating the code!!
+
+ QTextStream sql(&file);
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".sql");
+ if(!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"),fileName);
+ str.replace(QRegExp("%filepath%"),file.name());
+ sql<<str<<m_endl;
+ }
+
+ //Write class Documentation if there is somthing or if force option
+ if(forceDoc() || !c->getDoc().isEmpty()) {
+ sql << m_endl << "--" << m_endl;
+ sql<<"-- TABLE: "<<classname<<m_endl;
+ sql<<formatDoc(c->getDoc(),"-- ");
+ sql << "-- " << m_endl << m_endl;
+ }
+
+ sql << "CREATE TABLE "<< classname << " ( " << m_endl;
+
+ if (isClass)
+ writeAttributes(c, sql);
+
+ sql << m_endl << ");" << m_endl;
+
+ QMap<UMLAssociation*,UMLAssociation*> constraintMap; // so we don't repeat constraint
+ UMLAssociationList aggregations = c->getAggregations();
+ if( forceSections() || !aggregations.isEmpty() ) {
+ for(UMLAssociation* a = aggregations.first(); a; a = aggregations.next()) {
+ UMLObject *objA = a->getObject(Uml::A);
+ UMLObject *objB = a->getObject(Uml::B);
+ if (objA->getID() == c->getID() && objB->getID() != c->getID())
+ continue;
+ constraintMap[a] = a;
+ }
+ }
+
+ QMap<UMLAssociation*,UMLAssociation*>::Iterator itor = constraintMap.begin();
+ for (;itor != constraintMap.end();itor++) {
+ UMLAssociation* a = itor.data();
+ sql << "ALTER TABLE "<< classname
+ << " ADD CONSTRAINT " << a->getName() << " FOREIGN KEY ("
+ << a->getRoleName(Uml::B) << ") REFERENCES "
+ << a->getObject(Uml::A)->getName()
+ << " (" << a->getRoleName(Uml::A) << ");" << m_endl;
+ }
+
+
+ file.close();
+ emit codeGenerated(c, true);
+}
+
+
+void SQLWriter::writeAttributes(UMLClassifier *c, QTextStream &sql) {
+ UMLAttributeList atpub, atprot, atpriv, atimp;
+ atpub.setAutoDelete(false);
+ atprot.setAutoDelete(false);
+ atpriv.setAutoDelete(false);
+ atimp.setAutoDelete(false);
+
+ //sort attributes by scope and see if they have a default value
+ UMLAttributeList atl = c->getAttributeList();
+ for(UMLAttribute* at=atl.first(); at ; at=atl.next()) {
+ switch(at->getVisibility()) {
+ case Uml::Visibility::Public:
+ atpub.append(at);
+ break;
+ case Uml::Visibility::Protected:
+ atprot.append(at);
+ break;
+ case Uml::Visibility::Private:
+ atpriv.append(at);
+ break;
+ case Uml::Visibility::Implementation:
+ atimp.append(at);
+ break;
+ }
+ }
+
+ // now print the attributes; they are sorted by there scope
+ // in front of the first attribute shouldn't be a , -> so we need to find
+ // out, when the first attribute was added
+ bool first = true;
+
+ if (atpub.count() > 0)
+ {
+ printAttributes(sql, atpub, first);
+ first = false;
+ }
+
+ if (atprot.count() > 0)
+ {
+ printAttributes(sql, atprot, first);
+ first = false;
+ }
+
+ if (atpriv.count() > 0)
+ {
+ printAttributes(sql, atpriv, first);
+ first = false;
+ }
+
+ if (atimp.count() > 0)
+ {
+ printAttributes(sql, atimp, first);
+ first = false;
+ }
+
+ return;
+}
+
+void SQLWriter::printAttributes(QTextStream& sql, UMLAttributeList attributeList, bool first) {
+ QString attrDoc = "";
+ UMLAttribute* at;
+
+ for (at=attributeList.first();at;at=attributeList.next())
+ {
+ // print , after attribute
+ if (first == false) {
+ sql <<",";
+ } else {
+ first = false;
+ }
+
+ // print documentation/comment of last attribute at end of line
+ if (attrDoc.isEmpty() == false)
+ {
+ sql << " -- " << attrDoc << m_endl;
+ } else {
+ sql << m_endl;
+ }
+
+ // write the attribute
+ sql << m_indentation << cleanName(at->getName()) << " " << at->getTypeName() << " "
+ << (at->getInitialValue().isEmpty()?QString(""):QString(" DEFAULT ")+at->getInitialValue());
+
+ // now get documentation/comment of current attribute
+ attrDoc = at->getDoc();
+ }
+
+ // print documentation/comment at end of line
+ if (attrDoc.isEmpty() == false)
+ {
+ sql << " -- " << attrDoc << m_endl;
+ } else {
+ sql << m_endl;
+ }
+
+ return;
+}
+
+Uml::Programming_Language SQLWriter::getLanguage() {
+ return Uml::pl_SQL;
+}
+
+QStringList SQLWriter::defaultDatatypes() {
+ QStringList l;
+ l.append("varchar");
+ l.append("tinyint");
+ l.append("smallint");
+ l.append("mediumint");
+ l.append("bigint");
+ l.append("float");
+ l.append("double");
+ l.append("decimal");
+ l.append("date");
+ l.append("datetime");
+ l.append("time");
+ l.append("timestamp");
+ l.append("year");
+ l.append("char");
+ l.append("tinyblob");
+ l.append("blob");
+ l.append("mediumblob");
+ l.append("longblob");
+ l.append("tinytext");
+ l.append("text");
+ l.append("mediumtext");
+ l.append("longtext");
+ l.append("enum");
+ l.append("set");
+ return l;
+}
+
+const QStringList SQLWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "access"
+ << "add"
+ << "all"
+ << "alter"
+ << "analyze"
+ << "and"
+ << "any"
+ << "as"
+ << "asc"
+ << "audit"
+ << "begin"
+ << "between"
+ << "boolean"
+ << "by"
+ << "char"
+ << "character"
+ << "check"
+ << "cluster"
+ << "column"
+ << "comment"
+ << "commit"
+ << "compress"
+ << "connect"
+ << "create"
+ << "current"
+ << "cursor"
+ << "date"
+ << "decimal"
+ << "default"
+ << "delete"
+ << "desc"
+ << "distinct"
+ << "drop"
+ << "else"
+ << "elsif"
+ << "end"
+ << "escape"
+ << "exception"
+ << "exclusive"
+ << "execute"
+ << "exists"
+ << "explain"
+ << "false"
+ << "file"
+ << "float"
+ << "for"
+ << "from"
+ << "function"
+ << "grant"
+ << "group"
+ << "having"
+ << "identified"
+ << "if"
+ << "immediate"
+ << "in"
+ << "increment"
+ << "index"
+ << "initial"
+ << "insert"
+ << "integer"
+ << "intersect"
+ << "into"
+ << "is"
+ << "level"
+ << "like"
+ << "lock"
+ << "long"
+ << "loop"
+ << "maxextents"
+ << "minus"
+ << "mlslabel"
+ << "mode"
+ << "modify"
+ << "noaudit"
+ << "nocompress"
+ << "not"
+ << "nowait"
+ << "null"
+ << "number"
+ << "of"
+ << "offline"
+ << "on"
+ << "online"
+ << "option"
+ << "or"
+ << "order"
+ << "out"
+ << "pctfree"
+ << "prior"
+ << "privileges"
+ << "procedure"
+ << "public"
+ << "raw"
+ << "rename"
+ << "resource"
+ << "return"
+ << "revoke"
+ << "rollback"
+ << "row"
+ << "rowid"
+ << "rowlabel"
+ << "rownum"
+ << "rows"
+ << "savepoint"
+ << "select"
+ << "session"
+ << "set"
+ << "share"
+ << "size"
+ << "smallint"
+ << "some"
+ << "start"
+ << "successful"
+ << "synonym"
+ << "sysdate"
+ << "table"
+ << "then"
+ << "to"
+ << "trigger"
+ << "true"
+ << "truncate"
+ << "type"
+ << "uid"
+ << "union"
+ << "unique"
+ << "update"
+ << "user"
+ << "using"
+ << "validate"
+ << "values"
+ << "varchar"
+ << "varchar2"
+ << "varray"
+ << "view"
+ << "whenever"
+ << "where"
+ << "with";
+ }
+
+ return keywords;
+}
+
+#include "sqlwriter.moc"
diff --git a/umbrello/umbrello/codegenerators/sqlwriter.h b/umbrello/umbrello/codegenerators/sqlwriter.h
new file mode 100644
index 00000000..c500e2e7
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/sqlwriter.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ sqlwriter.h - description
+ -------------------
+ begin : 10.02.2003
+ copyright : (C) 2003 by Nikolaus Gradwohl
+ email : guru@local-guru.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQLWRITER_H
+#define SQLWRITER_H
+
+#include "simplecodegenerator.h"
+#include "../umlattributelist.h"
+
+/**
+ * class SQLWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate a sql source file for
+ * that concept
+ */
+class SQLWriter : public SimpleCodeGenerator {
+ Q_OBJECT
+public:
+
+ SQLWriter();
+ virtual ~SQLWriter();
+
+ /**
+ * call this method to generate sql code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "SQL"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * Reimplement method from CodeGenerator.
+ */
+ virtual QStringList defaultDatatypes();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * write all attributes for a given class
+ * @param c the class for which we are generating code
+ * @param j the stream associated with the output file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &j);
+
+ /**
+ * Prints out attributes as columns in the table
+ *
+ * @param sql the stream we should print to
+ * @param attributeList the attributes to be printed
+ * @param first if the attributes are the first one
+ */
+ void printAttributes(QTextStream& sql, UMLAttributeList attributeList, bool first);
+};
+
+#endif // SQLWRITER_H
diff --git a/umbrello/umbrello/codegenerators/tclwriter.cpp b/umbrello/umbrello/codegenerators/tclwriter.cpp
new file mode 100644
index 00000000..d8607aa7
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/tclwriter.cpp
@@ -0,0 +1,951 @@
+/***************************************************************************
+ begin : Thu Jul 26 2005
+ copyright : (C) 2005 by Rene Meyer
+ email : rene.meyer@sturmit.de
+ (C) 2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// own header
+#include "tclwriter.h"
+// qt/kde includes
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <kdebug.h>
+// app includes
+#include "classifierinfo.h"
+#include "codegen_utils.h"
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../template.h"
+#include "../umltemplatelist.h"
+#include "../umlclassifierlistitemlist.h"
+#include "../classifierlistitem.h"
+#include "../model_utils.h"
+
+static const char *tclwords[] = {
+ "body",
+ "break",
+ "case",
+ "class",
+ "common",
+ "concat",
+ "configbody",
+ "constructor",
+ "continue",
+ "default",
+ "destructor",
+ "else",
+ "elseif",
+ "for",
+ "foreach",
+ "global",
+ "if",
+ "incr",
+ "lappend",
+ "lindex",
+ "list",
+ "llength",
+ "load",
+ "lrange",
+ "lreplace",
+ "method",
+ "namespace",
+ "private",
+ "proc",
+ "protected",
+ "public",
+ "return",
+ "set",
+ "source",
+ "switch",
+ "then",
+ "upvar",
+ "variable",
+ "virtual",
+ "while",
+ 0
+ };
+
+TclWriter::TclWriter()
+{
+}
+
+TclWriter::~TclWriter()
+{
+}
+
+Uml::Programming_Language
+TclWriter::getLanguage()
+{
+ return Uml::pl_Tcl;
+}
+
+void
+TclWriter::writeClass(UMLClassifier * c)
+{
+
+ if (!c) {
+ kDebug() << "Cannot write class of NULL concept!\n";
+ return;
+ }
+ QFile fileh, filetcl;
+
+ // find an appropriate name for our file
+ QString fileName = findFileName(c, ".tcl");
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ if (!openFile(fileh, fileName)) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ // preparations
+ classifierInfo = new ClassifierInfo(c);
+ classifierInfo->fileName = fileName;
+ classifierInfo->className = cleanName(c->getName());
+ mClass = cleanName(c->getName());
+ if (!c->getPackage().isEmpty()) {
+ mNamespace = "::" + cleanName(c->getPackage());
+ mClassGlobal = mNamespace + "::" + mClass;
+ } else {
+ mNamespace = "::";
+ mClassGlobal = "::" + mClass;
+ }
+
+ // write Header file
+ writeHeaderFile(c, fileh);
+ fileh.close();
+
+ // Determine whether the implementation file is required.
+ // (It is not required if the class is an enumeration.)
+ bool need_impl = true;
+ if (!classifierInfo->isInterface) {
+ if (c->getBaseType() == Uml::ot_Enum)
+ need_impl = false;
+ }
+ if (need_impl) {
+ if (!openFile(filetcl, fileName + "body")) {
+ emit codeGenerated(c, false);
+ return;
+ }
+ // write Source file
+ writeSourceFile(c, filetcl);
+ filetcl.close();
+ }
+ // Wrap up: free classifierInfo, emit done code
+ classifierInfo = 0;
+
+ emit codeGenerated(c, true);
+
+}
+
+void
+TclWriter::writeHeaderFile(UMLClassifier * c, QFile & fileh)
+{
+ // open stream for writing
+ QTextStream stream(&fileh);
+ mStream = &stream;
+
+ // reset the indent level
+ m_indentLevel = 0;
+
+ // write header blurb
+ QString str = getHeadingFile(".tcl");
+ if (!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"), classifierInfo->fileName);
+ str.replace(QRegExp("%filepath%"), fileh.name());
+ writeCode(str);
+ }
+ // set current namespace
+ writeCode("namespace eval " + mNamespace + " {");
+ m_indentLevel++;
+
+ // check on already existing
+ writeComm("Do not load twice");
+ writeCode("if {[namespace exist " + mClass + "]} return");
+
+ // source used superclass files
+ UMLClassifierList superclasses = classifierInfo->superclasses;
+ if (superclasses.count() > 0) {
+ writeComm
+ ("Source found and used class files and import class command if necessary");
+
+ for (UMLClassifier * classifier = superclasses.first(); classifier;
+ classifier = superclasses.next()) {
+ writeUse(classifier);
+ }
+ }
+ // write all "source" we need to include other classes, that arent us.
+ if (classifierInfo->hasAssociations) {
+ writeAssociationIncl(classifierInfo->plainAssociations, c->getID(),
+ "Associations");
+ writeAssociationIncl(classifierInfo->aggregations, c->getID(),
+ "Aggregations");
+ writeAssociationIncl(classifierInfo->compositions, c->getID(),
+ "Compositions");
+ }
+ //Write class Documentation
+ writeDocu("\n@class\t" + mClass + m_endl + c->getDoc());
+
+ //check if class is abstract and / or has abstract methods
+ if ((c->getAbstract() || classifierInfo->isInterface)
+ && !hasAbstractOps(c)) {
+ writeComm("TODO abstract class" + mClass +
+ "\nInherit from it and create only objects from the derived classes");
+ }
+ // check on enum classes
+ if (!classifierInfo->isInterface) {
+ // use tcl-list for enum's
+ if (c->getBaseType() == Uml::ot_Enum) {
+ UMLClassifierListItemList litList =
+ c->getFilteredList(Uml::ot_EnumLiteral);
+ writeCode("set enum_" + mClass + " [list\\");
+ m_indentLevel++;
+ for (UMLClassifierListItem * lit = litList.first(); lit;
+ lit = litList.next()) {
+ QString enumLiteral = cleanName(lit->getName());
+ writeCode(enumLiteral + "\\");
+ }
+ m_indentLevel--;
+ writeCode("];# end of enum");
+ m_indentLevel--;
+ writeCode("};# end of namespace");
+ return;
+ }
+ }
+ // Generate template parameters.
+ UMLTemplateList template_params = c->getTemplateList();
+ if (template_params.count()) {
+ writeCode("#TODO template<");
+ for (UMLTemplate * t = template_params.first(); t;
+ t = template_params.next()) {
+ QString formalName = t->getName();
+ QString typeName = t->getTypeName();
+ writeCode(typeName + "# " + formalName);
+ }
+ }
+ // start my own class
+ writeCode("class " + mClass + " {");
+ m_indentLevel++;
+ if (classifierInfo->superclasses.count() > 0) {
+ QString code = "inherit";
+ for (UMLClassifier * superClass = classifierInfo->superclasses.first();
+ superClass; superClass = classifierInfo->superclasses.next()) {
+ /*
+ if (superClass->getAbstract() || superClass->isInterface())
+ stream << getIndent() << "virtual ";
+ */
+ if (superClass->getPackage().isEmpty()) {
+ code += " ::" + cleanName(superClass->getName());
+ } else {
+ code +=
+ " ::" + cleanName(superClass->getPackage()) + "::" +
+ cleanName(superClass->getName());
+ }
+ }
+ writeCode(code);
+ }
+ //
+ //declarations of operations
+ //
+ // write out field and operations decl grouped by visibility
+ //
+
+ // PUBLIC attribs/methods
+ // for public: constructors are first ops we print out
+ if (!classifierInfo->isInterface) {
+ writeConstructorHeader();
+ writeDestructorHeader();
+ }
+ // attributes
+ writeAttributeDecl(Uml::Visibility::Public, true); // write static attributes first
+ writeAttributeDecl(Uml::Visibility::Public, false);
+ // associations
+ writeAssociationDecl(classifierInfo->plainAssociations, Uml::Visibility::Public,
+ c->getID(), "Associations");
+ writeAssociationDecl(classifierInfo->aggregations, Uml::Visibility::Public, c->getID(),
+ "Aggregations");
+ writeAssociationDecl(classifierInfo->compositions, Uml::Visibility::Public, c->getID(),
+ "Compositions");
+ //TODO writeHeaderAccessorMethodDecl(c, Uml::Visibility::Public, stream);
+ writeOperationHeader(c, Uml::Visibility::Public);
+
+ // PROTECTED attribs/methods
+ //
+ // attributes
+ writeAttributeDecl(Uml::Visibility::Protected, true); // write static attributes first
+ writeAttributeDecl(Uml::Visibility::Protected, false);
+ // associations
+ writeAssociationDecl(classifierInfo->plainAssociations, Uml::Visibility::Protected,
+ c->getID(), "Association");
+ writeAssociationDecl(classifierInfo->aggregations, Uml::Visibility::Protected,
+ c->getID(), "Aggregation");
+ writeAssociationDecl(classifierInfo->compositions, Uml::Visibility::Protected,
+ c->getID(), "Composition");
+ //TODO writeHeaderAccessorMethodDecl(c, Uml::Visibility::Protected, stream);
+ writeOperationHeader(c, Uml::Visibility::Protected);
+
+ // PRIVATE attribs/methods
+ //
+ // attributes
+ writeAttributeDecl(Uml::Visibility::Private, true); // write static attributes first
+ writeAttributeDecl(Uml::Visibility::Private, false);
+ // associations
+ writeAssociationDecl(classifierInfo->plainAssociations, Uml::Visibility::Private,
+ c->getID(), "Associations");
+ writeAssociationDecl(classifierInfo->aggregations, Uml::Visibility::Private, c->getID(),
+ "Aggregations");
+ writeAssociationDecl(classifierInfo->compositions, Uml::Visibility::Private, c->getID(),
+ "Compositions");
+ //TODO writeHeaderAccessorMethodDecl(c, Uml::Visibility::Public, stream);
+ writeOperationHeader(c, Uml::Visibility::Private);
+ writeInitAttributeHeader(); // this is always private, used by constructors to initialize class
+
+ // end of class header
+ m_indentLevel--;
+ writeCode("};# end of class");
+
+ // end of class namespace, if any
+ m_indentLevel--;
+ writeCode("};# end of namespace");
+}
+
+void
+TclWriter::writeSourceFile(UMLClassifier * c, QFile & filetcl)
+{
+ // open stream for writing
+ QTextStream stream(&filetcl);
+ mStream = &stream;
+
+ // set the starting indentation at zero
+ m_indentLevel = 0;
+
+ //try to find a heading file (license, coments, etc)
+ QString str;
+ str = getHeadingFile(".tclbody");
+ if (!str.isEmpty()) {
+ str.replace(QRegExp("%filename%"), classifierInfo->fileName + "body");
+ str.replace(QRegExp("%filepath%"), filetcl.name());
+ writeCode(str);
+ }
+ // Start body of class
+
+ // constructors are first ops we print out
+ if (!classifierInfo->isInterface) {
+ writeConstructorSource();
+ writeDestructorSource();
+ }
+ // Public attributes have in tcl a configbody method
+ writeAttributeSource();
+ // Association access functions
+ writeAssociationSource(classifierInfo->plainAssociations, c->getID());
+ writeAssociationSource(classifierInfo->aggregations, c->getID());
+ writeAssociationSource(classifierInfo->compositions, c->getID());
+ // Procedures and methods
+ writeOperationSource(c, Uml::Visibility::Public);
+ writeOperationSource(c, Uml::Visibility::Protected);
+ writeOperationSource(c, Uml::Visibility::Private);
+ // Yep, bringing up the back of the bus, our initialization method for attributes
+ writeInitAttributeSource();
+}
+
+void
+TclWriter::writeCode(const QString &text)
+{
+ *mStream << getIndent() << text << m_endl;
+}
+
+void
+TclWriter::writeComm(const QString &text)
+{
+ QStringList lines = QStringList::split("\n", text, true);
+ for (uint i = 0; i < lines.count(); i++) {
+ *mStream << getIndent() << "# " << lines[i] << m_endl;
+ }
+}
+
+void
+TclWriter::writeDocu(const QString &text)
+{
+ QStringList lines = QStringList::split("\n", text, true);
+ for (uint i = 0; i < lines.count(); i++) {
+ *mStream << getIndent() << "## " << lines[i] << m_endl;
+ }
+}
+
+// To prevent circular including when both classifiers on either end
+// of an association have roles we need to have forward declaration of
+// the other class...but only IF its not THIS class (as could happen
+// in self-association relationship).
+void
+TclWriter::writeAssociationIncl(UMLAssociationList list, Uml::IDType myId,
+ const QString &type)
+{
+ for (UMLAssociation * a = list.first(); a; a = list.next()) {
+ UMLClassifier *classifier = NULL;
+
+ writeComm(m_endl + type + m_endl + a->toString() + m_endl + a->getDoc());
+ // only use OTHER classes (e.g. we don't need to write includes for ourselves!!
+ // AND only IF the roleName is defined, otherwise, its not meant to be noticed.
+ if (a->getObjectId(Uml::A) == myId && !a->getRoleName(Uml::B).isEmpty()) {
+ classifier = dynamic_cast < UMLClassifier * >(a->getObject(Uml::B));
+ writeUse(classifier);
+ } else if (a->getObjectId(Uml::B) == myId
+ && !a->getRoleName(Uml::A).isEmpty()) {
+ classifier = dynamic_cast < UMLClassifier * >(a->getObject(Uml::A));
+ if (classifier->getPackage().isEmpty())
+ writeCode("namespace eval " + cleanName(classifier->getName()) +
+ " {}");
+ } else {
+ // CHECK: This crashes (classifier still NULL from above)
+ /*
+ writeCode("namespace eval " + cleanName(classifier->getPackage()) +
+ "::" + cleanName(classifier->getName()) + " {}");
+ */
+ }
+ }
+}
+
+void
+TclWriter::writeUse(UMLClassifier * c)
+{
+ QString myNs;
+
+ if (!c->getPackage().isEmpty()) {
+ myNs = cleanName(c->getPackage());
+ } else {
+ myNs = "";
+ }
+ // if different package
+ if (("::"+myNs) != mNamespace) {
+ if (c->getPackage().isEmpty()) {
+ writeCode("source " + findFileName(c, ".tcl"));
+ writeCode("namespace import ::" + cleanName(c->getName()));
+ } else {
+ writeCode("package require " + myNs);
+ writeCode("namespace import ::" + myNs + "::" +
+ cleanName(c->getName()));
+ }
+ } else {
+ // source the file
+ writeCode("source " + findFileName(c, ".tcl"));
+ }
+}
+
+void
+TclWriter::writeConstructorHeader()
+{
+
+ writeDocu
+ (m_endl + "@func constructor" + m_endl +
+ "@par args contain all configuration parameters" + m_endl);
+
+ writeCode("constructor {args} {}" + m_endl);
+}
+
+void
+TclWriter::writeConstructorSource()
+{
+ writeComm(mClassGlobal + "::constructor");
+ writeCode(mClassGlobal + "::constructor {args} {");
+ m_indentLevel++;
+ if (classifierInfo->hasAttributes) {
+ writeCode("initAttributes");
+ }
+ writeCode("eval configure $args");
+ m_indentLevel--;
+ writeCode('}' + m_endl);
+}
+
+void
+TclWriter::writeDestructorHeader()
+{
+
+ writeDocu(m_endl + "@func destructor" + m_endl);
+
+ writeCode("destructor {} {}");
+}
+
+void
+TclWriter::writeDestructorSource()
+{
+ writeComm(mClassGlobal + "::destructor");
+ writeCode(mClassGlobal + "::destructor {} {" + m_endl + '}' + m_endl);
+}
+
+void
+TclWriter::writeAttributeDecl(Uml::Visibility visibility, bool writeStatic)
+{
+ if (classifierInfo->isInterface)
+ return;
+
+ QString scope = visibility.toString();
+ QString type;
+ if (writeStatic) {
+ type = "common";
+ } else {
+ type = "variable";
+ }
+ UMLAttributeList *list = NULL;
+ switch (visibility) {
+ case Uml::Visibility::Private:
+ if (writeStatic) {
+ list = &(classifierInfo->static_atpriv);
+ } else {
+ list = &(classifierInfo->atpriv);
+ }
+ break;
+
+ case Uml::Visibility::Protected:
+ if (writeStatic) {
+ list = &(classifierInfo->static_atprot);
+ } else {
+ list = &(classifierInfo->atprot);
+ }
+ break;
+
+ case Uml::Visibility::Public:
+ if (writeStatic) {
+ list = &(classifierInfo->static_atpub);
+ } else {
+ list = &(classifierInfo->atpub);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (list && list->count() > 0) {
+ writeComm(m_endl + scope + ' ' + type + " attributes" + m_endl);
+ // write attrib declarations now
+ QString documentation;
+ for (UMLAttribute * at = list->first(); at; at = list->next()) {
+ documentation = at->getDoc();
+ QString varName = cleanName(at->getName());
+ QString typeName = fixTypeName(at->getTypeName());
+ writeDocu(m_endl + "@var " + scope + ' ' + type + ' ' + typeName + ' ' +
+ varName + m_endl + documentation);
+ writeCode(scope + ' ' + type + ' ' + varName + m_endl);
+ }
+ }
+}
+
+void
+TclWriter::writeAssociationDecl(UMLAssociationList associations,
+ Uml::Visibility permitScope, Uml::IDType id,
+ const QString &/*type*/)
+{
+ if (forceSections() || !associations.isEmpty()) {
+ bool printRoleA = false, printRoleB = false;
+ for (UMLAssociation * a = associations.first(); a;
+ a = associations.next()) {
+
+ // it may seem counter intuitive, but you want to insert the role of the
+ // *other* class into *this* class.
+ if (a->getObjectId(Uml::A) == id && !a->getRoleName(Uml::B).isEmpty())
+ printRoleB = true;
+
+ if (a->getObjectId(Uml::B) == id && !a->getRoleName(Uml::A).isEmpty())
+ printRoleA = true;
+
+ // First: we insert documentaion for association IF it has either role AND some documentation (!)
+ // print RoleB decl
+ if (printRoleB && a->getVisibility(Uml::B) == permitScope) {
+
+ QString fieldClassName =
+ cleanName(getUMLObjectName(a->getObject(Uml::B)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::B),
+ a->getMulti(Uml::B), a->getRoleDoc(Uml::B),
+ permitScope.toString());
+ }
+ // print RoleA decl
+ if (printRoleA && a->getVisibility(Uml::A) == permitScope) {
+ QString fieldClassName =
+ cleanName(getUMLObjectName(a->getObject(Uml::A)));
+ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::A),
+ a->getMulti(Uml::A), a->getRoleDoc(Uml::A),
+ permitScope.toString());
+ }
+ // reset for next association in our loop
+ printRoleA = false;
+ printRoleB = false;
+ }
+ }
+}
+
+void
+TclWriter::writeAssociationRoleDecl(const QString &fieldClassName, const QString &roleName,
+ const QString &multi, const QString &doc, const QString &scope)
+{
+ // ONLY write out IF there is a rolename given
+ // otherwise its not meant to be declared in the code
+ if (roleName.isEmpty())
+ return;
+
+
+ // declare the association based on whether it is this a single variable
+ // or a List (Vector). One day this will be done correctly with special
+ // multiplicity object that we don't have to figure out what it means via regex.
+ if (multi.isEmpty() || multi.contains(QRegExp("^[01]$"))) {
+ QString fieldVarName = roleName.lower();
+
+ // record this for later consideration of initialization IF the
+ // multi value requires 1 of these objects
+ if (ObjectFieldVariables.findIndex(fieldVarName) == -1 &&
+ multi.contains(QRegExp("^1$"))
+ ) {
+ // ugh. UGLY. Storing variable name and its class in pairs.
+ ObjectFieldVariables.append(fieldVarName);
+ ObjectFieldVariables.append(fieldClassName);
+ }
+ writeDocu(m_endl + "@var " + scope + " variable <" + fieldClassName +
+ "> " + fieldVarName + m_endl + doc);
+ writeCode(scope + " variable " + fieldVarName + m_endl);
+ } else {
+ QString fieldVarName = roleName.lower();
+
+ // record unique occurrences for later when we want to check
+ // for initialization of this vector
+ if (VectorFieldVariables.findIndex(fieldVarName) == -1)
+ VectorFieldVariables.append(fieldVarName);
+ writeDocu(m_endl + "@var" + scope + " variable <" + fieldClassName +
+ "*> " + fieldVarName + m_endl + doc);
+ writeCode(scope + " variable " + fieldVarName + m_endl);
+ }
+}
+
+void
+TclWriter::writeInitAttributeHeader()
+{
+ if (classifierInfo->hasAttributes) {
+ writeDocu("@method private initAttributes" + m_endl +
+ "Initialize all internal variables");
+ writeCode("private method initAttributes {}");
+ }
+}
+
+void
+TclWriter::writeInitAttributeSource()
+{
+ // only need to do this under certain conditions
+ if (classifierInfo->hasAttributes) {
+ QString varName;
+
+ writeComm(mClassGlobal + "::initAttributes");
+ writeCode("body " + mClassGlobal + "::initAttributes {} {");
+ m_indentLevel++;
+
+ // first, initiation of fields derived from attributes
+ UMLAttributeList atl = classifierInfo->getAttList();
+ for (UMLAttribute * at = atl.first(); at; at = atl.next()) {
+ if (!at->getInitialValue().isEmpty()) {
+ varName = cleanName(at->getName());
+ writeCode("set " + varName + ' ' + at->getInitialValue());
+ }
+ }
+ // Now initialize the association related fields (e.g. vectors)
+ QStringList::Iterator it;
+ for (it = VectorFieldVariables.begin();
+ it != VectorFieldVariables.end(); ++it) {
+ varName = *it;
+ writeCode("set " + varName + " [list]");
+ }
+
+ for (it = ObjectFieldVariables.begin();
+ it != ObjectFieldVariables.end(); ++it) {
+ varName = *it;
+ it++;
+ QString fieldClassName = *it;
+ writeCode("set " + varName + " [list]");
+ }
+ // clean up
+ ObjectFieldVariables.clear(); // shouldn't be needed?
+ VectorFieldVariables.clear(); // shouldn't be needed?
+
+ m_indentLevel--;
+ writeCode('}' + m_endl);
+ }
+}
+
+void
+TclWriter::writeOperationHeader(UMLClassifier * c, Uml::Visibility permitScope)
+{
+
+ UMLOperationList oplist;
+ UMLOperation *op;
+ UMLAttribute *at;
+ int j;
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList inputlist = c->getOpList();
+ for (UMLOperation * op = inputlist.first(); op; op = inputlist.next()) {
+ switch (op->getVisibility()) {
+ case Uml::Visibility::Public:
+ if (permitScope == Uml::Visibility::Public)
+ oplist.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ if (permitScope == Uml::Visibility::Protected)
+ oplist.append(op);
+ break;
+ case Uml::Visibility::Private:
+ if (permitScope == Uml::Visibility::Private)
+ oplist.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // generate method decl for each operation given
+ if (oplist.count() > 0) {
+ writeComm("Operations");
+ }
+ for (op = oplist.first(); op; op = oplist.next()) {
+ QString doc = "";
+ QString code = "";
+ QString methodReturnType = fixTypeName(op->getTypeName());
+ QString name = cleanName(op->getName());
+ QString scope = permitScope.toString();
+ if (op->getAbstract() || classifierInfo->isInterface) {
+ //TODO declare abstract method as 'virtual'
+ // str += "virtual ";
+ }
+ // declaration for header file
+ if (op->getStatic()) {
+ doc = m_endl + "@fn " + scope + " proc " + name + m_endl;
+ code = scope + " proc " + name + " {";
+ } else {
+ doc = m_endl + "@fn " + scope + " method " + name + m_endl;
+ code = scope + " method " + name + " {";
+ }
+ // method parameters
+ UMLAttributeList atl = op->getParmList();
+ j = 0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+ QString typeName = fixTypeName(at->getTypeName());
+ QString atName = cleanName(at->getName());
+ if (at->getInitialValue().isEmpty()) {
+ doc +=
+ "@param " + typeName + ' ' + atName + m_endl + at->getDoc() +
+ m_endl;
+ code += ' ' + atName;
+ } else {
+ doc +=
+ "@param " + typeName + ' ' + atName + " (default=" +
+ at->getInitialValue() + ") " + m_endl + at->getDoc() + m_endl;
+ code += " {" + atName + ' ' + at->getInitialValue() + "} ";
+ }
+ }
+ if (methodReturnType != "void") {
+ doc += "@return " + methodReturnType + m_endl;
+ }
+ writeDocu(doc + op->getDoc());
+ writeCode(code + "} {}" + m_endl);
+ }
+}
+
+void
+TclWriter::writeOperationSource(UMLClassifier * c, Uml::Visibility permitScope)
+{
+
+ UMLOperationList oplist;
+ UMLOperation *op;
+ UMLAttribute *at;
+ int j;
+
+ //sort operations by scope first and see if there are abstract methods
+ UMLOperationList inputlist = c->getOpList();
+ for (UMLOperation * op = inputlist.first(); op; op = inputlist.next()) {
+ switch (op->getVisibility()) {
+ case Uml::Visibility::Public:
+ if (permitScope == Uml::Visibility::Public)
+ oplist.append(op);
+ break;
+ case Uml::Visibility::Protected:
+ if (permitScope == Uml::Visibility::Protected)
+ oplist.append(op);
+ break;
+ case Uml::Visibility::Private:
+ if (permitScope == Uml::Visibility::Private)
+ oplist.append(op);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // generate source for each operation given
+ for (op = oplist.first(); op; op = oplist.next()) {
+ QString code = "";
+ QString methodReturnType = fixTypeName(op->getTypeName());
+ QString name;
+ // no code needed
+ if (op->getAbstract() || classifierInfo->isInterface) {
+ continue;
+ }
+ name = mClassGlobal + "::" + cleanName(op->getName());
+ writeComm(name);
+ code = "body " + name + " {";
+ // parameters
+ UMLAttributeList atl = op->getParmList();
+ j = 0;
+ for (at = atl.first(); at; at = atl.next(), j++) {
+ QString atName = cleanName(at->getName());
+ if (at->getInitialValue().isEmpty()) {
+ code += ' ' + atName;
+ } else {
+ code += " {" + atName + ' ' + at->getInitialValue() + "} ";
+ }
+ }
+ writeCode(code += "} {");
+ m_indentLevel++;
+ if (methodReturnType != "void") {
+ writeCode("return " + methodReturnType);
+ } else {
+ writeCode("return");
+ }
+ m_indentLevel--;
+ writeCode('}' + m_endl);
+ }
+}
+
+void
+TclWriter::writeAttributeSource()
+{
+ UMLAttributeList *list = &(classifierInfo->atpub);
+ UMLAttribute *at;
+ for (at = list->first(); at; at = list->next()) {
+ QString name = mClassGlobal + "::" + cleanName(at->getName());
+
+ writeComm(name);
+ writeCode("configbody " + name + " {} {" + m_endl + '}' + m_endl);
+ }
+}
+
+void
+TclWriter::writeAssociationSource(UMLAssociationList associations,
+ Uml::IDType id)
+{
+ if (associations.isEmpty()) {
+ return;
+ }
+
+ bool printRoleA = false, printRoleB = false;
+ for (UMLAssociation * a = associations.first(); a; a = associations.next()) {
+
+ // it may seem counter intuitive, but you want to insert the role of the
+ // *other* class into *this* class.
+ if (a->getObjectId(Uml::A) == id && !a->getRoleName(Uml::B).isEmpty())
+ printRoleB = true;
+
+ if (a->getObjectId(Uml::B) == id && !a->getRoleName(Uml::A).isEmpty())
+ printRoleA = true;
+
+ // print RoleB source
+ if (printRoleB && a->getVisibility(Uml::B) == Uml::Visibility::Public) {
+
+ QString fieldClassName =
+ cleanName(getUMLObjectName(a->getObject(Uml::B)));
+ writeAssociationRoleSource(fieldClassName, a->getRoleName(Uml::B),
+ a->getMulti(Uml::B));
+ }
+ // print RoleA source
+ if (printRoleA && a->getVisibility(Uml::A) == Uml::Visibility::Public) {
+ QString fieldClassName =
+ cleanName(getUMLObjectName(a->getObject(Uml::A)));
+ writeAssociationRoleSource(fieldClassName, a->getRoleName(Uml::A),
+ a->getMulti(Uml::A));
+ }
+ // reset for next association in our loop
+ printRoleA = false;
+ printRoleB = false;
+ }
+}
+
+void
+TclWriter::writeAssociationRoleSource(const QString &fieldClassName,
+ const QString &roleName, const QString &multi)
+{
+ // ONLY write out IF there is a rolename given
+ // otherwise its not meant to be declared in the code
+ if (roleName.isEmpty())
+ return;
+
+ // declare the association based on whether it is this a single variable
+ // or a List (Vector). One day this will be done correctly with special
+ // multiplicity object that we don't have to figure out what it means via regex.
+ if (multi.isEmpty() || multi.contains(QRegExp("^[01]$"))) {
+ QString fieldVarName = roleName.lower();
+
+ writeCode("configbody " + mClassGlobal + "::" + fieldVarName + " {} {");
+ m_indentLevel++;
+ writeCode("if {![$" + fieldVarName + " isa " + fieldClassName + "]} {");
+ m_indentLevel++;
+ writeCode("return -code error \"expected object of class: " +
+ fieldClassName + "\"");
+ m_indentLevel--;
+ writeCode("}");
+ m_indentLevel--;
+
+ } else {
+ QString fieldVarName = roleName.lower();
+
+ writeCode("configbody " + mClassGlobal + "::" + fieldVarName + " {} {");
+ m_indentLevel++;
+ writeCode("foreach myObj $" + fieldVarName + " {");
+ m_indentLevel++;
+ writeCode("if {![$myObj isa " + fieldClassName + "]} {");
+ m_indentLevel++;
+ writeCode("return -code error \"expected object of class: " +
+ fieldClassName + "\"");
+ m_indentLevel--;
+ writeCode("}");
+ m_indentLevel--;
+ writeCode("}");
+ m_indentLevel--;
+ }
+ writeCode('}' + m_endl);
+}
+
+QString
+TclWriter::fixTypeName(const QString &string)
+{
+ if (string.isEmpty())
+ return "void";
+ return string;
+}
+
+// methods like this _shouldn't_ be needed IF we properly did things thruought the code.
+QString
+TclWriter::getUMLObjectName(UMLObject * obj)
+{
+ return (obj != 0) ? obj->getName() : QString("NULL");
+}
+
+const QStringList
+TclWriter::reservedKeywords() const
+{
+ static QStringList keywords;
+
+ if (keywords.isEmpty())
+ {
+ for (int i = 0; tclwords[i]; i++)
+ keywords.append(tclwords[i]);
+ }
+ return keywords;
+}
+
diff --git a/umbrello/umbrello/codegenerators/tclwriter.h b/umbrello/umbrello/codegenerators/tclwriter.h
new file mode 100644
index 00000000..0c4d71c5
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/tclwriter.h
@@ -0,0 +1,174 @@
+/***************************************************************************
+ tclwriter.h - description
+ -------------------
+ begin : Thu Jul 26 2005
+ copyright : (C) 2005 by Rene Meyer
+ email : rene.meyer@sturmit.de
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef TCLWRITER_H
+#define TCLWRITER_H
+
+#include <qstringlist.h>
+#include "simplecodegenerator.h"
+#include "../umloperationlist.h"
+#include "../umlattributelist.h"
+#include "../umlassociationlist.h"
+
+class QFile;
+class QTextStream;
+class ClassifierInfo;
+
+/**
+ * class TclWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate both a header (.h) and
+ * source (.tcl) file for that classifier.
+ */
+class TclWriter : public SimpleCodeGenerator
+{
+public:
+
+ /**
+ * Constructor, initialises a couple of variables
+ */
+ TclWriter();
+
+ /**
+ * Destructor, empty
+ */
+ virtual ~ TclWriter();
+
+ /**
+ * call this method to generate tcl code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass(UMLClassifier * c);
+
+ /**
+ * returns "Tcl"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+ /**
+ * Current output stream.
+ */
+ QTextStream * mStream;
+ /**
+ * write the header file for this classifier.
+ */
+ void writeHeaderFile(UMLClassifier * c, QFile & file);
+
+ /**
+ * write the source code body file for this classifier.
+ */
+ void writeSourceFile(UMLClassifier * c, QFile & file);
+
+ /**
+ * write the source codei text.
+ */
+ void writeCode(const QString &text);
+
+ /**
+ * write comment text.
+ */
+ void writeComm(const QString &text);
+
+ /**
+ * write documentation text.
+ */
+ void writeDocu(const QString &text);
+
+ void writeConstructorDecl();
+
+ void writeDestructorDecl();
+
+ /**
+ * Summary information about current classifier.
+ */
+ ClassifierInfo *classifierInfo;
+ QString mNamespace;
+ QString mClass;
+ QString mClassGlobal;
+
+ /**
+ * writes the Attribute declarations
+ * @param visibility the visibility of the attribs to print out
+ * @param writeStatic whether to write static or non-static attributes out
+ * @param stream text stream
+ */
+ void writeAttributeDecl(Uml::Visibility visibility, bool writeStatic);
+
+ void writeAssociationIncl(UMLAssociationList list,
+ Uml::IDType myId, const QString &type);
+ /**
+ * Searches a list of associations for appropriate ones to write out as attributes
+ */
+ void writeAssociationDecl(UMLAssociationList associations,
+ Uml::Visibility permit, Uml::IDType id,
+ const QString &type);
+
+ /**
+ * Writes out an association as an attribute using Vector
+ */
+ void writeAssociationRoleDecl(const QString &fieldClassName,
+ const QString &roleName, const QString &multi, const QString &doc, const QString &docname);
+
+ /**
+ * If needed, write out the declaration for the method to initialize attributes of our class.
+ */
+ void writeInitAttributeHeader();
+ void writeInitAttributeSource();
+
+ void writeConstructorHeader();
+ void writeConstructorSource();
+ void writeDestructorHeader();
+ void writeDestructorSource();
+ void writeOperationHeader(UMLClassifier * c,
+ Uml::Visibility permitScope);
+ void writeOperationSource(UMLClassifier * c,
+ Uml::Visibility permitScope);
+ void writeAttributeSource();
+ void writeAssociationSource(UMLAssociationList associations,
+ Uml::IDType id);
+ void writeAssociationRoleSource(const QString &fieldClassName,
+ const QString &roleName,
+ const QString &multi);
+ void writeUse(UMLClassifier * c);
+
+
+
+ /**
+ * Returns the name of the given object (if it exists)
+ */
+ QString getUMLObjectName(UMLObject * obj);
+
+ /**
+ * Replaces `string' with STRING_TYPENAME.
+ */
+ QString fixTypeName(const QString &string);
+
+ QStringList ObjectFieldVariables;
+ QStringList VectorFieldVariables;
+
+};
+
+
+
+#endif // TCLWRITER_H
diff --git a/umbrello/umbrello/codegenerators/xmlcodecomment.cpp b/umbrello/umbrello/codegenerators/xmlcodecomment.cpp
new file mode 100644
index 00000000..5f44620b
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/xmlcodecomment.cpp
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * *
+ * 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 : Mon Sep 26 2003
+ */
+
+#include "xmlcodecomment.h"
+
+#include <kdebug.h>
+
+// Constructors/Destructors
+//
+
+XMLCodeComment::XMLCodeComment ( CodeDocument * doc, const QString & text )
+ : CodeComment (doc, text)
+{
+
+}
+
+XMLCodeComment::~XMLCodeComment ( ) { }
+
+//
+// Methods
+//
+
+
+// Accessor methods
+//
+
+// Other methods
+//
+
+/**
+ * @return QString
+ */
+QString XMLCodeComment::toString ( )
+{
+
+ QString output = "";
+
+ // simple output method
+ if(getWriteOutText())
+ {
+ QString indent = getIndentationString();
+ QString endLine = getNewLineEndingChars();
+ QString body = getText();
+ output.append(indent+"<!-- ");
+ if(!body.isEmpty())
+ output.append(formatMultiLineText (body, indent, endLine));
+ output.append(indent+"-->"+endLine);
+ }
+
+ return output;
+}
+
+
+#include "xmlcodecomment.moc"
diff --git a/umbrello/umbrello/codegenerators/xmlcodecomment.h b/umbrello/umbrello/codegenerators/xmlcodecomment.h
new file mode 100644
index 00000000..a30bcbab
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/xmlcodecomment.h
@@ -0,0 +1,68 @@
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Mon Sep 26 2003
+ */
+
+
+
+#ifndef XMLCODECOMMENT_H
+#define XMLCODECOMMENT_H
+
+#include <qstring.h>
+#include "../codecomment.h"
+
+class CodeDocument;
+
+/**
+ * class XMLCodeDocumentation
+ * A XML (code) comment.
+ */
+
+class XMLCodeComment: virtual public CodeComment
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+
+ /**
+ * Constructors
+ */
+ explicit XMLCodeComment ( CodeDocument * doc, const QString & text = "" );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~XMLCodeComment( );
+
+ // Public attributes
+ //
+
+ // Other
+ //
+
+ /**
+ * @return QString
+ */
+ QString toString ( );
+
+
+protected:
+
+private:
+
+};
+
+#endif // XMLCODECOMMENT_H
diff --git a/umbrello/umbrello/codegenerators/xmlelementcodeblock.cpp b/umbrello/umbrello/codegenerators/xmlelementcodeblock.cpp
new file mode 100644
index 00000000..7e702619
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/xmlelementcodeblock.cpp
@@ -0,0 +1,166 @@
+
+/***************************************************************************
+ * *
+ * 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 : Wed Sep 26 2003
+ */
+
+// own header
+#include "xmlelementcodeblock.h"
+
+// qt/kde includes
+#include <kdebug.h>
+
+// local includes
+#include "xmlcodecomment.h"
+#include "../attribute.h"
+#include "../codedocument.h"
+
+// Constructors/Destructors
+//
+
+XMLElementCodeBlock::XMLElementCodeBlock ( CodeDocument * parentDoc, const QString & nodeName, const QString & comment)
+ : HierarchicalCodeBlock(parentDoc)
+{
+ init(parentDoc, nodeName, comment);
+}
+
+XMLElementCodeBlock::~XMLElementCodeBlock ( ) { }
+
+//
+// Methods
+//
+
+/**
+ * Save the XMI representation of this object
+ */
+void XMLElementCodeBlock::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
+ QDomElement blockElement = doc.createElement( "xmlelementblock" );
+
+ setAttributesOnNode(doc, blockElement);
+
+ root.appendChild( blockElement );
+}
+
+/**
+ * load params from the appropriate XMI element node.
+ */
+void XMLElementCodeBlock::loadFromXMI ( QDomElement & root )
+{
+ setAttributesFromNode(root);
+}
+
+/** set attributes of the node that represents this class
+ * in the XMI document.
+ */
+void XMLElementCodeBlock::setAttributesOnNode ( QDomDocument & doc, QDomElement & docElement)
+{
+
+ // superclass call
+ HierarchicalCodeBlock::setAttributesOnNode(doc,docElement);
+
+ // now set local attributes/fields
+ docElement.setAttribute("nodeName",getNodeName());
+
+}
+
+/** set the class attributes of this object from
+ * the passed element node.
+ */
+void XMLElementCodeBlock::setAttributesFromNode ( QDomElement & root) {
+
+ // superclass call
+ HierarchicalCodeBlock::setAttributesFromNode(root);
+
+ // now set local attributes
+ setNodeName(root.attribute("nodeName","UNKNOWN"));
+
+}
+
+// Accessor methods
+//
+
+void XMLElementCodeBlock::setNodeName (const QString &name) {
+ m_nodeName = name;
+}
+
+QString XMLElementCodeBlock::getNodeName () {
+ return m_nodeName;
+}
+
+void XMLElementCodeBlock::addAttribute (UMLAttribute * at) {
+ m_attList.append(at);
+}
+
+UMLAttributeList * XMLElementCodeBlock::getAttributeList() {
+ return & m_attList;
+}
+
+
+// Other methods
+//
+
+/**
+ * update the start and end text for this ownedhierarchicalcodeblock.
+ */
+void XMLElementCodeBlock::updateContent ( )
+{
+
+ QString endLine = getNewLineEndingChars();
+
+ QString nodeName = getNodeName();
+
+ // Now update START/ENDING Text
+ QString startText = '<' + nodeName;
+ QString endText = "";
+
+ UMLAttributeList * alist = getAttributeList();
+ for (UMLAttribute *at = alist->first(); at; at=alist->next())
+ {
+ if(at->getInitialValue().isEmpty())
+ kWarning()<<" XMLElementCodeBlock : cant print out attribute that lacks an initial value"<<endl;
+ else {
+ startText.append(" " +at->getName()+"=\"");
+ startText.append(at->getInitialValue()+"\"");
+ }
+ }
+
+ // now set close of starting/ending node, the style depending on whether we have child text or not
+ if(getTextBlockList()->count())
+ {
+ startText.append(">");
+ endText = "</" + nodeName + '>';
+ } else {
+ startText.append("/>");
+ endText = "";
+ }
+
+ setStartText(startText);
+ setEndText(endText);
+
+}
+
+void XMLElementCodeBlock::init (CodeDocument *parentDoc, const QString &nodeName, const QString &comment)
+{
+
+ setComment(new XMLCodeComment(parentDoc));
+ getComment()->setText(comment);
+
+ m_nodeName = nodeName;
+
+ updateContent();
+
+}
+
+
+#include "xmlelementcodeblock.moc"
diff --git a/umbrello/umbrello/codegenerators/xmlelementcodeblock.h b/umbrello/umbrello/codegenerators/xmlelementcodeblock.h
new file mode 100644
index 00000000..b0acd277
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/xmlelementcodeblock.h
@@ -0,0 +1,88 @@
+
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Wed Sep 26 2003
+ */
+
+#ifndef XMLELEMENTCODEBLOCK_H
+#define XMLELEMENTCODEBLOCK_H
+
+#include <qstring.h>
+
+#include "../umlattributelist.h"
+#include "../hierarchicalcodeblock.h"
+
+class CodeDocument;
+class UMLAttribute;
+
+class XMLElementCodeBlock : public HierarchicalCodeBlock
+{
+ Q_OBJECT
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ XMLElementCodeBlock ( CodeDocument * parentDoc, const QString & nodeName, const QString & comment = "");
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~XMLElementCodeBlock ( );
+
+ /**
+ * Save the XMI representation of this object
+ */
+ virtual void saveToXMI ( QDomDocument & doc, QDomElement & root );
+
+ /**
+ * load params from the appropriate XMI element node.
+ */
+ virtual void loadFromXMI ( QDomElement & root );
+
+ virtual UMLAttributeList * getAttributeList();
+
+ virtual void setNodeName (const QString &name);
+ virtual QString getNodeName ();
+
+ void addAttribute (UMLAttribute * at);
+
+protected:
+
+ /** set attributes of the node that represents this class
+ * in the XMI document.
+ */
+ virtual void setAttributesOnNode ( QDomDocument & doc, QDomElement & blockElement);
+
+ /** set the class attributes of this object from
+ * the passed element node.
+ */
+ virtual void setAttributesFromNode ( QDomElement & element);
+
+ /**
+ * Update the start/end text of this codeblock.
+ */
+ void updateContent ( );
+
+private:
+
+ UMLAttributeList m_attList;
+ QString m_nodeName;
+ void init (CodeDocument * parent, const QString &nodeName, const QString &comment);
+
+};
+
+#endif // XMLELEMENTCODEBLOCK_H
diff --git a/umbrello/umbrello/codegenerators/xmlschemawriter.cpp b/umbrello/umbrello/codegenerators/xmlschemawriter.cpp
new file mode 100644
index 00000000..303d3230
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/xmlschemawriter.cpp
@@ -0,0 +1,809 @@
+/***************************************************************************
+ copyright : (C) 2003 Brian Thomas brian.thomas@gsfc.nasa.gov
+ (C) 2004-2006 Umbrello UML Modeller Authors <uml-devel@uml.sf.net>
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "xmlschemawriter.h"
+
+#include <kdebug.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#include "../umldoc.h"
+#include "../classifier.h"
+#include "../operation.h"
+#include "../umlnamespace.h"
+
+// Constructor
+XMLSchemaWriter::XMLSchemaWriter()
+{
+
+ packageNamespaceTag = "tns";
+ packageNamespaceURI = "http://foo.example.com/";
+ schemaNamespaceTag = "xs";
+ schemaNamespaceURI = "http://www.w3.org/2001/XMLSchema";
+}
+
+// form of..."the Destructor"!!
+XMLSchemaWriter::~XMLSchemaWriter() {
+}
+
+/**
+ * returns "XMLSchema"
+ */
+Uml::Programming_Language XMLSchemaWriter::getLanguage() {
+ return Uml::pl_XMLSchema;
+}
+
+// main method for invoking..
+void XMLSchemaWriter::writeClass(UMLClassifier *c)
+{
+
+ if (!c) {
+ kDebug()<<"Cannot write class of NULL classifier!\n";
+ return;
+ }
+
+ // find an appropriate name for our file
+ QString fileName = findFileName(c,".xsd");
+
+ if (fileName.isEmpty()) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ // check that we may open that file for writing
+ QFile file;
+ if ( !openFile(file, fileName) ) {
+ emit codeGenerated(c, false);
+ return;
+ }
+
+ QTextStream XMLschema(&file);
+
+ // set package namespace tag appropriately
+ if(!c->getPackage().isEmpty())
+ packageNamespaceTag = c->getPackage();
+
+ // START WRITING
+
+ // 0. FIRST THING: open the xml processing instruction. This MUST be
+ // the first thing in the file
+ XMLschema<<"<?xml version=\"1.0\"?>"<<m_endl;
+
+ // 1. create the header
+ QString headerText = getHeadingFile(".xsd");
+ if(!headerText.isEmpty()) {
+ headerText.replace(QRegExp("%filename%"),fileName);
+ headerText.replace(QRegExp("%filepath%"),file.name());
+ }
+ if(!headerText.isEmpty())
+ XMLschema<<headerText<<m_endl;
+
+ // 2. Open schema element node with appropriate namespace decl
+ XMLschema<<"<"<<makeSchemaTag("schema");
+ // common namespaces we know will be in the file..
+ XMLschema<<" targetNamespace=\""<<packageNamespaceURI+packageNamespaceTag<<"\""<<m_endl;
+ XMLschema<<" xmlns:"<<schemaNamespaceTag<<"=\""<<schemaNamespaceURI<<"\"";
+ XMLschema<<" xmlns:"<<packageNamespaceTag<<"=\""<<packageNamespaceURI+packageNamespaceTag<<"\"";
+
+ XMLschema<<">"<<m_endl; // close opening declaration
+
+ m_indentLevel++;
+
+ // 3? IMPORT statements -- do we need to do anything here? I suppose if
+ // our document has more than one package, which is possible, we are missing
+ // the correct import statements. Leave that for later at this time.
+ /*
+ //only import classes in a different package as this class
+ UMLPackageList imports;
+ findObjectsRelated(c,imports);
+ for(UMLPackage *con = imports.first(); con ; con = imports.next())
+ if(con->getPackage() != c->getPackage())
+ XMLschema<<"import "<<con->getPackage()<<"."<<cleanName(con->getName())<<";"<<m_endl;
+ */
+
+ // 4. BODY of the schema.
+ // start the writing by sending this classifier, the "root" for this particular
+ // schema, to writeClassifier method, which will subsequently call itself on all
+ // related classifiers and thus populate the schema.
+ writeClassifier(c, XMLschema);
+
+ // 5. What remains is to make the root node declaration
+ XMLschema<<m_endl;
+ writeElementDecl(getElementName(c), getElementTypeName(c), XMLschema);
+
+ // 6. Finished: now we may close schema decl
+ m_indentLevel--;
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("schema")<<">"<<m_endl; // finished.. close schema node
+
+ // bookeeping for code generation
+ emit codeGenerated(c, true);
+
+ // tidy up. no dangling open files please..
+ file.close();
+
+ // need to clear HERE, NOT in the destructor because we want each
+ // schema that we write to have all related classes.
+ writtenClassifiers.clear();
+}
+
+void XMLSchemaWriter::writeElementDecl( const QString &elementName, const QString &elementTypeName, QTextStream &XMLschema)
+{
+ if(forceDoc())
+ writeComment(elementName+" is the root element, declared here.", XMLschema);
+
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("element")
+ <<" name=\""<<elementName<<"\""
+ <<" type=\""<<makePackageTag(elementTypeName)<<"\""
+ <<"/>"<<m_endl;
+
+}
+
+void XMLSchemaWriter::writeClassifier (UMLClassifier *c, QTextStream &XMLschema)
+{
+
+ // NO doing this 2 or more times.
+ if(hasBeenWritten(c))
+ return;
+
+ XMLschema<<m_endl;
+
+ // write documentation for class, if any, first
+ if(forceDoc() || !c->getDoc().isEmpty())
+ writeComment(c->getDoc(),XMLschema);
+
+ if(c->getAbstract() || c->isInterface() )
+ writeAbstractClassifier(c,XMLschema); // if its an interface or abstract class
+ else
+ writeConcreteClassifier(c,XMLschema);
+
+}
+
+UMLAttributeList XMLSchemaWriter::findAttributes (UMLClassifier *c)
+{
+ // sort attributes by Scope
+ UMLAttributeList attribs;
+ attribs.setAutoDelete(false);
+
+ if (!c->isInterface()) {
+ UMLAttributeList atl = c->getAttributeList();
+ for(UMLAttribute *at=atl.first(); at ; at=atl.next()) {
+ switch(at->getVisibility())
+ {
+ case Uml::Visibility::Public:
+ case Uml::Visibility::Protected:
+ attribs.append(at);
+ break;
+ case Uml::Visibility::Private:
+ // DO NOTHING! no way to print in the schema
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return attribs;
+}
+
+// We have to do 2 things with abstract classifiers (e.g. abstract classes and interfaces)
+// which is to:
+// 1) declare it as a complexType so it may be inherited (I can see an option here: to NOT write
+// this complexType declaration IF the classifier itself isnt inherited by or is inheriting
+// from anything because no other element will use this complexType).
+// 2) Create a group so that elements, which obey the abstract class /interface may be placed in
+// aggregation with other elements (again, and option here to NOT write the group if no other
+// element use the interface in element aggregation)
+//
+
+void XMLSchemaWriter::writeAbstractClassifier (UMLClassifier *c, QTextStream &XMLschema)
+{
+
+ // preparations
+ UMLClassifierList subclasses = c->findSubClassConcepts(); // list of what inherits from us
+ UMLClassifierList superclasses = c->findSuperClassConcepts(); // list of what we inherit from
+
+ // write the main declaration
+ writeConcreteClassifier (c, XMLschema);
+ writeGroupClassifierDecl (c, subclasses, XMLschema);
+
+ markAsWritten(c);
+
+ // now go back and make sure all sub-classing nodes are declared
+ if(subclasses.count() > 0)
+ {
+
+ QString elementName = getElementName(c);
+ UMLAttributeList attribs = findAttributes(c);
+ QStringList attribGroups = findAttributeGroups(c);
+
+ writeAttributeGroupDecl(elementName, attribs, XMLschema);
+
+ // now write out inheriting classes, as needed
+ for(UMLClassifier * classifier = subclasses.first(); classifier; classifier = subclasses.next())
+ writeClassifier(classifier, XMLschema);
+ }
+
+ // write out any superclasses as needed
+ for(UMLClassifier *classifier = superclasses.first(); classifier; classifier = superclasses.next())
+ writeClassifier(classifier, XMLschema);
+
+}
+
+void XMLSchemaWriter::writeGroupClassifierDecl (UMLClassifier *c,
+ UMLClassifierList subclasses,
+ QTextStream &XMLschema)
+{
+
+ // name of class, subclassing classifiers
+ QString elementTypeName = getElementGroupTypeName(c);
+
+ // start Writing node but only if it has subclasses? Nah..right now put in empty group
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("group")<<" name=\""<<elementTypeName<<"\">"<<m_endl;
+ m_indentLevel++;
+
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("choice")<<">"<<m_endl;
+ m_indentLevel++;
+
+ for(UMLClassifier *classifier = subclasses.first(); classifier; classifier = subclasses.next()) {
+ writeAssociationRoleDecl(classifier, "1", XMLschema);
+ }
+
+ m_indentLevel--;
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("choice")<<">"<<m_endl;
+
+ m_indentLevel--;
+
+ // finish node
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("group")<<">"<<m_endl;
+
+}
+
+void XMLSchemaWriter::writeComplexTypeClassifierDecl (UMLClassifier *c,
+ UMLAssociationList associations,
+ UMLAssociationList aggregations,
+ UMLAssociationList compositions,
+ UMLClassifierList superclasses,
+ QTextStream &XMLschema)
+{
+
+ // Preparations
+ //
+
+ // sort attributes by Scope
+ UMLAttributeList attribs = findAttributes(c);
+ QStringList attribGroups = findAttributeGroups(c);
+
+ // test for relevant associations
+ bool hasAssociations = determineIfHasChildNodes(c);
+ bool hasSuperclass = superclasses.count()> 0;
+ bool hasAttributes = attribs.count() > 0 || attribGroups.count() > 0;
+
+ // START WRITING
+
+ // start body of element
+ QString elementTypeName = getElementTypeName(c);
+
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("complexType")<<" name=\""<<elementTypeName<<"\"";
+
+ if(hasAssociations || hasAttributes || hasSuperclass)
+ {
+
+ XMLschema<<">"<<m_endl;
+
+ m_indentLevel++;
+
+ if(hasSuperclass)
+ {
+ QString superClassName = getElementTypeName(superclasses.first());
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("complexContent")<<">"<<m_endl;
+
+ //PROBLEM: we only treat ONE superclass for inheritence.. bah.
+ m_indentLevel++;
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("extension")<<" base=\""<<makePackageTag(superClassName)
+ <<"\"";
+ if(hasAssociations || hasAttributes )
+ XMLschema<<">"<<m_endl;
+ else
+ XMLschema<<"/>"<<m_endl;
+
+ m_indentLevel++;
+ }
+
+ if(hasAssociations)
+ {
+ // Child Elements (from most associations)
+ //
+ bool didFirstOne = false;
+ didFirstOne = writeAssociationDecls(associations, true, didFirstOne, c->getID(), XMLschema);
+ didFirstOne = writeAssociationDecls(aggregations, false, didFirstOne, c->getID(), XMLschema);
+ didFirstOne = writeAssociationDecls(compositions, false, didFirstOne, c->getID(), XMLschema);
+
+ if (didFirstOne) {
+ m_indentLevel--;
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("sequence")<<">"<<m_endl;
+ }
+ }
+
+ // ATTRIBUTES
+ //
+ if(hasAttributes)
+ {
+ writeAttributeDecls(attribs, XMLschema);
+ for(uint i= 0; i < attribGroups.count(); i++)
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("attributeGroup")<<" ref=\""
+ <<makePackageTag(attribGroups[i])<<"\"/>"<<m_endl;
+ }
+
+ if(hasSuperclass)
+ {
+ m_indentLevel--;
+
+ if(hasAssociations || hasAttributes )
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("extension")<<">"<<m_endl;
+
+ m_indentLevel--;
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("complexContent")<<">"<<m_endl;
+ }
+
+ // close this element decl
+ m_indentLevel--;
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("complexType")<<">"<<m_endl;
+
+ } else
+ XMLschema<<"/>"<<m_endl; // empty node. just close this element decl
+
+}
+
+void XMLSchemaWriter::writeConcreteClassifier (UMLClassifier *c, QTextStream &XMLschema)
+{
+
+ // preparations.. gather information about this classifier
+ //
+ UMLClassifierList superclasses = c->findSuperClassConcepts(); // list of what inherits from us
+ UMLClassifierList subclasses = c->findSubClassConcepts(); // list of what we inherit from
+ UMLAssociationList aggregations = c->getAggregations();
+ UMLAssociationList compositions = c->getCompositions();
+ // BAD! only way to get "general" associations.
+ UMLAssociationList associations = c->getSpecificAssocs(Uml::at_Association);
+
+ // write the main declaration
+ writeComplexTypeClassifierDecl(c, associations, aggregations, compositions, superclasses, XMLschema);
+
+ markAsWritten(c);
+
+ // Now write out any child def's
+ writeChildObjsInAssociation(c, associations, XMLschema);
+ writeChildObjsInAssociation(c, aggregations, XMLschema);
+ writeChildObjsInAssociation(c, compositions, XMLschema);
+
+ // write out any superclasses as needed
+ for(UMLClassifier *classifier = superclasses.first(); classifier; classifier = superclasses.next())
+ writeClassifier(classifier, XMLschema);
+
+ // write out any subclasses as needed
+ for(UMLClassifier *classifier = subclasses.first(); classifier; classifier = subclasses.next())
+ writeClassifier(classifier, XMLschema);
+}
+
+// these exist for abstract classes only (which become xs:group nodes)
+QStringList XMLSchemaWriter::findAttributeGroups (UMLClassifier *c)
+{
+ // we need to look for any class we inherit from. IF these
+ // have attributes, then we need to notice
+ QStringList list;
+ UMLClassifierList superclasses = c->findSuperClassConcepts(); // list of what inherits from us
+ for(UMLClassifier *classifier = superclasses.first(); classifier; classifier = superclasses.next())
+ {
+ if(classifier->getAbstract())
+ {
+ // only classes have attributes..
+ if (!classifier->isInterface()) {
+ UMLAttributeList attribs = c->getAttributeList();
+ if (attribs.count() > 0)
+ list.append(getElementName(classifier)+"AttribGroupType");
+ }
+ }
+ }
+ return list;
+}
+
+bool XMLSchemaWriter::determineIfHasChildNodes( UMLClassifier *c)
+{
+ UMLObjectList aggList = findChildObjsInAssociations (c, c->getAggregations());
+ UMLObjectList compList = findChildObjsInAssociations (c, c->getCompositions());
+ UMLAssociationList associations = c->getSpecificAssocs(Uml::at_Association); // BAD! only way to get "general" associations.
+ UMLObjectList assocList = findChildObjsInAssociations (c, associations);
+ return aggList.count() > 0 || compList.count() > 0 || assocList.count() > 0;
+}
+
+void XMLSchemaWriter::writeChildObjsInAssociation (UMLClassifier *c,
+ UMLAssociationList assoc,
+ QTextStream &XMLschema)
+{
+
+ UMLObjectList list = findChildObjsInAssociations (c, assoc);
+ for(UMLObject * obj = list.first(); obj; obj = list.next())
+ {
+ UMLClassifier * thisClassifier = dynamic_cast<UMLClassifier*>(obj);
+ if(thisClassifier)
+ writeClassifier(thisClassifier, XMLschema);
+ }
+}
+
+bool XMLSchemaWriter::hasBeenWritten(UMLClassifier *c) {
+ if (writtenClassifiers.contains(c))
+ return true;
+ else
+ return false;
+}
+
+void XMLSchemaWriter::markAsWritten(UMLClassifier *c) {
+ writtenClassifiers.append(c);
+}
+
+void XMLSchemaWriter::writeAttributeDecls(UMLAttributeList &attribs, QTextStream &XMLschema )
+{
+
+ UMLAttribute *at;
+ for(at=attribs.first(); at; at=attribs.next())
+ {
+ writeAttributeDecl(at,XMLschema);
+ }
+
+}
+
+void XMLSchemaWriter::writeAttributeDecl(UMLAttribute *attrib, QTextStream &XMLschema )
+{
+
+ QString documentation = attrib->getDoc();
+ QString typeName = fixTypeName(attrib->getTypeName());
+ bool isStatic = attrib->getStatic();
+ QString initialValue = fixInitialStringDeclValue(attrib->getInitialValue(), typeName);
+
+ if(!documentation.isEmpty())
+ writeComment(documentation, XMLschema);
+
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("attribute")
+ <<" name=\""<<cleanName(attrib->getName())<<"\""
+ <<" type=\""<<typeName<<"\"";
+
+ // default value?
+ if(!initialValue.isEmpty())
+ {
+ // IF its static, then we use "fixed", otherwise, we use "default" decl.
+ // For the default decl, we _must_ use "optional" decl
+ if(isStatic)
+ XMLschema<<" use=\"required\" fixed=\""<<initialValue<<"\"";
+ else
+ XMLschema<<" use=\"optional\" default=\""<<initialValue<<"\"";
+ }
+
+ // finish decl
+ XMLschema<<"/>"<<m_endl;
+
+}
+
+void XMLSchemaWriter::writeAttributeGroupDecl (const QString &elementName, UMLAttributeList &attribs, QTextStream &XMLschema )
+{
+
+ if (attribs.count()> 0) {
+
+ // write a little documentation
+ writeComment("attributes for element "+elementName,XMLschema);
+
+ // open attribute group
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("attributeGroup")<<" name=\""<<elementName+"AttribGroupType"<<"\">"<<m_endl;
+
+ m_indentLevel++;
+
+ for( UMLAttribute *at=attribs.first(); at; at=attribs.next())
+ {
+ writeAttributeDecl(at,XMLschema);
+ }
+
+ m_indentLevel--;
+
+ // close attrib group node
+ XMLschema<<getIndent()<<"</"<<makeSchemaTag("attributeGroup")<<">"<<m_endl;
+ }
+}
+
+void XMLSchemaWriter::writeComment( const QString &comment, QTextStream &XMLschema )
+{
+ // in the case we have several line comment..
+ // NOTE: this part of the method has the problem of adopting UNIX newline,
+ // need to resolve for using with MAC/WinDoze eventually I assume
+ QString indent = getIndent();
+ XMLschema<<indent<<"<!-- ";
+ if (comment.contains(QRegExp("\n"))) {
+ XMLschema<<m_endl;
+ QStringList lines = QStringList::split( "\n", comment);
+ for(uint i= 0; i < lines.count(); i++)
+ XMLschema<<indent<<" "<<lines[i]<<m_endl;
+
+ XMLschema<<indent<<"-->"<<m_endl;
+ } else {
+ // this should be more fancy in the future, breaking it up into 80 char
+ // lines so that it doesn't look too bad
+ XMLschema<<comment<<" -->"<<m_endl;
+ }
+}
+
+// all that matters here is roleA, the role served by the children of this class
+// in any composition or aggregation association. In full associations, I have only
+// considered the case of "self" association, so it shouldn't matter if we use role A or
+// B to find the child class as long as we don't use BOTH roles. I bet this will fail
+// badly for someone using a plain association between 2 different classes. THAT should
+// be done, but isnt yet (this is why I have left role b code in for now). -b.t.
+bool XMLSchemaWriter::writeAssociationDecls(UMLAssociationList associations,
+ bool noRoleNameOK, bool didFirstOne, Uml::IDType id, QTextStream &XMLschema)
+{
+
+ if( !associations.isEmpty() )
+ {
+ bool printRoleA = false, printRoleB = false;
+
+ for(UMLAssociation *a = associations.first(); a; a = associations.next())
+ {
+ // it may seem counter intuitive, but you want to insert the role of the
+ // *other* class into *this* class.
+
+ if (a->getObjectId(Uml::A) == id && a->getVisibility(Uml::B) != Uml::Visibility::Private)
+ printRoleB = true;
+
+ if (a->getObjectId(Uml::B) == id && a->getVisibility(Uml::A) != Uml::Visibility::Private)
+ printRoleA = true;
+
+ // First: we insert documentaion for association IF it has either role
+ // AND some documentation (!)
+ if ((printRoleA || printRoleB) && !(a->getDoc().isEmpty()))
+ writeComment(a->getDoc(), XMLschema);
+
+ // opening for sequence
+ if(!didFirstOne && (printRoleA || printRoleB))
+ {
+ didFirstOne = true;
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("sequence")<<">"<<m_endl;
+ m_indentLevel++;
+ }
+
+ // print RoleB decl
+ /*
+ // As mentioned in the header comment for this method: this block of code is
+ // commented out for now as it will only be needed if/when plain associations
+ // between different classes are to be treated
+ if (printRoleB)
+ {
+ UMLClassifier *classifierB = dynamic_cast<UMLClassifier*>(a->getObjectB());
+ if (classifierB) {
+ // ONLY write out IF there is a rolename given
+ // otherwise its not meant to be declared
+ if (!a->getRoleNameB().isEmpty() || noRoleNameOK)
+ writeAssociationRoleDecl(classifierB, a->getMultiB(), XMLschema);
+ }
+ }
+ */
+
+ // print RoleA decl
+ if (printRoleA)
+ {
+ UMLClassifier *classifierA = dynamic_cast<UMLClassifier*>(a->getObject(Uml::A));
+ if (classifierA) {
+ // ONLY write out IF there is a rolename given
+ // otherwise its not meant to be declared
+ if (!a->getRoleName(Uml::A).isEmpty() || noRoleNameOK )
+ writeAssociationRoleDecl(classifierA, a->getMulti(Uml::A), XMLschema);
+ }
+ }
+ }
+
+ }
+
+ return didFirstOne;
+}
+
+UMLObjectList XMLSchemaWriter::findChildObjsInAssociations (UMLClassifier *c, UMLAssociationList associations)
+{
+ Uml::IDType id = c->getID();
+ UMLObjectList list;
+ for(UMLAssociation *a = associations.first(); a; a = associations.next())
+ {
+ if (a->getObjectId(Uml::A) == id
+ && a->getVisibility(Uml::B) != Uml::Visibility::Private
+ && !a->getRoleName(Uml::B).isEmpty()
+ )
+ list.append(a->getObject(Uml::B));
+
+ if (a->getObjectId(Uml::B) == id
+ && a->getVisibility(Uml::A) != Uml::Visibility::Private
+ && !a->getRoleName(Uml::A).isEmpty()
+ )
+ list.append(a->getObject(Uml::A));
+ }
+ return list;
+}
+
+void XMLSchemaWriter::writeAssociationRoleDecl( UMLClassifier *c, const QString &multi, QTextStream &XMLschema)
+{
+
+ bool isAbstract = c->getAbstract();
+ bool isInterface = c->isInterface();
+
+ QString elementName = getElementName(c);
+ QString doc = c->getDoc();
+
+ if (!doc.isEmpty())
+ writeComment(doc, XMLschema);
+
+
+ // Min/Max Occurs is based on whether it is this a single element
+ // or a List (maxoccurs>1). One day this will be done correctly with special
+ // multiplicity object that we don't have to figure out what it means via regex.
+ QString minOccurs = "0";
+ QString maxOccurs = "unbounded";
+ if (multi.isEmpty())
+ {
+ // in this case, association will only specify ONE element can exist
+ // as a child
+ minOccurs = "1";
+ maxOccurs = "1";
+ }
+ else
+ {
+ QStringList values = QStringList::split( QRegExp("[^\\d{1,}|\\*]"), multi);
+
+ // could use some improvement here.. for sequences like "0..1,3..5,10" we
+ // don't capture the whole "richness" of the multi. Instead we translate it
+ // now to minOccurs="0" maxOccurs="10"
+ if (values.count() > 0)
+ {
+ // populate both with the actual value as long as our value isnt an asterix
+ // In that case, use special value (from above)
+ if(values[0].contains(QRegExp("\\d{1,}")))
+ minOccurs = values[0]; // use first number in sequence
+
+ if(values[values.count()-1].contains(QRegExp("\\d{1,}")))
+ maxOccurs = values[values.count()-1]; // use only last number in sequence
+ }
+ }
+
+ // Now declare the class in the association as an element or group.
+ //
+ // In a semi-arbitrary way, we have decided to make abstract classes into
+ // "groups" and concrete classes into "complexTypes".
+ //
+ // This is because about the only thing you can do with an abstract
+ // class (err. node) is inherit from it with a "concrete" element. Therefore,
+ // in this manner, we need a group node for abstract classes to lay out the child
+ // element choices so that the child, concrete class may be plugged into whatever spot
+ // it parent could go. The tradeoff is that "group" nodes may not be extended, so the
+ // choices that you lay out here are it (e.g. no more nodes may inherit" from this group)
+ //
+ // The flipside for concrete classes is that we want to use them as elements in our document.
+ // Unfortunately, about all you can do with complexTypes in terms of inheritance, is to
+ // use these as the basis for a new node type. This is NOT full inheritence because the new
+ // class (err. element node) wont be able to go into the document where it parent went without
+ // you heavily editing the schema.
+ //
+ // Therefore, IF a group is abstract, but has no inheriting sub-classes, there are no choices, and its nigh
+ // on pointless to declare it as a group, in this special case, abstract classes get declared
+ // as complexTypes.
+ //
+ // Of course, in OO methodology, you should be able to inherit from
+ // any class, but schema just don't allow use to have full inheritence using either groups
+ // or complexTypes. Thus we have taken a middle rode. If someone wants to key me into a
+ // better way to represent this, I'd be happy to listen. =b.t.
+ //
+ // UPDATE: partial solution to the above: as of 13-Mar-2003 we now write BOTH a complexType
+ // AND a group declaration for interfaces AND classes which are inherited from.
+ //
+ if ((isAbstract || isInterface ) && c->findSubClassConcepts().count() > 0)
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("group")
+ <<" ref=\""<<makePackageTag(getElementGroupTypeName(c))<<"\"";
+ else
+ XMLschema<<getIndent()<<"<"<<makeSchemaTag("element")
+ <<" name=\""<<getElementName(c)<<"\""
+ <<" type=\""<<makePackageTag(getElementTypeName(c))<<"\"";
+
+ // min/max occurs
+ if (minOccurs != "1")
+ XMLschema<<" minOccurs=\""<<minOccurs<<"\"";
+
+ if (maxOccurs != "1")
+ XMLschema<<" maxOccurs=\""<<maxOccurs<<"\"";
+
+ // tidy up the node
+ XMLschema<<"/>"<<m_endl;
+
+}
+
+// IF the type is "string" we need to declare it as
+// the XMLSchema Object "String" (there is no string primative in XMLSchema).
+// Same thing again for "bool" to "boolean"
+QString XMLSchemaWriter::fixTypeName(const QString& string)
+{
+ // string.replace(QRegExp("^string$"),schemaNamespaceTag+":string");
+ // string.replace(QRegExp("^bool$"),schemaNamespaceTag+":boolean");
+ return schemaNamespaceTag + ':' + string;
+}
+
+QString XMLSchemaWriter::fixInitialStringDeclValue(QString value, const QString &type)
+{
+ // check for strings only
+ if (!value.isEmpty() && type == "xs:string") {
+ if (!value.startsWith("\""))
+ value.remove(0,1);
+ if (!value.endsWith("\""))
+ value.remove(value.length(),1);
+ }
+ return value;
+}
+
+QString XMLSchemaWriter::getElementName(UMLClassifier *c)
+{
+ return cleanName(c->getName());
+}
+
+QString XMLSchemaWriter::getElementTypeName(UMLClassifier *c)
+{
+ QString elementName = getElementName(c);
+ return elementName + "ComplexType";
+}
+
+QString XMLSchemaWriter::getElementGroupTypeName(UMLClassifier *c)
+{
+ QString elementName = getElementName(c);
+ return elementName + "GroupType";
+}
+
+QString XMLSchemaWriter::makePackageTag (QString tagName) {
+ tagName.prepend( packageNamespaceTag + ':');
+ return tagName;
+}
+
+QString XMLSchemaWriter::makeSchemaTag (QString tagName) {
+ tagName.prepend( schemaNamespaceTag + ':');
+ return tagName;
+}
+
+const QStringList XMLSchemaWriter::reservedKeywords() const {
+
+ static QStringList keywords;
+
+ if (keywords.isEmpty()) {
+ keywords << "ATTLIST"
+ << "CDATA"
+ << "DOCTYPE"
+ << "ELEMENT"
+ << "ENTITIES"
+ << "ENTITY"
+ << "ID"
+ << "IDREF"
+ << "IDREFS"
+ << "NMTOKEN"
+ << "NMTOKENS"
+ << "NOTATION"
+ << "PUBLIC"
+ << "SHORTREF"
+ << "SYSTEM"
+ << "USEMAP";
+ }
+
+ return keywords;
+}
+
+#include "xmlschemawriter.moc"
diff --git a/umbrello/umbrello/codegenerators/xmlschemawriter.h b/umbrello/umbrello/codegenerators/xmlschemawriter.h
new file mode 100644
index 00000000..caf9f906
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/xmlschemawriter.h
@@ -0,0 +1,249 @@
+/***************************************************************************
+ * *
+ * 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) 2003 Brian Thomas <brian.thomas@gsfc.nasa.gov> *
+ * copyright (C) 2004-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+#ifndef XMLSCHEMAWRITER_H
+#define XMLSCHEMAWRITER_H
+
+#include "../codegenerator.h"
+#include "../attribute.h"
+#include "../association.h"
+#include "../umlclassifierlist.h"
+#include "../umlattributelist.h"
+#include "../umlobjectlist.h"
+#include "../umlassociationlist.h"
+#include "simplecodegenerator.h"
+
+/**
+ * Class XMLSchemaWriter is a code generator for UMLClassifier objects.
+ * Create an instance of this class, and feed it a UMLClassifier when
+ * calling writeClass and it will generate a XMLschema source file for
+ * that concept
+ *
+ * Our basic approach is to map UMLClassifiers (classes/interfaces) into
+ * XML elements (or nodes). We declare these element in the schema either
+ * as complexType or as groups based on whether they are concrete or abstract
+ * in nature. This is not a perfect decision, but thats life with XML Schema...
+ * you cant fully represent Objects in the XML world ..yet. -b.t.
+ */
+
+class XMLSchemaWriter : public SimpleCodeGenerator
+{
+ Q_OBJECT
+public:
+
+ /**
+ * Constructor, initialises a couple of variables
+ */
+ XMLSchemaWriter();
+
+ /**
+ * Destructor, empty
+ */
+ virtual ~XMLSchemaWriter();
+
+ /**
+ * call this method to generate XMLschema code for a UMLClassifier
+ * @param c the class to generate code for
+ */
+ virtual void writeClass(UMLClassifier *c);
+
+ /**
+ * returns "XMLSchema"
+ */
+ virtual Uml::Programming_Language getLanguage();
+
+ /**
+ * get list of reserved keywords
+ */
+ virtual const QStringList reservedKeywords() const;
+
+private:
+
+ /**
+ * Writes concept's documentation then guts
+ */
+ void writeClassifier(UMLClassifier *c, QTextStream &XMLSchema);
+ void writeAbstractClassifier(UMLClassifier *c, QTextStream &XMLSchema);
+ void writeConcreteClassifier(UMLClassifier *c, QTextStream &XMLSchema);
+
+ /**
+ * write a <complexType> declaration for this classifier
+ */
+ void writeComplexTypeClassifierDecl(UMLClassifier *c,
+ UMLAssociationList associations,
+ UMLAssociationList aggregations,
+ UMLAssociationList compositions,
+ UMLClassifierList superclassifiers,
+ QTextStream &XMLSchema);
+
+ /**
+ * write a <group> declaration for this classifier. Used for interfaces to classes with
+ * inheriting children.
+ */
+ void writeGroupClassifierDecl(UMLClassifier *c,
+ UMLClassifierList superclassifiers,
+ QTextStream &XMLSchema);
+
+ /**
+ * find if the classifier would have any Child elements.
+ */
+ bool determineIfHasChildNodes( UMLClassifier *c);
+
+ /**
+ * write all attributes for a given class
+ * @param c the class for which we are generating code
+ * @param j the stream associated with the output file
+ */
+ void writeAttributes(UMLClassifier *c, QTextStream &j);
+
+ /**
+ * write an element declaration.
+ */
+ void writeElementDecl( const QString &elementName, const QString &elementTypeName, QTextStream &XMLschema);
+
+ /**
+ * writes the Attribute declarations
+ * @param attribs List of attributes
+ * @param XMLschema text stream
+ */
+ void writeAttributeDecls(UMLAttributeList &attribs, QTextStream &XMLschema );
+
+ /**
+ * write an element attribute.
+ */
+ void writeAttributeDecl(UMLAttribute *attrib, QTextStream &XMLschema );
+
+ /**
+ * Find all attributes for this concept.
+ */
+ UMLAttributeList findAttributes (UMLClassifier *c);
+
+ /**
+ * Discover the string name of all the attribute groups (which are child nodes)
+ * of this concept (err.. element)
+ */
+ QStringList findAttributeGroups (UMLClassifier *c);
+
+ /**
+ * Searches a list of associations for appropriate ones to write out as attributes.
+ * This works well for compositions, aggregations and self-associations but will
+ * not work right for plain associations between 2 different classes.
+ */
+ bool writeAssociationDecls(UMLAssociationList associations, bool noRoleOK, bool didOne,
+ Uml::IDType id, QTextStream &XMLschema);
+
+ /**
+ * Find all attributes that belong in group
+ */
+ void writeAttributeGroupDecl(const QString &elementName, UMLAttributeList &attribs, QTextStream &XMLschema );
+
+ /**
+ * Writes out an association as an attribute using Vector
+ */
+ void writeAssociationRoleDecl(UMLClassifier *c, const QString &multi, QTextStream &XMLschema);
+
+ /**
+ * Construct an element tag with the schema namespace
+ */
+ QString makeSchemaTag ( QString tagName );
+
+ /**
+ * Construct an element tag with the package namespace
+ */
+ QString makePackageTag ( QString tagName );
+
+ /**
+ * Writes a comment
+ */
+ void writeComment(const QString &text, QTextStream &XMLschema);
+
+ /**
+ * Find and return a list of child UMLObjects pointed to by the associations
+ * in this UMLClassifier.
+ */
+ UMLObjectList findChildObjsInAssociations (UMLClassifier *c, UMLAssociationList associations);
+
+ /**
+ * Replaces `string' with `String' and `bool' with `boolean'
+ */
+ QString fixTypeName(const QString& string);
+
+ /**
+ * check that initial values of strings DONT have quotes around them
+ * (we get double quoting then!!
+ */
+ QString fixInitialStringDeclValue( QString value, const QString &type);
+
+ /**
+ * Find the element node name for this concept.
+ */
+ QString getElementName(UMLClassifier *c);
+
+ /**
+ * Find the element node "type" name. Used in the "complexType" which
+ * might define that element node.
+ */
+ QString getElementTypeName(UMLClassifier *c);
+
+ /**
+ * Find the group node "type" name. Used for elements which define an interface/are abstract.
+ */
+ QString getElementGroupTypeName(UMLClassifier *c);
+
+ /**
+ * Find all the child objects in this association and make sure they get
+ * written out (if they havent already been)
+ */
+ void writeChildObjsInAssociation (UMLClassifier *c, UMLAssociationList assoc, QTextStream &s);
+
+ /**
+ * Quick check to see if we have written the declaration for this concept yet.
+ */
+ bool hasBeenWritten(UMLClassifier *c);
+
+ /**
+ * mark a concept as written, so it is not repeatedly re-declared in the schema
+ */
+ void markAsWritten(UMLClassifier *c);
+
+ /**
+ * The basic schemaNamespace tag
+ */
+ QString schemaNamespaceTag;
+
+ /**
+ * The basic schemaNamespace tag
+ */
+ QString packageNamespaceTag;
+
+ /*
+ * The basic schemaNamespace URI
+ */
+ QString schemaNamespaceURI;
+
+ /**
+ * The basic schemaNamespace URI
+ */
+ QString packageNamespaceURI;
+
+ /**
+ * A \n, used at the end of each line
+ */
+ QString startline;
+
+ /**
+ * a list of UMLClassifiers we have already written
+ */
+ UMLClassifierList writtenClassifiers;
+};
+
+#endif // XMLSCHEMAWRITER_H