[Uml-devel] CVS: kdesdk/umbrello/umbrello/codegenerators pythonwriter.cpp,NONE,1.1 pythonwriter.h,NONE,1.1 factory.cpp,1.3,1.4

kde at office.kde.org kde at office.kde.org
Tue Jan 28 11:00:03 UTC 2003


Update of /home/kde/kdesdk/umbrello/umbrello/codegenerators
In directory office:/tmp/cvs-serv8287/codegenerators

Modified Files:
	factory.cpp 
Added Files:
	pythonwriter.cpp pythonwriter.h 
Log Message:
Added python code generator
from Vincent Decorges vincent.decorges at eivd.ch
modified to work with current code base and included in factory.cpp and codegenerator.cpp


--- NEW FILE: pythonwriter.cpp ---
/***************************************************************************
                          pythonwriter.h  -  description
                             -------------------
    begin                : Sat Dec 21 2002
    author               : Vincent Decorges
    email                : vincent.decorges at eivd.ch
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "../association.h"
#include "../attribute.h"
#include "../concept.h"
#include "../operation.h"
#include "../umlnamespace.h"

PythonWriter::PythonWriter( QObject *parent, const char *name ) :
  CodeGenerator( parent, name) {}

PythonWriter::~PythonWriter() {}

void PythonWriter::setSpaceIndent(int number) {
	spaceIndent = "";
	for (int i = 0; i < number; i++) {
		spaceIndent.append(' ');
	}
}

int PythonWriter::getSpaceIndent(void) {
	return spaceIndent.length();
}

void PythonWriter::writeClass(UMLConcept *c) {
	if(!c) {
		kdDebug()<<"Cannot write class of NULL concept!\n";
		return;
	}

	spaceIndent = "    ";

	QString classname = cleanName(c->getName());
	QString fileName = c->getName();

	QPtrList<UMLAssociation> generalizations = c->getGeneralizations();
	QPtrList<UMLAssociation> aggregations = c->getAggregations();
	QPtrList<UMLAssociation> compositions = c->getCompositions();
	UMLAssociation *a;

	//find an appropriate name for our file
	fileName = findFileName(c,".py");
	if (!fileName) {
		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+".py") ) {
		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+".py");
		str.replace(QRegExp("%filepath%"), fileh.name());
		h<<str<<endl;
	}


	//write includes and take namespaces into account
	QList<UMLConcept> includes;
	findObjectsRelated(c,includes);
	UMLConcept* conc;
	for(conc = includes.first(); conc ;conc = includes.next()) {
		QString headerName = findFileName(conc, ".py");
		if ( !headerName.isEmpty() ) {
			first = headerName.at(0);
			first = first.upper();
			headerName = headerName.replace(0, 1, first);
			h<<"from "<<headerName<<" import *"<<endl;
		}
	}
	h<<endl;

	h<<"class "<<classname<<(generalizations.count() > 0 ? " (":"");
	int i;

	for (a = generalizations.first(), i = generalizations.count();
	     a && i; a = generalizations.next(), i--) {

		UMLObject* obj = m_doc->findUMLObject(a->getRoleB());
		h<<cleanName(obj->getName())<<(i>1?", ":"");
	}


	h<<(generalizations.count() > 0 ? ")":"")<<":"<<endl<<endl;

	if(forceDoc() || !c->getDoc().isEmpty()) {
		h<<spaceIndent<<"\"\"\""<<endl;
		h<<spaceIndent<<c->getDoc()<<endl;
		h<<spaceIndent<<":version:"<<endl;
		h<<spaceIndent<<":author:"<<endl;
		h<<spaceIndent<<"\"\"\""<<endl<<endl;
	}

	//operations
	writeOperations(c,h);

	//finish files
	h<<endl<<endl;

	//close files and notfiy we are done
	fileh.close();
	emit codeGenerated(c, true);
}


////////////////////////////////////////////////////////////////////////////////////
//  Helper Methods

void PythonWriter::writeOperations(UMLConcept *c,QTextStream &h) {

	//Lists to store operations  sorted by scope
	QList<UMLOperation> *opl;
	QList<UMLOperation> 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();
	for(UMLOperation *op = opl->first(); op ; op = opl->next()) {
		switch(op->getScope()) {
			case Uml::Public:
				oppub.append(op);
				break;
			case Uml::Protected:
				opprot.append(op);
				break;
			case Uml::Private:
				oppriv.append(op);
				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(QString /*classname*/, QList<UMLOperation> &opList,
				   QTextStream &h, Access access) {
	UMLOperation *op;
	QList<UMLAttribute> *atl;
	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()) {
		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<< spaceIndent << "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<<"):"<<endl;

		if( writeDoc )  //write method documentation
		{
			h<<spaceIndent<<spaceIndent<<"\"\"\""<<endl;
			h<<spaceIndent<<spaceIndent<<op->getDoc()<<endl<<endl;

			for(at = atl->first(); at ; at = atl -> next())  //write parameter documentation
			{
				if(forceDoc() || !at->getDoc().isEmpty()) {
					h<<spaceIndent<<spaceIndent<<"@param "<<at->getTypeName()<<
						" " << cleanName(at->getName());
					h<<" : "<<at->getDoc()<<endl;
				}
			}//end for : write parameter documentation
			h<<spaceIndent<<spaceIndent<<"@return " + op->getReturnType()<<" :"<<endl;
			h<<spaceIndent<<spaceIndent<<"@since"<<endl;
			h<<spaceIndent<<spaceIndent<<"@author"<<endl;
			h<<spaceIndent<<spaceIndent<<"\"\"\""<<endl;
		}
		h<<spaceIndent<<spaceIndent<<"pass"<<endl<<endl;

	}//end for
}





