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::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); } } }
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 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 } } }
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; }
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); }
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); }
// 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; }