/** * Call this method to generate d code for a UMLClassifier. * @param c the class to generate code for */ void DWriter::writeClass(UMLClassifier *c) { if (!c) { uDebug() << "Cannot write class of NULL concept!"; return; } isInterface = c->isInterface(); QString fileName = cleanName(c->name().toLower()); //find an appropriate name for our file fileName = findFileName(c, QLatin1String(".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(QLatin1String(".d")); if (!str.isEmpty()) { str.replace(QRegExp(QLatin1String("%filename%")), fileName); str.replace(QRegExp(QLatin1String("%filepath%")), file.fileName()); 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; if (!isInterface) { UMLAttributeList atl = c->getAttributeList(); foreach (UMLAttribute* at, atl) { switch(at->visibility()) { case Uml::Visibility::Public: if (at->isStatic()) final_atpub.append(at); else atpub.append(at); break; case Uml::Visibility::Protected: if (at->isStatic()) final_atprot.append(at); else atprot.append(at); break; case Uml::Visibility::Private: if (at->isStatic()) 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; } } }
/*=export_func optionSaveFile * * what: saves the option state to a file * * arg: tOptions*, pOpts, program options descriptor * * doc: * * This routine will save the state of option processing to a file. The name * of that file can be specified with the argument to the @code{--save-opts} * option, or by appending the @code{rcfile} attribute to the last * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it * will default to @code{.@i{programname}rc}. If you wish to specify another * file, you should invoke the @code{SET_OPT_SAVE_OPTS( @i{filename} )} macro. * * err: * * If no @code{homerc} file was specified, this routine will silently return * and do nothing. If the output file cannot be created or updated, a message * will be printed to @code{stderr} and the routine will return. =*/ void optionSaveFile( tOptions* pOpts ) { tOptDesc* pOD; int ct; FILE* fp; { int free_name = 0; tCC* pzFName = findFileName( pOpts, &free_name ); if (pzFName == NULL) return; fp = fopen( pzFName, "w" FOPEN_BINARY_FLAG ); if (fp == NULL) { fprintf( stderr, zWarn, pOpts->pzProgName ); fprintf( stderr, zNoCreat, errno, strerror( errno ), pzFName ); if (free_name) AGFREE((void*) pzFName ); return; } if (free_name) AGFREE( (void*)pzFName ); } { char const* pz = pOpts->pzUsageTitle; fputs( "# ", fp ); do { fputc( *pz, fp ); } while (*(pz++) != '\n'); } { time_t timeVal = time( NULL ); char* pzTime = ctime( &timeVal ); fprintf( fp, zPresetFile, pzTime ); #ifdef HAVE_ALLOCATED_CTIME /* * The return values for ctime(), localtime(), and gmtime() * normally point to static data that is overwritten by each call. * The test to detect allocated ctime, so we leak the memory. */ AGFREE( (void*)pzTime ); #endif } /* * FOR each of the defined options, ... */ ct = pOpts->presetOptCt; pOD = pOpts->pOptDesc; do { int arg_state; tOptDesc* p; /* * IF the option has not been defined * OR it does not take an initialization value * OR it is equivalenced to another option * THEN continue (ignore it) */ if (UNUSED_OPT( pOD )) continue; if ((pOD->fOptState & (OPTST_NO_INIT|OPTST_DOCUMENT|OPTST_OMITTED)) != 0) continue; if ( (pOD->optEquivIndex != NO_EQUIVALENT) && (pOD->optEquivIndex != pOD->optIndex)) continue; /* * Set a temporary pointer to the real option description * (i.e. account for equivalencing) */ p = ((pOD->fOptState & OPTST_EQUIVALENCE) != 0) ? (pOpts->pOptDesc + pOD->optActualIndex) : pOD; /* * IF no arguments are allowed * THEN just print the name and continue */ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NONE) { char const * pznm = (DISABLED_OPT( p )) ? p->pz_DisableName : p->pz_Name; /* * If the option was disabled and the disablement name is NULL, * then the disablement was caused by aliasing. * Use the name as the string to emit. */ if (pznm == NULL) pznm = p->pz_Name; fprintf(fp, "%s\n", pznm); continue; } arg_state = OPTST_GET_ARGTYPE(p->fOptState); switch (arg_state) { case 0: case OPARG_TYPE_NUMERIC: printEntry( fp, p, (void*)(p->optArg.argInt)); break; case OPARG_TYPE_STRING: if (p->fOptState & OPTST_STACKED) { tArgList* pAL = (tArgList*)p->optCookie; int uct = pAL->useCt; tCC** ppz = pAL->apzArgs; /* * Disallow multiple copies of disabled options. */ if (uct > 1) p->fOptState &= ~OPTST_DISABLED; while (uct-- > 0) printEntry( fp, p, *(ppz++) ); } else { printEntry( fp, p, p->optArg.argString ); } break; case OPARG_TYPE_ENUMERATION: case OPARG_TYPE_MEMBERSHIP: { uintptr_t val = p->optArg.argEnum; /* * This is a magic incantation that will convert the * bit flag values back into a string suitable for printing. */ (*(p->pOptProc))( (tOptions*)2UL, p ); printEntry( fp, p, (void*)(p->optArg.argString)); if ( (p->optArg.argString != NULL) && (arg_state != OPARG_TYPE_ENUMERATION)) { /* * set membership strings get allocated */ AGFREE( (void*)p->optArg.argString ); p->fOptState &= ~OPTST_ALLOC_ARG; } p->optArg.argEnum = val; break; } case OPARG_TYPE_BOOLEAN: printEntry( fp, p, p->optArg.argBool ? "true" : "false" ); break; default: break; /* cannot handle - skip it */ } } while ( (pOD++), (--ct > 0)); fclose( fp ); }
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); }
/** * Call this method to generate C++ code for a UMLClassifier. * @param c the class you want to generate code for. */ void RubyWriter::writeClass(UMLClassifier *c) { if (!c) { uDebug() << "Cannot write class of NULL concept!"; return; } UMLClassifierList superclasses = c->getSuperClasses(); UMLAssociationList aggregations = c->getAggregations(); UMLAssociationList compositions = c->getCompositions(); //find an appropriate name for our file fileName_ = findFileName(c, QLatin1String(".rb")); if (fileName_.isEmpty()) { emit codeGenerated(c, false); return; } QFile fileh; if (!openFile(fileh, fileName_)) { emit codeGenerated(c, false); return; } QTextStream h(&fileh); className_ = cleanName(c->name()); ////////////////////////////// //Start generating the code!! ///////////////////////////// //try to find a heading file (license, coments, etc) QString str; str = getHeadingFile(QLatin1String(".rb")); if (!str.isEmpty()) { str.replace(QRegExp(QLatin1String("%filename%")), fileName_); str.replace(QRegExp(QLatin1String("%filepath%")), fileh.fileName()); h << str << m_endl; } if (forceDoc() || !c->doc().isEmpty()) { QString docStr = c->doc(); docStr.replace(QRegExp(QLatin1String("\\n")), QLatin1String("\n# ")); docStr.remove(QLatin1String("@ref ")); docStr.replace(QLatin1String("@see"), QLatin1String("_See_")); docStr.replace(QLatin1String("@short"), QLatin1String("_Summary_")); docStr.replace(QLatin1String("@author"), QLatin1String("_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 ? QLatin1String(" < ") : QString()); int i = 0; foreach (concept, superclasses) { if (i == 0) { h << cppToRubyType(concept->name()) << 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->name()) << m_endl; } i++; } h << m_endl; // write comment for sub-section IF needed if (forceDoc() || c->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(c->getAttributeList(Uml::Visibility::Public), Uml::Visibility::Public, h); writeAttributeMethods(c->getAttributeList(Uml::Visibility::Protected), Uml::Visibility::Protected, h); writeAttributeMethods(c->getAttributeList(Uml::Visibility::Private), 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); }
void PythonWriter::writeClass(UMLClassifier *c) { if (!c) { uDebug() << "Cannot write class of NULL concept!"; return; } QString classname = cleanName(c->name()); 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.toUpper(); 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.fileName()); h<<str<<m_endl; } // generate import statement for superclasses and take packages into account str = cleanName(c->name()); QString pkg = cleanName(c->package()); if (!pkg.isEmpty()) str.prepend(pkg + '.'); QStringList includesList = QStringList(str); //save imported classes int i = superclasses.count(); foreach (UMLClassifier *classifier , superclasses ) { str = cleanName(classifier->name()); pkg = cleanName(classifier->package()); if (!pkg.isEmpty()) str.prepend(pkg + '.'); includesList.append(str); h << "from " + str + " import *" << m_endl; i--; }
// 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(); }