--- NEW FILE: pythonwriter.h ---
/***************************************************************************
                          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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef PYTHONWRITER_H
#define PYTHONWRITER_H

#include "../codegenerator.h"

#include <qlist.h>
#include <qstringlist.h>
class UMLOperation;
class UMLAttribute;

enum Access {PRIVATE, PUBLIC, PROTECTED};

/**
  * class PythonWriter is a python code generator for UMLConcept objects
  * Just call writeClass and feed it a UMLConcept;
  */
class PythonWriter : public CodeGenerator {
public:

	PythonWriter( QObject* parent = 0, const char* name = 0 );
	virtual ~PythonWriter();

	/**
	  * call this method to generate C++ code for a UMLConcept
	  * @param c the class you want to generate code for.
	  */
	virtual void writeClass(UMLConcept *c);

  void setSpaceIndent(int number);
  int getSpaceIndent(void);

private:

  QString spaceIndent;

	/**
	  * 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(UMLConcept *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(QString classname, QList<UMLOperation> &opList,
	                     QTextStream &h, Access access);


};


#endif //PYTHONWRITER

Index: factory.cpp
===================================================================
RCS file: /home/kde/kdesdk/umbrello/umbrello/codegenerators/factory.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- factory.cpp	28 Jan 2003 17:25:14 -0000	1.3
+++ factory.cpp	28 Jan 2003 18:59:06 -0000	1.4
@@ -21,6 +21,7 @@
 #include "javawriter.h"
 #include "phpwriter.h"
 #include "perlwriter.h"
+#include "pythonwriter.h"
 #include "adawriter.h"
 #include "qstringlist.h"
 
@@ -45,6 +46,7 @@
 	l.append("Java");
  	l.append("Perl");
 	l.append("PHP");
+	l.append("Python");
 	return l;
 }
 
@@ -60,6 +62,8 @@
 		return "AdaWriter";
  	if (l == "Perl")
  		return "PerlWriter";
+ 	if (l == "Python")
+ 		return "PythonWriter";
 	//else...
 	kdDebug()<<"WriterFactory::Error: no generator for language "<<l<<endl;
 	return "";
@@ -72,24 +76,21 @@
 	kdDebug()<<"Trying to create object of type "<<n<<endl;
 
 	QObject *obj = 0;
-	if(n == "CppWriter")
+	if(n == "CppWriter") {
 		obj = new CppWriter( parent, name );
-
-	else if(n =="JavaWriter")
+	} else if(n =="JavaWriter") {
 		obj = new JavaWriter(parent, name);
-
-	else if (n == "PHPWriter")
+	} else if (n == "PHPWriter") {
 		obj = new PhpWriter(parent, name);
-
-	else if (n == "AdaWriter")
+	} else if (n == "AdaWriter") {
 		obj = new AdaWriter(parent, name);
-
- 	else if (n == "PerlWriter")
- 		obj = new PerlWriter(parent, name);
-	// add other languages provides by this lib
-
-	else
+ 	} else if (n == "PerlWriter") {
+		obj = new PerlWriter(parent, name);
+ 	} else if (n == "PythonWriter") {
+		obj = new PythonWriter(parent, name);
+	} else {
 		kdDebug()<<"WriterFactory:: cannot create object of type "<<n<<". Type unknown"<<endl;
+	}
 
 	return obj;
 }





More information about the umbrello-devel mailing list