void UmlClass::importRelations(File & f) { Q3CString s; f.read("("); f.read("list"); if (f.read(s) != ATOM) f.syntaxError(s, "an atom"); for (;;) { switch (f.read(s)) { case ')': return; case '(': break; default: f.syntaxError(s); } f.read("object"); if (f.read(s) != ATOM) f.syntaxError(s, "an atom"); aRelationKind rk; Q3CString sr; if (s == "Uses_Relationship") { rk = aDependency; sr = "dependency"; } else if (s == "Inheritance_Relationship") { rk = aGeneralisation; sr = "generalisation"; } else if (s == "Realize_Relationship") { rk = aRealization; sr = "realization"; } else { f.skipBlock(); continue; } // dependency or generalisation Q3CString id; Q3CString ste; Q3CString doc; Q3Dict<Q3CString> prop; Q3CString s2; int k; do { k = f.readDefinitionBeginning(s2, id, ste, doc, prop); } while (id.isEmpty()); Q3CString target_id; aVisibility visibility = PublicVisibility; bool virtual_inheritance = FALSE; bool a_friend = FALSE; for (;;) { if (k == ATOM) { if (s2 == "quidu") { if (f.read(target_id) != STRING) f.syntaxError(target_id, "quidu value"); } else if (s2 == "exportControl") visibility = f.readVisibility(); else if (s2 == "virtual") virtual_inheritance = f.readBool(); else if (s2 == "friend") a_friend = f.readBool(); else f.skipNextForm(); k = f.read(s2); } else if (k == ')') break; else f.syntaxError(s2); } if (target_id.isEmpty()) f.syntaxError("quidu missing"); UmlClass * target = (UmlClass *) findItem(target_id, aClass); if (target != 0) { UmlRelation * r; if (a_friend) { if ((r = UmlRelation::create(rk, target, this)) == 0) { UmlCom::trace("<br>cannot create " + sr + " from '" + target->fullName() + "' to '" + fullName() + "'"); f.skipBlock(); return; } r->set_Stereotype("friend"); } else { if ((r = UmlRelation::create(rk, this, target)) == 0) { UmlCom::trace("<br>cannot create " + sr + " from '" + fullName() + "' to '" + target->fullName() + "'"); f.skipBlock(); return; } if (!ste.isEmpty()) r->set_Stereotype(ste); if (visibility != PublicVisibility) r->set_Visibility(visibility); if (virtual_inheritance) r->set_CppVirtualInheritance(TRUE); } newItem(r, id); if (!doc.isEmpty()) r->set_Description(doc); r->setProperties(prop); } } }
void UmlRelation::set_unidir() { UmlRelation * r1 = side(TRUE); UmlRelation * r2 = (r1 != this) ? this : side(FALSE); if (r1->isReadOnly() || r2->isReadOnly()) { UmlCom::trace(Q3CString("<font face=helvetica>in <i>") + Q3CString(Lex::filename().toAscii().constData()) + "</i> line " + Q3CString().setNum(Lex::line_number()) + " <b>cannot remove relation between classes <i>" + roleType()->name() + "</i> and <i>" + parent()->name() + "</i> because one is read only</b></font><br>"); throw 0; } aRelationKind k; switch (relationKind()) { case anAssociation: k = aDirectionalAssociation; break; case anAggregation: k = aDirectionalAggregation; break; default: k = aDirectionalAggregationByValue; } if (this == r1) set_rel_kind(k); else { UmlRelation * rel = UmlBaseRelation::create(aDirectionalAssociation, (UmlClass *) parent(), roleType()); Q3CString role = roleName(); rel->moveAfter(this); rel->set_Visibility(visibility()); if (!description().isEmpty()) rel->set_Description(description()); if (isReadOnly()) rel->set_isReadOnly(TRUE); if (isVolatile()) rel->set_isVolatile(TRUE); if (isClassMember()) rel->set_isClassMember(TRUE); if (!multiplicity().isEmpty()) rel->set_Multiplicity(multiplicity()); if (!defaultValue().isEmpty()) rel->set_DefaultValue(defaultValue()); if (!stereotype().isEmpty()) rel->set_Stereotype(stereotype()); rel->set_CppDecl(cppDecl()); rel->set_CppVisibility(cppVisibility()); if (cppVirtualInheritance()) rel->set_CppVirtualInheritance(TRUE); if (isCppMutable()) rel->set_isCppMutable(TRUE); UmlOperation * op; UmlOperation * oper; if (((op = getOperation()) != 0) && rel->addGetOperation() && ((oper = rel->getOperation()) != 0)) copy(op, oper); if (((op = setOperation()) != 0) && rel->addSetOperation() && ((oper = rel->getOperation()) != 0)) copy(op, oper); r1->deleteIt(); r2->deleteIt(); rel->set_RoleName(role); } }
bool UmlClass::manage_inherit(ClassContainer * container, const QList<FormalParameterList> & tmplts #ifdef REVERSE , bool libp # ifdef ROUNDTRIP , bool roundtrip, QList<UmlItem *> & expected_order , bool container_roundtrip, QList<UmlItem *> & container_expected_order # endif #endif ) { #ifdef DEBUG_DOUML QLOG_INFO() << name() << "->manage_inherit()\n"; #endif WrapperStr s = Lex::read_word(TRUE); while (s != "{") { #ifdef DEBUG_DOUML QLOG_INFO() << "Class::manage_inherit, visibility : " << s << '\n'; #endif bool is_virtual; if (s == "virtual") { is_virtual = TRUE; s = Lex::read_word(TRUE); } else is_virtual = FALSE; aVisibility v; if (s == "public") { v = PublicVisibility; s = Lex::read_word(TRUE); } else if (s == "protected") { v = ProtectedVisibility; s = Lex::read_word(TRUE); } else if (s == "private") { v = PrivateVisibility; s = Lex::read_word(TRUE); } else v = PrivateVisibility; if (s.isEmpty()) { Lex::premature_eof(); return FALSE; } #ifdef DEBUG_DOUML QLOG_INFO() << "UmlClass::manage_inherit, mother : " << s << '\n'; #endif WrapperStr mother_name = s; UmlTypeSpec mother; WrapperStr typeform; UmlRelation * rel = 0; #ifdef ROUNDTRIP bool is_new = TRUE; #endif container->compute_type(s, mother, typeform); s = Lex::read_word(); if (s == "<") { Lex::mark(); // goes up to the corresponding '>' WrapperStr after_gt; Lex::finish_template(after_gt); s = Lex::read_word(TRUE); if (*s == ':') { // inherits 'T<...>::...' // don't try to solve, use a typedef named 'Type_<n>' based on T<...>::... // creating this typedef if it doesn't yet exist mother_name += "<" + Lex::region(); mother.type = 0; // made below s = Lex::read_word(); } else if (mother.type == 0) { mother_name += "<" + after_gt; } else { // inherits T<...> #ifdef ROUNDTRIP is_new = !roundtrip || ((rel = search_for_inherit(mother.type)) == 0); #endif mother_name += "<" + after_gt; Lex::come_back(); // must add inheritance before setting actuals if ( #ifdef ROUNDTRIP is_new && ( #endif (rel = UmlBaseRelation::create(aRealization, this, mother.type)) == 0 #ifdef ROUNDTRIP ) #endif ) { Lex::warn("cannot inherit <font color =\"red\">" + Lex::quote(mother_name) + " </font>"); #ifdef DEBUG_DOUML QLOG_INFO() << "cannot create <|---\n"; #endif return FALSE; } else if (!get_actuals(mother.type, container, tmplts #ifdef ROUNDTRIP , !is_new #endif )) return FALSE; #ifdef ROUNDTRIP if (! is_new) { if (neq(rel->stereotype(), "bind")) { rel->set_Stereotype("bind"); the_class->set_updated(); } } else #endif rel->set_Stereotype("bind"); s = Lex::read_word(); } } if (mother.type == 0) { mother.type = auxilarily_typedef(mother_name #ifdef REVERSE , libp # ifdef ROUNDTRIP , container_roundtrip , container_expected_order # endif #endif ); if (mother.type == 0) return FALSE; } #ifdef ROUNDTRIP if (rel == 0) is_new = !roundtrip || ((rel = search_for_inherit(mother.type)) == 0); #endif if ((rel == 0) && ((rel = UmlBaseRelation::create(aGeneralisation, this, mother.type)) == 0)) { Lex::warn("cannot inherit <font color =\"red\">" + Lex::quote(mother_name) + " </font>"); #ifdef DEBUG_DOUML QLOG_INFO() << "cannot create <|---\n"; #endif return FALSE; } #ifdef ROUNDTRIP expected_order.append(rel); if (!is_new) { rel->set_usefull(); if (neq(rel->cppDecl(), "${type}")) { rel->set_CppDecl("${type}"); the_class->set_updated(); } if (rel->visibility() != v) { rel->set_Visibility(v); the_class->set_updated(); } if (is_virtual != rel->cppVirtualInheritance()) { rel->set_CppVirtualInheritance(is_virtual); the_class->set_updated(); } } else { #elif defined(REVERSE) Statistic::one_relation_more(); #endif rel->set_CppDecl("${type}"); rel->set_Visibility(v); if (is_virtual) rel->set_CppVirtualInheritance(TRUE); #ifdef ROUNDTRIP } #endif if (s == ",") s = Lex::read_word(); } Lex::unread_word(); // '{' return TRUE; }