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