Source: ./codegenerator.h


Annotated List
Files
Globals
Hierarchy
Index
/***************************************************************************
                          codegenerator.h  -  description
                             -------------------
    begin                : Mon Jun 17 2002
    copyright            : (C) 2002 by Luis De la Parra Blum
    email                : luis@delaparra.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 CODEGENERATOR_H
#define CODEGENERATOR_H

#include 
#include 
#include 

class UMLDoc;
class UMLConcept;


/**
 * CodeGenerator is the basis class for all CodeGenerators. It
 * provides the Interface trough wich all Generators are invoked and
 * the all the basicfunctionality. The only thing it doesnt do is to
 * generate code =)
 *
 * If you want to implement a CodeGenerator for some language follow
 * these steps:
 *
 * Create a class which inherits CodeGenerator. This class can have
 * any name, I use names like CppWriter for the Cpp Generator,
 * JavaWriter for the Java Generator and so on, but you can use what
 * you want.
 *
 * The only method which you should implement in your class is:
 *
 *    void writeClass(UMLConcept *)
 *
 * in which you get a pointer to the UMLConcept (class) for which you
 * have to write the code, and you write a file with the code.
 *
 * The code you generate should be output to "outputDirectory" and you
 * should respect the OverwritePolicy specified. You should call
 * findFileName(..) to get an appropiate file name, and then you can
 * call openFile if you want, but if you want to do it yourself you
 * must check the overwrite policy :
 *
 * OverwritePolicy  can have the following values
 *  - Ok: if there is a file named the same as what you want to name your output file,
 *        you can overwrite the old file.
 *  - Ask:if there is a file named the same as what you want to name your output file,
 *        you should ask the User what to do, and give him the option to overwrite the file
 *        write the code to a different file, or to abort the generation of this class.
 *  - Never: you cannot overwrite any files. If there is a file already named the same
 *        as what you want to name your output file, you have to choose another name which
 *        doesnt exist. I suggest you add some suffix, like "fileName1.h", "fileName2.h"
 *        until you find an appropiate name.
 *
 * Finally put your generator in a library which can be dlopened
 * together with a factory class (see below) and you are ready to go.
 */
class CodeGenerator : public QObject {
	Q_OBJECT

public:
	enum OverwritePolicy {Ok=0, Ask, Never};
	enum ModifyNamePolicy {No=0 ,Underscore, Capitalise};

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

	void generateAllClasses();

	/**
	 *   Generate code for the list of classes given.
	 */
	void generateCode( QPtrList &list );

	/**
	 *   Generate code for class c
	 */
	void generateCode( UMLConcept *c);

	inline void setDocument(UMLDoc *d);

	inline void setOutputDirectory(QString d);
	inline QString outputDirectory() const;

	inline void setOverwritePolicy(OverwritePolicy p);
	inline OverwritePolicy overwritePolicy() const;

	inline void setModifyNamePolicy(ModifyNamePolicy p);
	inline ModifyNamePolicy modifyNamePolicy()const;

	inline void setIncludeHeadings(bool i);
	inline bool includeHeadings() const;

	inline void setHeadingFileDir(const QString &);
	inline QString headingFileDir() const;

	inline void setForceDoc(bool f);
	inline bool forceDoc() const;

	inline void setForceSections(bool f);
	inline bool forceSections() const;

//FIXME public or private or should it be friendly?
signals:
	/**
	 * This signal is emited when code for UMLConcept c has been successfuly generated
	 */
	void codeGenerated(UMLConcept *c);

protected:

	/**
	 * To be implemented by the Language Writers
	 */
	virtual void writeClass(UMLConcept *) {};

	/**
	 * Finds an appropiate file name for class c, taking into account the Overwrite
	 * Policy and asking the user what to do if need be. (if policy == Ask)
	 *
	 * @param c the class for which an output file name is desired.
	 * @param ext the extension (or suffix) used for output files
	 * @return the file name that should be used. (without extension)
	 */
	QString findFileName(UMLConcept *c,QString ext);

	/** Opens a file named "name" for writing in the outputDirectory.
	 * If something goes wrong, it infroms the user and sets the file to point to stderr
	 * if this function returns true, you know you can write to the file
	 */
	bool openFile(QFile &file, QString name);

	/**
	 *  Gets the heading file (as a string) to be inserted at the
	 *  begining of the generated file. you give the file type as
	 *  parameter and get the string. if fileName starts with a
	 *  period (.) then fileName is the extension (.cpp, .h,
	 *  .java) if fileName starts with another character you are
	 *  requesting a specific file (mylicensefile.txt).  The files
	 *  can have parameters which are denoted by %parameter%.
	 *
	 *  current parameters are
	 *  %author%
	 *  %date%
	 *  %time%
	 *  %filepath%
	 */
	QString getHeadingFile(QString file);

	QString cleanName(QString);

