void CSharpWriter::writeAttributes(UMLClassifier *c, QTextStream &cs) { UMLAttributeList atpub, atprot, atpriv, atdefval; atpub.setAutoDelete(false); atprot.setAutoDelete(false); atpriv.setAutoDelete(false); atdefval.setAutoDelete(false); //sort attributes by scope and see if they have a default value UMLAttributeList atl = c->getAttributeList(); UMLAttribute *at; for (at = atl.first(); at ; at = atl.next()) { if (!at->getInitialValue().isEmpty()) atdefval.append(at); switch (at->getVisibility()) { case Uml::Visibility::Public: atpub.append(at); break; case Uml::Visibility::Protected: atprot.append(at); break; case Uml::Visibility::Private: atpriv.append(at); break; default: break; } } if (forceSections() || atl.count()) cs << m_endl << m_container_indent << m_indentation << "#region Attributes" << m_endl << m_endl; // write public attributes if (forceSections() || atpub.count()) { writeAttributes(atpub,cs); } // write protected attributes if (forceSections() || atprot.count()) { writeAttributes(atprot,cs); } // write private attributes if (forceSections() || atpriv.count()) { writeAttributes(atpriv,cs); } if (forceSections() || atl.count()) cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl; }
// we basically want to update the doc and start text of this method void JavaCodeOperation::updateMethodDeclaration() { CodeDocument * doc = getParentDocument(); JavaClassifierCodeDocument * javadoc = dynamic_cast<JavaClassifierCodeDocument*>(doc); UMLOperation * o = getParentOperation(); bool isInterface = javadoc->getParentClassifier()->isInterface(); QString endLine = getNewLineEndingChars(); // now, the starting text. QString strVis = Uml::Visibility::toString(o->visibility()); // no return type for constructors QString fixedReturn = JavaCodeGenerator::fixTypeName(o->getTypeName()); QString returnType = o->isConstructorOperation() ? QString() : (fixedReturn + QLatin1String(" ")); QString methodName = o->name(); QString paramStr; // assemble parameters UMLAttributeList list = getParentOperation()->getParmList(); int nrofParam = list.count(); int paramNum = 0; foreach (UMLAttribute* parm, list) { QString rType = parm->getTypeName(); QString paramName = parm->name(); paramStr += rType + QLatin1Char(' ') + paramName; paramNum++; if (paramNum != nrofParam) paramStr += QLatin1String(", "); }
// we basically want to update the doc and start text of this method void DCodeOperation::updateMethodDeclaration() { CodeDocument * doc = getParentDocument(); DClassifierCodeDocument * ddoc = dynamic_cast<DClassifierCodeDocument*>(doc); UMLOperation * o = getParentOperation(); bool isInterface = ddoc->getParentClassifier()->isInterface(); QString endLine = getNewLineEndingChars(); /* * Member function declaration * * (visibility) (static | abstract | override) retType name (param1, ..., paramN) (; | {) * a b c d e f g h */ QString startText; // (a) visibility modifier //FIXME: startText += o->getVisibility().toString() + " "; // (b) static if (o->isStatic()) startText += "static "; // (c) abstract //TODO // (d) override //TODO // (e) return type if (!o->isConstructorOperation()) { //FIXME: startText += DCodeGenerator::fixTypeName(o->getTypeName()) + " "; } // (f) name startText += o->name(); // (g) params startText += '('; // assemble parameters QString paramStr = QString(""); UMLAttributeList list = getParentOperation()->getParmList(); int paramNum = list.count(); foreach (UMLAttribute* parm, list ) { QString rType = parm->getTypeName(); QString paramName = parm->name(); paramStr += rType + ' ' + paramName; paramNum--; if (paramNum > 0) paramStr += ", "; }
// we basically want to update the doc and start text of this method void RubyCodeOperation::updateMethodDeclaration() { CodeDocument * doc = getParentDocument(); RubyClassifierCodeDocument * rubydoc = dynamic_cast<RubyClassifierCodeDocument*>(doc); UMLClassifier *c = rubydoc->getParentClassifier(); UMLOperation * o = getParentOperation(); bool isInterface = rubydoc->getParentClassifier()->isInterface(); QString endLine = getNewLineEndingChars(); // now, the starting text. //:UNUSED: QString strVis = o->visibility().toString(); // no return type for constructors QString fixedReturn = RubyCodeGenerator::cppToRubyType(o->getTypeName()); QString returnType = o->isConstructorOperation() ? QString("") : (fixedReturn + QString(" ")); QString methodName = o->name(); QString RubyClassName = rubydoc->getRubyClassName(c->name()); // Skip destructors, and operator methods which // can't be defined in ruby if ( methodName.startsWith('~') || QRegExp("operator\\s*(=|--|\\+\\+|!=)$").exactMatch(methodName) ) { getComment()->setText(""); return; } if (RubyClassName == methodName) { methodName = "initialize"; } methodName.remove(QRegExp("operator\\s*")); methodName = methodName.mid(0, 1).toLower() + methodName.mid(1); QString paramStr = QString(""); QStringList commentedParams; // assemble parameters UMLAttributeList list = getParentOperation()->getParmList(); int nrofParam = list.count(); int paramNum = 0; foreach (UMLAttribute* parm, list) { QString paramName = RubyCodeGenerator::cppToRubyName(parm->name()); paramStr += paramName; if (! parm->getInitialValue().isEmpty()) { paramStr += QString(" = ") + RubyCodeGenerator::cppToRubyType(parm->getInitialValue()); } paramNum++; if (paramNum != nrofParam ) paramStr += ", "; }
void JSWriter::writeOperations(QString classname, UMLOperationList *opList, QTextStream &js) { UMLOperation *op; UMLAttribute *at; for(op = opList->first(); op; op = opList->next()) { UMLAttributeList atl = op->getParmList(); //write method doc if we have doc || if at least one of the params has doc bool writeDoc = forceDoc() || !op->getDoc().isEmpty(); for (at = atl.first(); at; at = atl.next()) writeDoc |= !at->getDoc().isEmpty(); if( writeDoc ) //write method documentation { js << "/**" << m_endl << formatDoc(op->getDoc()," * "); for (at = atl.first(); at; at = atl.next()) //write parameter documentation { if(forceDoc() || !at->getDoc().isEmpty()) { js << " * @param " + cleanName(at->getName())<<m_endl; js << formatDoc(at->getDoc()," * "); } }//end for : write parameter documentation js << " */" << m_endl; }//end if : write method documentation js << classname << ".prototype." << cleanName(op->getName()) << " = function " << "("; int i = atl.count(); int j=0; for (at = atl.first(); at ;at = atl.next(),j++) { js << cleanName(at->getName()) << (!(at->getInitialValue().isEmpty()) ? (QString(" = ")+at->getInitialValue()) : QString("")) << ((j < i-1)?", ":""); } js << ")" << m_endl << "{" << m_endl << m_indentation << m_endl << "}" << m_endl; js << m_endl << m_endl; }//end for }
// these exist for abstract classes only (which become xs:group nodes) QStringList XMLSchemaWriter::findAttributeGroups (UMLClassifier *c) { // we need to look for any class we inherit from. IF these // have attributes, then we need to notice QStringList list; UMLClassifierList superclasses = c->findSuperClassConcepts(); // list of what inherits from us for(UMLClassifier *classifier = superclasses.first(); classifier; classifier = superclasses.next()) { if(classifier->getAbstract()) { // only classes have attributes.. if (!classifier->isInterface()) { UMLAttributeList attribs = c->getAttributeList(); if (attribs.count() > 0) list.append(getElementName(classifier)+"AttribGroupType"); } } } return list; }
void XMLSchemaWriter::writeAttributeGroupDecl (const QString &elementName, UMLAttributeList &attribs, QTextStream &XMLschema ) { if (attribs.count()> 0) { // write a little documentation writeComment("attributes for element "+elementName,XMLschema); // open attribute group XMLschema<<getIndent()<<"<"<<makeSchemaTag("attributeGroup")<<" name=\""<<elementName+"AttribGroupType"<<"\">"<<m_endl; m_indentLevel++; for( UMLAttribute *at=attribs.first(); at; at=attribs.next()) { writeAttributeDecl(at,XMLschema); } m_indentLevel--; // close attrib group node XMLschema<<getIndent()<<"</"<<makeSchemaTag("attributeGroup")<<">"<<m_endl; } }
void CSharpWriter::writeOperations(UMLOperationList opList, QTextStream &cs, bool isInterface /* = false */, bool isOverride /* = false */, bool generateErrorStub /* = false */) { for (UMLOperation *op=opList.first(); op ; op=opList.next()) { UMLAttributeList atl = op->getParmList(); UMLAttribute *at; //write method doc if we have doc || if at least one of the params has doc bool writeDoc = forceDoc() || !op->getDoc().isEmpty(); for (at = atl.first(); at; at = atl.next()) { writeDoc |= !at->getDoc().isEmpty(); } //write method documentation if (writeDoc && !isOverride) { cs << m_container_indent << m_indentation << "/// <summary>" << m_endl; cs << formatDoc(op->getDoc(), m_container_indent + m_indentation + "/// "); cs << m_container_indent << m_indentation << "/// </summary>" << m_endl; //write parameter documentation for (at = atl.first(); at; at = atl.next()) { if (forceDoc() || !at->getDoc().isEmpty()) { cs << m_container_indent << m_indentation << "/// <param name=\"" << cleanName(at->getName()) << "\">"; //removing newlines from parameter doc cs << formatDoc(at->getDoc(), "").replace("\n", " ").remove('\r').replace(QRegExp(" $"), ""); cs << "</param>" << m_endl; } } // FIXME: "returns" should contain documentation, not type. cs << m_container_indent << m_indentation << "/// <returns>"; if (! op->getTypeName().isEmpty()) { cs << makeLocalTypeName(op); } cs << "</returns>" << m_endl; } // method visibility cs << m_container_indent << m_indentation; if (!isInterface) { if (!isOverride) { if (op->getAbstract()) cs << "abstract "; cs << op->getVisibility().toString() << " "; if (op->getStatic()) cs << "static "; } else { // method overriding an abstract parent cs << op->getVisibility().toString() << " override "; if (op->getStatic()) cs << "static "; } } // return type (unless constructor, destructor) if (!op->isLifeOperation()) { if (op->getTypeName().isEmpty()) { cs << "void "; } else { cs << makeLocalTypeName(op) << " "; } } // method name cs << cleanName(op->getName()) << "("; // method parameters int i= atl.count(); int j=0; for (at = atl.first(); at; at = atl.next(), j++) { cs << makeLocalTypeName(at) << " " << cleanName(at->getName()); // no initial values in C# //<< (!(at->getInitialValue().isEmpty()) ? // (QString(" = ")+at->getInitialValue()) : // QString("")) cs << ((j < i-1)?", ":""); } cs << ")"; //FIXME: how to control generation of error stub? if (!isInterface && (!op->getAbstract() || isOverride)) { cs << m_endl << m_container_indent << m_indentation << "{" << m_endl; if (generateErrorStub) { cs << m_container_indent << m_indentation << m_indentation; cs << "throw new Exception(\"The method or operation is not implemented.\");" << m_endl; } cs << m_container_indent << m_indentation << "}" << m_endl; } else { cs << ';' << m_endl; } cs << m_endl; } }
/** * This slot is called to finish item editing */ void UMLListViewItem::slotEditFinished(const QString &newText) { m_label = text(0); DEBUG(DBG_LVI) << this << "text=" << newText; UMLListView* listView = static_cast<UMLListView*>(treeWidget()); UMLDoc* doc = listView->document(); if (newText == m_label) { return; } if (newText.isEmpty()) { cancelRenameWithMsg(); return; } switch (m_type) { case lvt_UseCase: case lvt_Actor: case lvt_Class: case lvt_Package: case lvt_UseCase_Folder: case lvt_Logical_Folder: case lvt_Component_Folder: case lvt_Deployment_Folder: case lvt_EntityRelationship_Folder: case lvt_Interface: case lvt_Datatype: case lvt_Enum: case lvt_EnumLiteral: case lvt_Subsystem: case lvt_Component: case lvt_Port: case lvt_Node: case lvt_Category: if (m_object == 0 || !doc->isUnique(newText)) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, newText)); doc->setModified(true); m_label = newText; break; case lvt_Operation: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLOperation *op = static_cast<UMLOperation*>(m_object); UMLClassifier *parent = static_cast<UMLClassifier *>(op->parent()); Model_Utils::OpDescriptor od; Model_Utils::Parse_Status st = Model_Utils::parseOperation(newText, od, parent); if (st == Model_Utils::PS_OK) { // TODO: Check that no operation with the exact same profile exists. UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(op, od.m_name)); op->setType(od.m_pReturnType); UMLAttributeList parmList = op->getParmList(); const int newParmListCount = parmList.count(); if (newParmListCount > od.m_args.count()) { // Remove parameters at end of of list that no longer exist. for (int i = od.m_args.count(); i < newParmListCount; i++) { UMLAttribute *a = parmList.at(i); op->removeParm(a, false); } } Model_Utils::NameAndType_ListIt lit = od.m_args.begin(); for (int i = 0; lit != od.m_args.end(); ++lit, ++i) { const Model_Utils::NameAndType& nm_tp = *lit; UMLAttribute *a; if (i < newParmListCount) { a = parmList.at(i); } else { a = new UMLAttribute(op); a->setID(UniqueID::gen()); } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(a, nm_tp.m_name)); a->setType(nm_tp.m_type); a->setParmKind(nm_tp.m_direction); a->setInitialValue(nm_tp.m_initialValue); if (i >= newParmListCount) { op->addParm(a); } } m_label = op->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_Attribute: case lvt_EntityAttribute: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLClassifier *parent = static_cast<UMLClassifier*>(m_object->parent()); Model_Utils::NameAndType nt; Uml::Visibility::Enum vis; Model_Utils::Parse_Status st; st = Model_Utils::parseAttribute(newText, nt, parent, &vis); if (st == Model_Utils::PS_OK) { UMLObject *exists = parent->findChildObject(newText); if (exists) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, nt.m_name)); UMLAttribute *pAtt = static_cast<UMLAttribute*>(m_object); pAtt->setType(nt.m_type); pAtt->setVisibility(vis); pAtt->setParmKind(nt.m_direction); pAtt->setInitialValue(nt.m_initialValue); m_label = pAtt->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_PrimaryKeyConstraint: case lvt_UniqueConstraint: case lvt_ForeignKeyConstraint: case lvt_CheckConstraint: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLEntity *parent = static_cast<UMLEntity*>(m_object->parent()); QString name; Model_Utils::Parse_Status st; st = Model_Utils::parseConstraint(newText, name, parent); if (st == Model_Utils::PS_OK) { UMLObject *exists = parent->findChildObject(name); if (exists) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, name)); UMLEntityConstraint* uec = static_cast<UMLEntityConstraint*>(m_object); m_label = uec->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_Template: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLClassifier *parent = static_cast<UMLClassifier*>(m_object->parent()); Model_Utils::NameAndType nt; Model_Utils::Parse_Status st = Model_Utils::parseTemplate(newText, nt, parent); if (st == Model_Utils::PS_OK) { UMLObject *exists = parent->findChildObject(newText); if (exists) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, nt.m_name)); UMLTemplate *tmpl = static_cast<UMLTemplate*>(m_object); tmpl->setType(nt.m_type); m_label = tmpl->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_UseCase_Diagram: case lvt_Class_Diagram: case lvt_Sequence_Diagram: case lvt_Collaboration_Diagram: case lvt_State_Diagram: case lvt_Activity_Diagram: case lvt_Component_Diagram: case lvt_Deployment_Diagram: { UMLView *view = doc->findView(ID()); if (view == 0) { cancelRenameWithMsg(); return; } UMLView *anotherView = doc->findView(view->umlScene()->type(), newText); if (anotherView && anotherView->umlScene()->ID() == ID()) { anotherView = 0; } if (anotherView) { cancelRenameWithMsg(); return; } view->umlScene()->setName(newText); setText(newText); doc->signalDiagramRenamed(view); break; } default: KMessageBox::error(0, i18n("Renaming an item of listview type %1 is not yet implemented.", m_type), i18n("Function Not Implemented")); setText(m_label); break; } doc->setModified(true); }
// we basically want to update the doc and start text of this method void RubyCodeOperation::updateMethodDeclaration() { CodeDocument * doc = getParentDocument(); RubyClassifierCodeDocument * rubydoc = dynamic_cast<RubyClassifierCodeDocument*>(doc); UMLClassifier *c = rubydoc->getParentClassifier(); UMLOperation * o = getParentOperation(); bool isInterface = rubydoc->getParentClassifier()->isInterface(); QString endLine = getNewLineEndingChars(); // now, the starting text. QString strVis = rubydoc->scopeToRubyDecl(o->getVisibility()); // no return type for constructors QString fixedReturn = RubyCodeGenerator::cppToRubyType(o->getTypeName()); QString returnType = o->isConstructorOperation() ? QString("") : (fixedReturn + QString(" ")); QString methodName = o->getName(); QString RubyClassName = rubydoc->getRubyClassName(c->getName()); // Skip destructors, and operator methods which // can't be defined in ruby if ( methodName.startsWith("~") || QRegExp("operator\\s*(=|--|\\+\\+|!=)$").exactMatch(methodName) ) { getComment()->setText(""); return; } if (RubyClassName == methodName) { methodName = "initialize"; } methodName.replace(QRegExp("operator\\s*"), ""); methodName = methodName.mid(0, 1).lower() + methodName.mid(1); QString paramStr = QString(""); QStringList commentedParams; // assemble parameters UMLAttributeList list = getParentOperation()->getParmList(); int nrofParam = list.count(); int paramNum = 0; for(UMLAttribute* parm = list.first(); parm; parm = list.next()) { QString paramName = RubyCodeGenerator::cppToRubyName(parm->getName()); paramStr += paramName; if (! parm->getInitialValue().isEmpty()) { paramStr += QString(" = ") + RubyCodeGenerator::cppToRubyType(parm->getInitialValue()); } paramNum++; if (paramNum != nrofParam ) paramStr += ", "; } QString startText; if (isInterface) { // Assume 'isInterface' means a module in Ruby, so // generate module methods startText = "def "+ RubyClassName + '.' + methodName + '(' + paramStr +')'; } else { startText = "def "+ methodName + '(' + paramStr +')'; } startText += ""; setEndMethodText("end"); setStartMethodText(startText); // Lastly, for text content generation, we fix the comment on the // operation, IF the codeop is autogenerated & currently empty QString comment = o->getDoc(); if (comment.isEmpty()) { if (getContentType() == CodeBlock::AutoGenerated) { UMLAttributeList parameters = o->getParmList(); for(UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) { comment += endLine + "* _" + iterator.current()->getName() + "_ "; comment += (' ' + iterator.current()->getDoc().replace( QRegExp("[\\n\\r]+[\\t ]*"), endLine + " " ) ); } // add a returns statement too if(!returnType.isEmpty() && !QRegExp("^void\\s*$").exactMatch(returnType)) comment += endLine + "* _returns_ " + returnType + ' '; getComment()->setText(comment); } } else { comment.replace(QRegExp("[\\n\\r]+ *"), endLine); comment.replace(QRegExp("[\\n\\r]+\\t*"), endLine); comment.replace(" m_", " "); comment.replace(QRegExp("\\s[npb](?=[A-Z])"), " "); QRegExp re_params("@param (\\w)(\\w*)"); int pos = re_params.search(comment); while (pos != -1) { comment.replace( re_params.cap(0), QString("@param _") + re_params.cap(1).lower() + re_params.cap(2) + '_' ); commentedParams.append(re_params.cap(1).lower() + re_params.cap(2)); pos += re_params.matchedLength() + 3; pos = re_params.search(comment, pos); } UMLAttributeList parameters = o->getParmList(); for (UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) { // Only write an individual @param entry if one hasn't been found already // in the main doc comment if (commentedParams.contains(RubyCodeGenerator::cppToRubyName(iterator.current()->getName())) == 0) { comment += (endLine + "@param _" + RubyCodeGenerator::cppToRubyName(iterator.current()->getName()) + '_'); if (iterator.current()->getDoc().isEmpty()) { comment += (' ' + RubyCodeGenerator::cppToRubyType(iterator.current()->getTypeName())); } else { comment += (' ' + iterator.current()->getDoc().replace(QRegExp("[\\n\\r]+[\\t ]*"), endLine + " ")); } } } comment.replace("@ref ", ""); comment.replace("@param", "*"); comment.replace("@return", "* _returns_"); // All lines after the first one starting with '*' in the doc comment // must be indented correctly. If they aren't a list // item starting with '*', then indent the text with // two spaces, ' ', to line up with the list item. pos = comment.find(endLine + '*'); if (pos != -1) { pos += endLine.length() + 1; pos = comment.find(endLine, pos); } while (pos > 0) { pos += endLine.length(); if (comment[pos] != '*') { comment.insert(pos, " "); pos += 2; } pos = comment.find(endLine, pos); } QString typeStr = RubyCodeGenerator::cppToRubyType(o->getTypeName()); if ( !typeStr.isEmpty() && !QRegExp("^void\\s*$").exactMatch(typeStr) && comment.contains("_returns_") == 0 ) { comment += endLine + "* _returns_ " + typeStr; } getComment()->setText(comment); } // In Java, for interfaces..we DONT write out non-public // method declarations. And for Ruby modules? if (isInterface) { UMLOperation * o = getParentOperation(); if(o->getVisibility() != Uml::Visibility::Public) setWriteOutText(false); } }
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 }