예제 #1
0
/**
 * Call this method to generate C++ code for a UMLClassifier.
 * @param c   the class you want to generate code for
 */
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, QLatin1String(".py"));
    if (fileName.isEmpty()) {
        emit codeGenerated(c, false);
        return;
    }

    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(QLatin1String(".py"));
    if (!str.isEmpty()) {
        str.replace(QRegExp(QLatin1String("%filename%")), fileName);
        str.replace(QRegExp(QLatin1String("%filepath%")), fileh.fileName());
        h<<str<<m_endl;
    }

    h << "# coding=" << h.codec()->name() << 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 + QLatin1Char('.'));
    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 + QLatin1Char('.'));
        includesList.append(str);
        h << "from " << str << " import *" << m_endl;
        i--;
    }
예제 #2
0
void TclWriter::writeHeaderFile(UMLClassifier * c, QFile & fileh)
{
    // open stream for writing
    QTextStream stream(&fileh);
    mStream = &stream;

    // reset the indent level
    m_indentLevel = 0;

    // write header blurb
    QString str = getHeadingFile(".tcl");
    if (!str.isEmpty()) {
        str.replace(QRegExp("%filename%"), fileName_);
        str.replace(QRegExp("%filepath%"), fileh.fileName());
        writeCode(str);
    }
    // set current namespace
    writeCode("namespace eval " + mNamespace + " {");
    m_indentLevel++;

    // check on already existing
    writeComm("Do not load twice");
    writeCode("if {[namespace exist " + className_ + "]} return");

    // source used superclass files
    UMLClassifierList superclasses = c->getSuperClasses();
    if (superclasses.count() > 0) {
        writeComm
        ("Source found and used class files and import class command if necessary");

        foreach (UMLClassifier * classifier , superclasses ) {
            writeUse(classifier);
        }
예제 #3
0
void CSharpWriter::writeOverridesRecursive(UMLClassifierList *superclasses, QTextStream &cs) {
    // oplist for implemented abstract operations
    UMLOperationList opabstract;
    opabstract.setAutoDelete(false);
    UMLClassifier *obj;

    for (obj = superclasses->first(); obj; obj = superclasses->next()) {
        if (!obj->isInterface() && obj->hasAbstractOps()) {
            // collect abstract ops
            UMLOperationList opl(obj->getOpList());
            for (UMLOperation *op = opl.first(); op ; op = opl.next()) {
                if (op->getAbstract()) {
                    opabstract.append(op);
                }
            }

            // write abstract implementations
            cs << m_endl << m_container_indent << m_indentation << "#region " << obj->getName() << " members" << m_endl << m_endl;
            writeOperations(opabstract,cs,false,true,true);
            cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;

            opabstract.clear();
        }
        // Recurse to parent superclasses
        UMLClassifierList superRecursive = obj->getSuperClasses();
        UMLClassifierList *superRecursivePtr =& superRecursive;
        if (superRecursivePtr->count() > 0) {
            writeOverridesRecursive(superRecursivePtr, cs);
        }
    }
}
예제 #4
0
void XMLSchemaWriter::writeAbstractClassifier (UMLClassifier *c, QTextStream &XMLschema)
{

    // preparations
    UMLClassifierList subclasses = c->findSubClassConcepts(); // list of what inherits from us
    UMLClassifierList superclasses = c->findSuperClassConcepts(); // list of what we inherit from

    // write the main declaration
    writeConcreteClassifier (c, XMLschema);
    writeGroupClassifierDecl (c, subclasses, XMLschema);

    markAsWritten(c);

    // now go back and make sure all sub-classing nodes are declared
    if(subclasses.count() > 0)
    {

        QString elementName = getElementName(c);
        UMLAttributeList attribs = findAttributes(c);
        QStringList attribGroups = findAttributeGroups(c);

        writeAttributeGroupDecl(elementName, attribs, XMLschema);

        // now write out inheriting classes, as needed
        for(UMLClassifier * classifier = subclasses.first(); classifier; classifier = subclasses.next())
            writeClassifier(classifier, XMLschema);
    }

    // write out any superclasses as needed
    for(UMLClassifier *classifier = superclasses.first(); classifier; classifier = superclasses.next())
        writeClassifier(classifier, XMLschema);

}
예제 #5
0
/**
 * Inserts @p type into the type-combobox as well as its completion object.
 */
void UMLEntityAttributeDialog::insertTypesSorted(const QString& type)
{
    QStringList types;
    // add the data types
    UMLDoc * pDoc = UMLApp::app()->document();
    UMLClassifierList dataTypes = pDoc->datatypes();
    if (dataTypes.count() == 0) {
        // Switch to SQL as the active language if no datatypes are set.
        UMLApp::app()->setActiveLanguage(Uml::ProgrammingLanguage::SQL);
        pDoc->addDefaultDatatypes();
        qApp->processEvents();
        dataTypes = pDoc->datatypes();
    }
    foreach (UMLClassifier* dat, dataTypes) {
        types << dat->name();
    }
    // add the given parameter
    if (!types.contains(type)) {
        types << type;
    }
    types.sort();

    m_pTypeCB->clear();
    m_pTypeCB->insertItems(-1, types);

    // select the given parameter
    int currentIndex = m_pTypeCB->findText(type);
    if (currentIndex > -1) {
        m_pTypeCB->setCurrentIndex(currentIndex);
    }
    m_pTypeCB->completionObject()->addItem(type);
}
예제 #6
0
bool PerlWriter::GetUseStatements(UMLClassifier *c, QString &Ret,
                                  QString &ThisPkgName)
{
  if (!c){
    return(false);
  }

  UMLPackageList includes;
  findObjectsRelated(c,includes);

  QString AV = QChar('@');
  QString SV = QChar('$');
  QString HV = QChar('%');
  foreach (UMLPackage* conc, includes ) {
    if (conc->baseType() == Uml::ot_Datatype)
        continue;
    QString neatName = cleanName(conc->name());
    if (neatName != AV && neatName != SV && neatName != HV) {
      QString OtherPkgName =  conc->package(".");
      OtherPkgName.replace(QRegExp("\\."),"::");
      QString OtherName = OtherPkgName + "::" + cleanName(conc->name());

      // Only print out the use statement if the other package isn't the
      // same as the one we are working on. (This happens for the
      // "Singleton" design pattern.)
      if (OtherName != ThisPkgName){
        Ret += "use ";
        Ret += OtherName;
        Ret +=  ';';
        Ret += m_endl;
      }
    }
  }
  UMLClassifierList  superclasses = c->getSuperClasses();
  if (superclasses.count()) {
    Ret += m_endl;
    Ret += "use base qw( ";
    foreach (UMLClassifier *obj , superclasses ) {
      QString packageName =  obj->package(".");
      packageName.replace(QRegExp("\\."),"::");

      Ret += packageName + "::" + cleanName(obj->name()) + ' ';
    }
예제 #7
0
void CSharpWriter::writeOperations(UMLClassifier *c, QTextStream &cs) {

    //Lists to store operations  sorted by scope
    UMLOperationList oppub,opprot,oppriv;

    bool isInterface = c->isInterface();
    bool generateErrorStub = true;

    oppub.setAutoDelete(false);
    opprot.setAutoDelete(false);
    oppriv.setAutoDelete(false);

    //sort operations by scope first and see if there are abstract methods
    UMLOperationList opl(c->getOpList());
    for (UMLOperation *op = opl.first(); op ; op = opl.next()) {
        switch (op->getVisibility()) {
          case Uml::Visibility::Public:
            oppub.append(op);
            break;
          case Uml::Visibility::Protected:
            opprot.append(op);
            break;
          case Uml::Visibility::Private:
            oppriv.append(op);
            break;
          default:
            break;
        }
    }

    // write realizations (recursive)
    UMLAssociationList realizations = c->getRealizations();

    if (!isInterface && !realizations.isEmpty()) {
        writeRealizationsRecursive(c, &realizations, cs);
    }

    // write public operations
    if (forceSections() || !oppub.isEmpty()) {
        cs << m_endl << m_container_indent << m_indentation << "#region Public methods" << m_endl << m_endl;
        writeOperations(oppub,cs,isInterface,false,generateErrorStub);
        cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
    }

    // write protected operations
    if (forceSections() || !opprot.isEmpty()) {
        cs << m_endl << m_container_indent << m_indentation << "#region Protected methods" << m_endl << m_endl;
        writeOperations(opprot,cs,isInterface,false,generateErrorStub);
        cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
    }

    // write private operations
    if (forceSections() || !oppriv.isEmpty()) {
        cs << m_endl << m_container_indent << m_indentation << "#region Private methods" << m_endl << m_endl;
        writeOperations(oppriv,cs,isInterface,false,generateErrorStub);
        cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
    }

    // write superclasses abstract methods
    UMLClassifierList superclasses = c->getSuperClasses();

    if (!isInterface && !c->getAbstract() && !c->hasAbstractOps()
            && superclasses.count() > 0) {
        writeOverridesRecursive(&superclasses, cs);
    }

}
예제 #8
0
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);
}
/**
 * update the start and end text for this hierarchicalcodeblock.
 */
void CPPHeaderClassDeclarationBlock::updateContent ()
{
    CPPHeaderCodeDocument *parentDoc = dynamic_cast<CPPHeaderCodeDocument*>(getParentDocument());
    UMLClassifier *c = parentDoc->getParentClassifier();
    QString endLine = UMLApp::app()->commonPolicy()->getNewLineEndingChars();
    bool isInterface = parentDoc->parentIsInterface(); // a little shortcut
    QString CPPHeaderClassName = CodeGenerator::cleanName(c->name());
    bool forceDoc = UMLApp::app()->commonPolicy()->getCodeVerboseDocumentComments();

    // COMMENT

    //check if class is abstract.. it should have abstract methods
    if(!isInterface && c->isAbstract() && !c->hasAbstractOps())
    {
        getComment()->setText(QLatin1String("******************************* Abstract Class ****************************") + endLine
                              + CPPHeaderClassName + QLatin1String(" does not have any pure virtual methods, but its author") + endLine
                              + QLatin1String("  defined it as an abstract class, so you should not use it directly.") + endLine
                              + QLatin1String("  Inherit from it instead and create only objects from the derived classes") + endLine
                              + QLatin1String("*****************************************************************************"));
    } else {
        if(isInterface)
            getComment()->setText(QLatin1String("Interface ") + CPPHeaderClassName + endLine + c->doc());
        else
            getComment()->setText(QLatin1String("Class ") + CPPHeaderClassName + endLine + c->doc());
    }

    if(forceDoc || !c->doc().isEmpty())
        getComment()->setWriteOutText(true);
    else
        getComment()->setWriteOutText(false);


    // Now set START/ENDING Text
    QString startText;

    /*
    */

    /*
        if(parentDoc->parentIsInterface())
                startText.append(QLatin1String("interface "));
        else
    */
    startText.append(QLatin1String("class "));

    startText.append(CPPHeaderClassName);

    // write inheritances out
    UMLClassifierList superclasses = c->findSuperClassConcepts();
    int nrof_superclasses = superclasses.count();

    // write out inheritance
    int i = 0;
    if(nrof_superclasses >0)
        startText.append(QLatin1String(" : "));
    foreach (UMLClassifier* concept, superclasses) {
        startText.append(Uml::Visibility::toString(concept->visibility()) + QLatin1Char(' ') +
            CodeGenerator::cleanName(concept->name()));
        if(i != (nrof_superclasses-1))
            startText.append(QLatin1String(", "));
        i++;
    }
예제 #10
0
/**
 * 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);
}
/**
 * update the start and end text for this ownedhierarchicalcodeblock.
 */
void JavaClassDeclarationBlock::updateContent ( )
{

    JavaClassifierCodeDocument *parentDoc = dynamic_cast<JavaClassifierCodeDocument*>(getParentDocument());
    UMLClassifier *c = parentDoc->getParentClassifier();
    CodeGenerationPolicy *commonPolicy = UMLApp::app()->getCommonPolicy();
    QString endLine = commonPolicy->getNewLineEndingChars();
    bool isInterface = parentDoc->parentIsInterface(); // a little shortcut
    QString JavaClassName = parentDoc->getJavaClassName(c->getName());

    // COMMENT
    if(isInterface)
        getComment()->setText("Interface "+JavaClassName+endLine+c->getDoc());
    else
        getComment()->setText("Class "+JavaClassName+endLine+c->getDoc());

    bool forceDoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
    if(forceDoc || !c->getDoc().isEmpty())
        getComment()->setWriteOutText(true);
    else
        getComment()->setWriteOutText(false);


    // Now set START/ENDING Text
    QString startText = "";
    // In Java, we need declare abstract only on classes
    if (c->getAbstract() && !isInterface)
        startText.append("abstract ");

    if (c->getVisibility() != Uml::Visibility::Public) {
        // We should probably emit a warning in here .. java doesn't like to allow
        // private/protected classes. The best we can do (I believe)
        // is to let these declarations default to "package visibility"
        // which is a level between traditional "private" and "protected"
        // scopes. To get this visibility level we just print nothing..
    } else
        startText.append("public ");

    if(parentDoc->parentIsInterface())
        startText.append("interface ");
    else
        startText.append("class ");

    startText.append(JavaClassName);

    // write inheritances out
    UMLClassifierList superclasses =
        c->findSuperClassConcepts(UMLClassifier::CLASS);
    UMLClassifierList superinterfaces =
        c->findSuperClassConcepts(UMLClassifier::INTERFACE);
    int nrof_superclasses = superclasses.count();
    int nrof_superinterfaces = superinterfaces.count();

    // write out inheritance
    int i = 0;
    if(nrof_superclasses >0)
        startText.append(" extends ");
    for (UMLClassifier * concept= superclasses.first(); concept; concept = superclasses.next())
    {
        startText.append(parentDoc->cleanName(concept->getName()));
        if(i != (nrof_superclasses-1))
            startText.append(", ");
        i++;
    }

    // write out what we 'implement'
    i = 0;
    if(nrof_superinterfaces >0)
    {
        // In Java interfaces "extend" other interfaces. Classes "implement" interfaces
        if(isInterface)
            startText.append(" extends ");
        else
            startText.append(" implements ");
    }
    for (UMLClassifier * concept= superinterfaces.first(); concept; concept = superinterfaces.next())
    {
        startText.append(parentDoc->cleanName(concept->getName()));
        if(i != (nrof_superinterfaces-1))
            startText.append(", ");
        i++;
    }

    // Set the header and end text for the hier.codeblock
    setStartText(startText+" {");

    // setEndText("}"); // not needed

}
예제 #12
0
void XMLSchemaWriter::writeComplexTypeClassifierDecl (UMLClassifier *c,
        UMLAssociationList associations,
        UMLAssociationList aggregations,
        UMLAssociationList compositions,
        UMLClassifierList superclasses,
        QTextStream &XMLschema)
{

    // Preparations
    //

    // sort attributes by Scope
    UMLAttributeList attribs = findAttributes(c);
    QStringList attribGroups = findAttributeGroups(c);

    // test for relevant associations
    bool hasAssociations = determineIfHasChildNodes(c);
    bool hasSuperclass = superclasses.count()> 0;
    bool hasAttributes = attribs.count() > 0 || attribGroups.count() > 0;

    // START WRITING

    // start body of element
    QString elementTypeName = getElementTypeName(c);

    XMLschema<<getIndent()<<"<"<<makeSchemaTag("complexType")<<" name=\""<<elementTypeName<<"\"";

    if(hasAssociations || hasAttributes || hasSuperclass)
    {

        XMLschema<<">"<<m_endl;

        m_indentLevel++;

        if(hasSuperclass)
        {
            QString superClassName = getElementTypeName(superclasses.first());
            XMLschema<<getIndent()<<"<"<<makeSchemaTag("complexContent")<<">"<<m_endl;

            //PROBLEM: we only treat ONE superclass for inheritence.. bah.
            m_indentLevel++;
            XMLschema<<getIndent()<<"<"<<makeSchemaTag("extension")<<" base=\""<<makePackageTag(superClassName)
            <<"\"";
            if(hasAssociations || hasAttributes )
                XMLschema<<">"<<m_endl;
            else
                XMLschema<<"/>"<<m_endl;

            m_indentLevel++;
        }

        if(hasAssociations)
        {
            // Child Elements (from most associations)
            //
            bool didFirstOne = false;
            didFirstOne = writeAssociationDecls(associations, true, didFirstOne, c->getID(), XMLschema);
            didFirstOne = writeAssociationDecls(aggregations, false, didFirstOne, c->getID(), XMLschema);
            didFirstOne = writeAssociationDecls(compositions, false, didFirstOne, c->getID(), XMLschema);

            if (didFirstOne) {
                m_indentLevel--;
                XMLschema<<getIndent()<<"</"<<makeSchemaTag("sequence")<<">"<<m_endl;
            }
        }

        // ATTRIBUTES
        //
        if(hasAttributes)
        {
            writeAttributeDecls(attribs, XMLschema);
            for(uint i= 0; i < attribGroups.count(); i++)
                XMLschema<<getIndent()<<"<"<<makeSchemaTag("attributeGroup")<<" ref=\""
                <<makePackageTag(attribGroups[i])<<"\"/>"<<m_endl;
        }

        if(hasSuperclass)
        {
            m_indentLevel--;

            if(hasAssociations || hasAttributes )
                XMLschema<<getIndent()<<"</"<<makeSchemaTag("extension")<<">"<<m_endl;

            m_indentLevel--;
            XMLschema<<getIndent()<<"</"<<makeSchemaTag("complexContent")<<">"<<m_endl;
        }

        // close this element decl
        m_indentLevel--;
        XMLschema<<getIndent()<<"</"<<makeSchemaTag("complexType")<<">"<<m_endl;

    } else
        XMLschema<<"/>"<<m_endl; // empty node. just close this element decl

}