	/** Format documentation for output in source files
	 *
	 * @param text the documentation which has to be formatted
	 * @param linePrefix the prefix which has to be added in the beginnig of each line
	 * @param lineWidth the line width used for word-wrapping the documentation
	 *
	 * @return the formatted documentation text
	 */
	QString formatDoc(const QString &text, const QString &linePrefix="* ", int lineWidth=80);

	/**
	 * Finds all classes in the current document to which objects of class c
	 * are in some way related. Posible relations are Associations (gneratlization,
	 * composition, etc) as well as parameters to methos and return values
	 * this is useful in deciding which classes/files to import/include in code generation
	 * @c the class for which relations are to be found
	 * @cList a reference to the list into which return the result
	 */
	void findObjectsRelated(UMLConcept *c, QList &cList);

	bool hasDefaultValueAttr(UMLConcept *c);

	bool hasAbstractOps(UMLConcept *c);

	/* Attributes*/
	QDir m_outputDirectory;
	OverwritePolicy m_overwrite;
	ModifyNamePolicy m_modname;
	QDir m_headingFiles;

	UMLDoc *m_doc;
	bool m_forceDoc;
	bool m_forceSections;
	bool m_includeHeadings;

	/**
	 * Maps UMLObjects to filenames. Used to know to which file
	 * each class was written to.  this is useful in varios places
	 */
	QMap *m_fileMap;

};


/**
 * WriterFactory is the Factory class for the library.
 * see the documentation of KLibFactory.
 * see the example implementation in "factory.cpp" by Luis De la Parra
 *
 * This class creates Objects and returns them to be used by the application.
 *
 * If you want to write a library containing Code Generators, you have
 * to implement the generators you want by subclassing CodeGenerator
 * (see the doc for CodeGenerator) and implement WriterFactory. Then
 * build the library as "shared library" with the option "module" so
 * that it can be dlopened, and distribute it.
 *
 * Your implementation of WriterFactory should behave like this:
 *
 * languagesAvailable() must return a QStringList of all the languages
 * offered by this library. For example, if in your library you
 * implement generators for C++, Python, and "PseudoCode", then you
 * should return a list containing this names.
 *
 * generatorName(const QString &l) must return the Class name of the
 * object implementing the language "l". Remember that you can name
 * your generators what you want, so if you subclased CodeGenerator
 * and created a class named "MyFirstCodeGenerator", which outputs
 * Java code, then you should return a QString "MyFirstCodeGenerator"
 * when l = "Java" If your library doesnt recognize /does not
 * implement the language "l", then return an empty string.
 *
 * createObject(...) receives a object name in "name". you should
 * check what this is and then return a object of that type. For
 * example, if name = "MyFirstCodeGenerator", then you should create
 * an object of that type and return a pointer to it. If you did not
 * write any class named "name" in your library, return NULL
 */
class WriterFactory : public KLibFactory {
	Q_OBJECT
public:

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

	/**
	 * Returns a QStringList containing the languages offered by this library
	 */
	QStringList languagesAvailable();

	/**
	 * Returns the name of the generator which implements language l
	 */
	QString generatorName(const QString &l);

	virtual QObject* createObject( QObject* parent = 0, const char* pname = 0,
	                               const char* name = "QObject",
	                               const QStringList &args = QStringList() );

private:
	static KInstance* s_instance;
};


class GeneratorInfo {
public:
	QString language;
	QString library;
	QString object;

};

///////////////////////////////////////////////////////////////////////////////
// inline methods
void CodeGenerator::setDocument(UMLDoc *d) {
	m_doc = d;
}

void CodeGenerator::setOutputDirectory(QString d) {
	if(!d.isEmpty())
		m_outputDirectory.setPath(d);
}

QString CodeGenerator::outputDirectory() const {
	return m_outputDirectory.absPath();
}

void CodeGenerator::setOverwritePolicy(OverwritePolicy p) {
	m_overwrite = p;
}

CodeGenerator::OverwritePolicy CodeGenerator::overwritePolicy() const {
	return m_overwrite;
}

void CodeGenerator::setModifyNamePolicy(ModifyNamePolicy p) {
	m_modname = p;
}

CodeGenerator::ModifyNamePolicy CodeGenerator::modifyNamePolicy()const {
	return m_modname;
}

void CodeGenerator::setHeadingFileDir(const QString &path) {
	m_headingFiles.setPath(path);
}

QString CodeGenerator::headingFileDir() const {
	return m_headingFiles.absPath();
}

void CodeGenerator::setForceDoc(bool f) {
	m_forceDoc = f;
}

bool CodeGenerator::forceDoc() const {
	return m_forceDoc;
}

void CodeGenerator::setForceSections(bool f) {
	m_forceSections = f;
}

bool CodeGenerator::forceSections() const {
	return m_forceSections;
}

void CodeGenerator::setIncludeHeadings(bool i) {
	m_includeHeadings = i;
}

bool CodeGenerator::includeHeadings() const {
	return m_includeHeadings;
}

#endif


Generated by: jr on radge on Wed Sep 25 00:11:47 2002, using kdoc 2.0a54.