Source: ./codegenerator.h
|
|
|
|
/***************************************************************************
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. |