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); } } }
/** * Override parent implementation: The secondary data is not for the * UMLAssociation itself but for its role B object. */ void setTypeReferences(UMLObject *item, const QString& quid, const QString& type) { UMLAssociation *assoc = static_cast<UMLAssociation*>(item); if (!quid.isEmpty()) { assoc->getUMLRole(Uml::B)->setSecondaryId(quid); } if (!type.isEmpty()) { assoc->getUMLRole(Uml::B)->setSecondaryFallback(type); } }
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); } } }
// need to get the ID of the parent object // this is kind of broken for UMLRoles. QString CodeParameter::getID () { UMLRole * role = dynamic_cast<UMLRole*>(m_parentObject); if(role) { // cant use Role "ID" as that is used to distinquish if its // role "A" or "B" UMLAssociation *assoc = role->parentAssociation(); return ID2STR(assoc->id()); } else return ID2STR(m_parentObject->id()); }
void AssociationGeneralPage::slotStereoCheckboxChanged(int state) { QWidget *nameInputWidget = NULL; if (state) { m_pAssocNameLE->hide(); m_pNameAndTypeLayout->removeWidget(m_pAssocNameLE); UMLAssociation *umlAssoc = m_pAssociationWidget->association(); Dialog_Utils::insertStereotypesSorted(m_pAssocNameComB, umlAssoc->stereotype()); nameInputWidget = m_pAssocNameComB; } else { m_pAssocNameComB->hide(); m_pNameAndTypeLayout->removeWidget(m_pAssocNameComB); nameInputWidget = m_pAssocNameLE; } m_pNameAndTypeLayout->addWidget(nameInputWidget, 0, 1); nameInputWidget->show(); nameInputWidget->setFocus(); m_pAssocNameL->setBuddy(nameInputWidget); }
/** * Adds an AssociationWidget to the association list and creates the * corresponding UMLAssociation in the current UMLDoc. * If the association can't be added, is deleted. * * @param assoc The AssociationWidget to add. * @return True on success */ bool ToolBarStateAssociation::addAssociationInViewAndDoc(AssociationWidget* assoc) { // append in view if (m_pUMLScene->addAssociation(assoc, false)) { // if view went ok, then append in document UMLAssociation *umla = assoc->association(); if (umla) { // association with model representation in UMLDoc Uml::ModelType::Enum m = Model_Utils::convert_DT_MT(m_pUMLScene->type()); UMLDoc *umldoc = UMLApp::app()->document(); umla->setUMLPackage(umldoc->rootFolder(m)); umldoc->addAssociation(umla); } return true; } else { uError() << "cannot addAssocInViewAndDoc(), deleting"; delete assoc; return false; } }
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 } } }
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; }
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); }
/** * Create an Umbrello object from a PetalNode of the Logical View. * * @return True for success. * Given a PetalNode for which the mapping to Umbrello is not yet * implemented umbrellify() is a no-op but also returns true. */ bool umbrellify(PetalNode *node, UMLPackage *parentPkg = NULL) { if (node == NULL) { uError() << "umbrellify: node is NULL"; return false; } QStringList args = node->initialArgs(); QString objType = args[0]; QString name = clean(args[1]); Uml::IDType id = quid(node); if (objType == "Class_Category") { UMLObject *o = Import_Utils::createUMLObject(UMLObject::ot_Package, name, parentPkg); o->setID(id); PetalNode *logical_models = node->findAttribute("logical_models").node; if (logical_models) { UMLPackage *localParent = static_cast<UMLPackage*>(o); PetalNode::NameValueList atts = logical_models->attributes(); for (int i = 0; i < atts.count(); ++i) { umbrellify(atts[i].second.node, localParent); } } else if (!handleControlledUnit(node, name, id, parentPkg)) { uDebug() << "umbrellify: handling of " << objType << " " << name << " is not yet implemented"; } } else if (objType == "Class") { UMLObject *o = Import_Utils::createUMLObject(UMLObject::ot_Class, name, parentPkg); o->setID(id); UMLClassifier *c = static_cast<UMLClassifier*>(o); // set stereotype QString stereotype = clean(node->findAttribute("stereotype").string); if (!stereotype.isEmpty()) { if (stereotype.toLower() == "interface") c->setBaseType(UMLObject::ot_Interface); else c->setStereotype(stereotype); } // insert attributes AttributesReader attReader(c); attReader.read(node, c->name()); // insert operations OperationsReader opReader(c); opReader.read(node, c->name()); // insert generalizations SuperclassesReader superReader(c); superReader.read(node, c->name()); // insert realizations RealizationsReader realReader(c); realReader.read(node, c->name()); } else if (objType == "Association") { PetalNode *roles = node->findAttribute("roles").node; if (node == NULL) { uError() << "umbrellify: cannot find roles of Association"; return false; } UMLAssociation *assoc = new UMLAssociation(Uml::AssociationType::UniAssociation); PetalNode::NameValueList roleList = roles->attributes(); for (uint i = 0; i <= 1; ++i) { PetalNode *roleNode = roleList[i].second.node; if (roleNode == NULL) { uError() << "umbrellify: roleNode of Association is NULL"; return false; } if (roleNode->name() != "Role") { uDebug() << "umbrellify(" << name << "): expecting Role, found \"" << roleNode->name(); continue; } // index 0 corresponds to Umbrello roleB // index 1 corresponds to Umbrello roleA UMLRole *role = assoc->getUMLRole((Uml::Role_Type) !i); QStringList initialArgs = roleNode->initialArgs(); if (initialArgs.count() > 1) { QString roleName = clean(initialArgs[1]); if (! roleName.startsWith(QLatin1String("$UNNAMED"))) role->setName(roleName); } role->setID(quid(roleNode)); QString quidref = quidu(roleNode); QString type = clean(roleNode->findAttribute("supplier").string); if (!quidref.isEmpty()) { role->setSecondaryId(quidref); } if (!type.isEmpty()) { role->setSecondaryFallback(type); } QString label = clean(roleNode->findAttribute("label").string); if (!label.isEmpty()) { role->setName(label); } QString client_cardinality = clean(roleNode->findAttribute("client_cardinality").string); if (!client_cardinality.isEmpty()) { role->setMultiplicity(client_cardinality); } QString is_navigable = clean(roleNode->findAttribute("is_navigable").string); if (is_navigable == "FALSE") { assoc->setAssociationType(Uml::AssociationType::Association); } QString is_aggregate = clean(roleNode->findAttribute("is_aggregate").string); if (is_aggregate == "TRUE") { assoc->setAssociationType(Uml::AssociationType::Aggregation); } QString containment = clean(roleNode->findAttribute("Containment").string); if (containment == "By Value") { assoc->setAssociationType(Uml::AssociationType::Composition); } QString doc = roleNode->findAttribute("documentation").string; if (! doc.isEmpty()) role->setDoc(doc); } UMLApp::app()->document()->addAssociation(assoc); } else { uDebug() << "umbrellify: object type " << objType << " is not yet implemented"; } return true; }
/** * Construct all the widgets for this dialog. */ void AssociationGeneralPage::constructWidget() { // general configuration of the GUI int margin = fontMetrics().height(); setMinimumSize(310, 330); QVBoxLayout * topLayout = new QVBoxLayout(this); topLayout->setSpacing(6); // group boxes for name+type, documentation properties QGroupBox *nameAndTypeGB = new QGroupBox(this); QGroupBox *docGB = new QGroupBox(this); nameAndTypeGB->setTitle(i18n("Properties")); docGB->setTitle(i18n("Documentation")); topLayout->addWidget(nameAndTypeGB); topLayout->addWidget(docGB); m_pNameAndTypeLayout = new QGridLayout(nameAndTypeGB); m_pNameAndTypeLayout->setSpacing(6); m_pNameAndTypeLayout->setMargin(margin); // Association name m_pAssocNameL = new QLabel(i18nc("name of association widget", "Name:")); m_pNameAndTypeLayout->addWidget(m_pAssocNameL, 0, 0); m_pAssocNameLE = new KLineEdit(m_pAssociationWidget->name()); m_pAssocNameComB = new KComboBox(true, nameAndTypeGB); m_pAssocNameComB->setCompletionMode(KGlobalSettings::CompletionPopup); m_pAssocNameComB->setDuplicatesEnabled(false); // only allow one of each type in box QWidget *nameInputWidget = m_pAssocNameLE; UMLAssociation *umlAssoc = m_pAssociationWidget->association(); if (umlAssoc && umlAssoc->umlStereotype()) { m_pAssocNameLE->hide(); Dialog_Utils::insertStereotypesSorted(m_pAssocNameComB, umlAssoc->stereotype()); nameInputWidget = m_pAssocNameComB; } else { m_pAssocNameComB->hide(); } m_pNameAndTypeLayout->addWidget(nameInputWidget, 0, 1); nameInputWidget->setFocus(); m_pAssocNameL->setBuddy(nameInputWidget); if (umlAssoc) { // stereotype checkbox m_pStereoChkB = new QCheckBox(i18n("Stereotype"), nameAndTypeGB); m_pStereoChkB->setChecked(umlAssoc->umlStereotype() != NULL); connect(m_pStereoChkB, SIGNAL(stateChanged(int)), this, SLOT(slotStereoCheckboxChanged(int))); m_pNameAndTypeLayout->addWidget(m_pStereoChkB, 0, 2); } // type Uml::AssociationType::Enum currentType = m_pAssociationWidget->associationType(); QString currentTypeAsString = Uml::AssociationType::toStringI18n(currentType); QLabel *pTypeL = new QLabel(i18n("Type:"), nameAndTypeGB); m_pNameAndTypeLayout->addWidget(pTypeL, 1, 0); // Here is a list of all the supported choices for changing // association types. m_AssocTypes.clear(); m_AssocTypes << currentType; uDebug() << "current type = " << Uml::AssociationType::toString(currentType); // dynamically load all allowed associations for (int i = Uml::AssociationType::Generalization; i < Uml::AssociationType::Reserved; ++i) { // we don't need to check for current type Uml::AssociationType::Enum assocType = Uml::AssociationType::fromInt(i); if (assocType == currentType) continue; // UMLScene based checks if (m_pAssociationWidget->umlScene()->type() == Uml::DiagramType::Collaboration && !(assocType == Uml::AssociationType::Coll_Message_Asynchronous || assocType == Uml::AssociationType::Coll_Message_Synchronous || assocType == Uml::AssociationType::Anchor)) continue; if (AssocRules::allowAssociation(assocType, m_pAssociationWidget->widgetForRole(Uml::RoleType::A), m_pAssociationWidget->widgetForRole(Uml::RoleType::B))) { m_AssocTypes << assocType; uDebug() << "to type list = " << Uml::AssociationType::toString(assocType); } } bool found = false; m_AssocTypeStrings.clear(); for (int i = 0; i < m_AssocTypes.size(); ++i) { if (m_AssocTypes[i] == currentType) { found = true; } m_AssocTypeStrings << Uml::AssociationType::toStringI18n(m_AssocTypes[i]); } if (!found) { m_AssocTypes.clear(); m_AssocTypes << currentType; m_AssocTypeStrings.clear(); m_AssocTypeStrings << currentTypeAsString; } m_pTypeCB = new KComboBox(nameAndTypeGB); pTypeL->setBuddy(m_pTypeCB); m_pTypeCB->addItems(m_AssocTypeStrings); m_pTypeCB->setCompletedItems(m_AssocTypeStrings); m_pTypeCB->setDuplicatesEnabled(false); // only allow one of each type in box m_pTypeCB->setCompletionMode(KGlobalSettings::CompletionPopup); m_pNameAndTypeLayout->addWidget(m_pTypeCB, 1, 1); // document QHBoxLayout * docLayout = new QHBoxLayout(docGB); docLayout->setMargin(margin); m_doc = new KTextEdit(docGB); docLayout->addWidget(m_doc); m_doc->setText(m_pAssociationWidget->documentation()); m_doc->setWordWrapMode(QTextOption::WordWrap); }
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); }
/** * Set the class attributes of this object from * the passed element node. */ void CodeParameter::setAttributesFromNode ( QDomElement & root) { // set local attributes, parent object first QString idStr = root.attribute("parent_id","-1"); Uml::IDType id = STR2ID(idStr); // always disconnect m_parentObject->disconnect(this); // now, what is the new object we want to set? UMLObject * obj = UMLApp::app()->document()->findObjectById(id); if(obj) { // FIX..one day. // Ugh. This is UGLY, but we have to do it this way because UMLRoles // don't go into the document list of UMLobjects, and have the same // ID as their parent UMLAssociations. So..the drill is then special // for Associations..in that case we need to find out which role will // serve as the parameter here. The REAL fix, of course, would be to // treat UMLRoles on a more even footing, but im not sure how that change // might ripple throughout the code and cause problems. Thus, since the // change appears to be needed for only this part, I'll do this crappy // change instead. -b.t. UMLAssociation * assoc = dynamic_cast<UMLAssociation*>(obj); if(assoc) { // In this case we init with indicated role child obj. UMLRole * role = 0; int role_id = root.attribute("role_id","-1").toInt(); if(role_id == 1) role = assoc->getUMLRole(Uml::A); else if(role_id == 0) role = assoc->getUMLRole(Uml::B); else uError() << "corrupt save file? " << "cant get proper UMLRole for codeparameter uml id:" << ID2STR(id) << " w/role_id:" << role_id; // init using UMLRole obj initFields ( m_parentDocument, role); } else initFields ( m_parentDocument, obj); // just the regular approach } else uError() << "Cant load CodeParam: parentUMLObject w/id:" << ID2STR(id) << " not found, corrupt save file?"; // other attribs now setInitialValue(root.attribute("initialValue","")); // load comment now // by looking for our particular child element QDomNode node = root.firstChild(); QDomElement element = node.toElement(); bool gotComment = false; while( !element.isNull() ) { QString tag = element.tagName(); if( tag == "header" ) { QDomNode cnode = element.firstChild(); QDomElement celem = cnode.toElement(); getComment()->loadFromXMI(celem); gotComment = true; break; } node = element.nextSibling(); element = node.toElement(); } if(!gotComment) uWarning()<<" loadFromXMI : Warning: unable to initialize CodeComment in codeparam:"<<this; }
void insertAtParent(const PetalNode *, UMLObject *item) { UMLAssociation *assoc = static_cast<UMLAssociation*>(item); assoc->setObject(m_classifier, Uml::A); UMLApp::app()->document()->addAssociation(assoc); }
/** * Implement abstract operation from NativeImportBase. */ bool AdaImport::parseStmt() { const int srcLength = m_source.count(); QString keyword = m_source[m_srcIndex]; UMLDoc *umldoc = UMLApp::app()->document(); //uDebug() << '"' << keyword << '"'; if (keyword == QLatin1String("with")) { if (m_inGenericFormalPart) { // mapping of generic formal subprograms or packages is not yet implemented return false; } while (++m_srcIndex < srcLength && m_source[m_srcIndex] != QLatin1String(";")) { QStringList components = m_source[m_srcIndex].toLower().split(QLatin1Char('.')); const QString& prefix = components.first(); if (prefix == QLatin1String("system") || prefix == QLatin1String("ada") || prefix == QLatin1String("gnat") || prefix == QLatin1String("interfaces") || prefix == QLatin1String("text_io") || prefix == QLatin1String("unchecked_conversion") || prefix == QLatin1String("unchecked_deallocation")) { if (advance() != QLatin1String(",")) break; continue; } parseStems(components); if (advance() != QLatin1String(",")) break; } return true; } if (keyword == QLatin1String("generic")) { m_inGenericFormalPart = true; return true; } if (keyword == QLatin1String("package")) { const QString& name = advance(); QStringList parentPkgs = name.toLower().split(QLatin1Char('.')); parentPkgs.pop_back(); // exclude the current package parseStems(parentPkgs); UMLObject *ns = NULL; if (advance() == QLatin1String("is")) { ns = Import_Utils::createUMLObject(UMLObject::ot_Package, name, currentScope(), m_comment); if (m_source[m_srcIndex + 1] == QLatin1String("new")) { m_srcIndex++; QString pkgName = advance(); UMLObject *gp = Import_Utils::createUMLObject(UMLObject::ot_Package, pkgName, currentScope()); gp->setStereotype(QLatin1String("generic")); // Add binding from instantiator to instantiatee UMLAssociation *assoc = new UMLAssociation(Uml::AssociationType::Dependency, ns, gp); assoc->setUMLPackage(umldoc->rootFolder(Uml::ModelType::Logical)); assoc->setStereotype(QLatin1String("bind")); // Work around missing display of stereotype in AssociationWidget: assoc->setName(assoc->stereotype(true)); umldoc->addAssociation(assoc); skipStmt(); } else { pushScope(static_cast<UMLPackage*>(ns)); } } else if (m_source[m_srcIndex] == QLatin1String("renames")) { m_renaming[name] = advance(); } else { uError() << "unexpected: " << m_source[m_srcIndex]; skipStmt(QLatin1String("is")); } if (m_inGenericFormalPart) { if (ns) ns->setStereotype(QLatin1String("generic")); m_inGenericFormalPart = false; } return true; } if (m_inGenericFormalPart) return false; // skip generic formal parameter (not yet implemented) if (keyword == QLatin1String("subtype")) { QString name = advance(); advance(); // "is" QString base = expand(advance()); base.remove(QLatin1String("Standard."), Qt::CaseInsensitive); UMLObject *type = umldoc->findUMLObject(base, UMLObject::ot_UMLObject, currentScope()); if (type == NULL) { type = Import_Utils::createUMLObject(UMLObject::ot_Datatype, base, currentScope()); } UMLObject *subtype = Import_Utils::createUMLObject(type->baseType(), name, currentScope(), m_comment); UMLAssociation *assoc = new UMLAssociation(Uml::AssociationType::Dependency, subtype, type); assoc->setUMLPackage(umldoc->rootFolder(Uml::ModelType::Logical)); assoc->setStereotype(QLatin1String("subtype")); // Work around missing display of stereotype in AssociationWidget: assoc->setName(assoc->stereotype(true)); umldoc->addAssociation(assoc); skipStmt(); return true; } if (keyword == QLatin1String("type")) { QString name = advance(); QString next = advance(); if (next == QLatin1String("(")) { uDebug() << name << ": discriminant handling is not yet implemented"; // @todo Find out how to map discriminated record to UML. // For now, we just create a pro forma empty record. Import_Utils::createUMLObject(UMLObject::ot_Class, name, currentScope(), m_comment, QLatin1String("record")); skipStmt(QLatin1String("end")); if ((next = advance()) == QLatin1String("case")) m_srcIndex += 2; // skip "case" ";" skipStmt(); return true; } if (next == QLatin1String(";")) { // forward declaration Import_Utils::createUMLObject(UMLObject::ot_Class, name, currentScope(), m_comment); return true; } if (next != QLatin1String("is")) { uError() << "expecting \"is\""; return false; } next = advance(); if (next == QLatin1String("(")) { // enum type UMLObject *ns = Import_Utils::createUMLObject(UMLObject::ot_Enum, name, currentScope(), m_comment); UMLEnum *enumType = static_cast<UMLEnum*>(ns); while ((next = advance()) != QLatin1String(")")) { Import_Utils::addEnumLiteral(enumType, next, m_comment); m_comment.clear(); if (advance() != QLatin1String(",")) break; } skipStmt(); return true; } bool isTaggedType = false; if (next == QLatin1String("abstract")) { m_isAbstract = true; next = advance(); } if (next == QLatin1String("tagged")) { isTaggedType = true; next = advance(); } if (next == QLatin1String("limited") || next == QLatin1String("task") || next == QLatin1String("protected") || next == QLatin1String("synchronized")) { next = advance(); // we can't (yet?) represent that } if (next == QLatin1String("private") || next == QLatin1String("interface") || next == QLatin1String("record") || (next == QLatin1String("null") && m_source[m_srcIndex+1] == QLatin1String("record"))) { UMLObject::ObjectType t = (next == QLatin1String("interface") ? UMLObject::ot_Interface : UMLObject::ot_Class); UMLObject *ns = Import_Utils::createUMLObject(t, name, currentScope(), m_comment); if (t == UMLObject::ot_Interface) { while ((next = advance()) == QLatin1String("and")) { UMLClassifier *klass = static_cast<UMLClassifier*>(ns); QString base = expand(advance()); UMLObject *p = Import_Utils::createUMLObject(UMLObject::ot_Interface, base, currentScope()); UMLClassifier *parent = static_cast<UMLClassifier*>(p); Import_Utils::createGeneralization(klass, parent); } } else { ns->setAbstract(m_isAbstract); } m_isAbstract = false; if (isTaggedType) { if (! m_classesDefinedInThisScope.contains(ns)) m_classesDefinedInThisScope.append(ns); } else { ns->setStereotype(QLatin1String("record")); } if (next == QLatin1String("record")) m_klass = static_cast<UMLClassifier*>(ns); else skipStmt(); return true; } if (next == QLatin1String("new")) { QString base = expand(advance()); QStringList baseInterfaces; while ((next = advance()) == QLatin1String("and")) { baseInterfaces.append(expand(advance())); } const bool isExtension = (next == QLatin1String("with")); UMLObject::ObjectType t; if (isExtension || m_isAbstract) { t = UMLObject::ot_Class; } else { base.remove(QLatin1String("Standard."), Qt::CaseInsensitive); UMLObject *known = umldoc->findUMLObject(base, UMLObject::ot_UMLObject, currentScope()); t = (known ? known->baseType() : UMLObject::ot_Datatype); } UMLObject *ns = Import_Utils::createUMLObject(t, base, NULL); UMLClassifier *parent = static_cast<UMLClassifier*>(ns); ns = Import_Utils::createUMLObject(t, name, currentScope(), m_comment); if (isExtension) { next = advance(); if (next == QLatin1String("null") || next == QLatin1String("record")) { UMLClassifier *klass = static_cast<UMLClassifier*>(ns); Import_Utils::createGeneralization(klass, parent); if (next == QLatin1String("record")) { // Set the m_klass for attributes. m_klass = klass; } if (baseInterfaces.count()) { t = UMLObject::ot_Interface; QStringList::Iterator end(baseInterfaces.end()); for (QStringList::Iterator bi(baseInterfaces.begin()); bi != end; ++bi) { ns = Import_Utils::createUMLObject(t, *bi, currentScope()); parent = static_cast<UMLClassifier*>(ns); Import_Utils::createGeneralization(klass, parent); } } } } skipStmt(); return true; } // Datatypes: TO BE DONE return false; } if (keyword == QLatin1String("private")) { m_currentAccess = Uml::Visibility::Private; return true; } if (keyword == QLatin1String("end")) { if (m_klass) { if (advance() != QLatin1String("record")) { uError() << "end: expecting \"record\" at " << m_source[m_srcIndex]; } m_klass = NULL; } else if (scopeIndex()) { if (advance() != QLatin1String(";")) { QString scopeName = currentScope()->fullyQualifiedName(); if (scopeName.toLower() != m_source[m_srcIndex].toLower()) uError() << "end: expecting " << scopeName << ", found " << m_source[m_srcIndex]; } popScope(); m_currentAccess = Uml::Visibility::Public; // @todo make a stack for this } else { uError() << "importAda: too many \"end\""; } skipStmt(); return true; } // subprogram if (keyword == QLatin1String("not")) keyword = advance(); if (keyword == QLatin1String("overriding")) keyword = advance(); if (keyword == QLatin1String("function") || keyword == QLatin1String("procedure")) { const QString& name = advance(); QString returnType; if (advance() != QLatin1String("(")) { // Unlike an Ada package, a UML package does not support // subprograms. // In order to map those, we would need to create a UML // class with stereotype <<utility>> for the Ada package. uDebug() << "ignoring parameterless " << keyword << " " << name; skipStmt(); return true; } UMLClassifier *klass = NULL; UMLOperation *op = NULL; const uint MAX_PARNAMES = 16; while (m_srcIndex < srcLength && m_source[m_srcIndex] != QLatin1String(")")) { QString parName[MAX_PARNAMES]; uint parNameCount = 0; do { if (parNameCount >= MAX_PARNAMES) { uError() << "MAX_PARNAMES is exceeded at " << name; break; } parName[parNameCount++] = advance(); } while (advance() == QLatin1String(",")); if (m_source[m_srcIndex] != QLatin1String(":")) { uError() << "importAda: expecting ':'"; skipStmt(); break; } const QString &direction = advance(); QString typeName; Uml::ParameterDirection::Enum dir = Uml::ParameterDirection::In; if (direction == QLatin1String("access")) { // Oops, we have to improvise here because there // is no such thing as "access" in UML. // So we use the next best thing, "inout". // Better ideas, anyone? dir = Uml::ParameterDirection::InOut; typeName = advance(); } else if (direction == QLatin1String("in")) { if (m_source[m_srcIndex + 1] == QLatin1String("out")) { dir = Uml::ParameterDirection::InOut; m_srcIndex++; } typeName = advance(); } else if (direction == QLatin1String("out")) { dir = Uml::ParameterDirection::Out; typeName = advance(); } else { typeName = direction; // In Ada, the default direction is "in" } typeName.remove(QLatin1String("Standard."), Qt::CaseInsensitive); typeName = expand(typeName); if (op == NULL) { // In Ada, the first parameter indicates the class. UMLObject *type = Import_Utils::createUMLObject(UMLObject::ot_Class, typeName, currentScope()); UMLObject::ObjectType t = type->baseType(); if ((t != UMLObject::ot_Interface && (t != UMLObject::ot_Class || type->stereotype() == QLatin1String("record"))) || !m_classesDefinedInThisScope.contains(type)) { // Not an instance bound method - we cannot represent it. skipStmt(QLatin1String(")")); break; } klass = static_cast<UMLClassifier*>(type); op = Import_Utils::makeOperation(klass, name); // The controlling parameter is suppressed. parNameCount--; if (parNameCount) { for (uint i = 0; i < parNameCount; ++i) { parName[i] = parName[i + 1]; } } } for (uint i = 0; i < parNameCount; ++i) { UMLAttribute *att = Import_Utils::addMethodParameter(op, typeName, parName[i]); att->setParmKind(dir); } if (advance() != QLatin1String(";")) break; } if (keyword == QLatin1String("function")) { if (advance() != QLatin1String("return")) { if (klass) uError() << "importAda: expecting \"return\" at function " << name; return false; } returnType = expand(advance()); returnType.remove(QLatin1String("Standard."), Qt::CaseInsensitive); } bool isAbstract = false; if (advance() == QLatin1String("is") && advance() == QLatin1String("abstract")) isAbstract = true; if (klass != NULL && op != NULL) Import_Utils::insertMethod(klass, op, m_currentAccess, returnType, false, isAbstract, false, false, m_comment); skipStmt(); return true; } if (keyword == QLatin1String("task") || keyword == QLatin1String("protected")) { // Can task and protected objects/types be mapped to UML? QString name = advance(); if (name == QLatin1String("type")) { name = advance(); } QString next = advance(); if (next == QLatin1String("(")) { skipStmt(QLatin1String(")")); // skip discriminant next = advance(); } if (next == QLatin1String("is")) skipStmt(QLatin1String("end")); skipStmt(); return true; } if (keyword == QLatin1String("for")) { // rep spec QString typeName = advance(); QString next = advance(); if (next == QLatin1String("'")) { advance(); // skip qualifier next = advance(); } if (next == QLatin1String("use")) { if (advance() == QLatin1String("record")) skipStmt(QLatin1String("end")); } else { uError() << "importAda: expecting \"use\" at rep spec of " << typeName; } skipStmt(); return true; } // At this point we're only interested in attribute declarations. if (m_klass == NULL || keyword == QLatin1String("null")) { skipStmt(); return true; } const QString& name = keyword; if (advance() != QLatin1String(":")) { uError() << "adaImport: expecting \":\" at " << name << " " << m_source[m_srcIndex]; skipStmt(); return true; } QString nextToken = advance(); if (nextToken == QLatin1String("aliased")) nextToken = advance(); QString typeName = expand(nextToken); QString initialValue; if (advance() == QLatin1String(":=")) { initialValue = advance(); QString token; while ((token = advance()) != QLatin1String(";")) { initialValue.append(QLatin1Char(' ') + token); } } UMLObject *o = Import_Utils::insertAttribute(m_klass, m_currentAccess, name, typeName, m_comment); if (o) { UMLAttribute *attr = static_cast<UMLAttribute*>(o); attr->setInitialValue(initialValue); } skipStmt(); return 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; }