void UmlClass::gen_python_decl(QByteArray s, bool descr) { QByteArray st = PythonSettings::classStereotype(stereotype()); if (st == "ignored") return; const char * p = bypass_comment(s); while (*p != 0) { if (!strncmp(p, "${comment}", 10)) p += 10; else if (!strncmp(p, "${description}", 14)) p += 14; else if (!strncmp(p, "${docstring}", 12)) p += 12; else if (!strncmp(p, "${name}", 7)) { p += 7; writeq(name()); } else if (!strncmp(p, "${inherit}", 10)) { p += 10; const QVector<UmlItem*> ch = children(); bool inh = FALSE; for (int i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if (((k == aGeneralisation) || (k == aRealization)) && !rel->pythonDecl().isEmpty()) { if (inh) fw.write(", "); else { inh = TRUE; fw.write('('); } rel->roleType()->write(); } } } if (inh) fw.write(')'); else if (isPython_2_2()) fw.write("(object)"); break; } else if (!descr && ((*p == '\r') || (*p == '\n') || (*p == ':'))) break; else if (*p == '@') manage_alias(p); else writeq(*p++); } }
void UmlClass::importInstantiate(File & f) { if (scanning) { f.skipNextForm(); return; } f.read("("); f.read("object"); f.read("Instantiation_Relationship"); 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()); for (;;) { if (k == ATOM) { if (s2 == "quidu") break; f.skipNextForm(); k = f.read(s2); } else f.syntaxError(s2); } if (f.read(s2) != STRING) f.syntaxError(s2, "quidu value"); UmlClass * target = (UmlClass *) findItem(s2, aClass); if (target != 0) { UmlRelation * r = UmlRelation::create(aRealization, this, target); if (r == 0) UmlCom::trace("<br>cannot create aRealization from '" + fullName() + "' to '" + target->fullName() + "'"); else { newItem(r, id); if (!ste.isEmpty()) r->set_Stereotype(ste); if (!doc.isEmpty()) r->set_Description(doc); r->setProperties(prop); } } f.skipBlock(); }
bool UmlRelation::new_friend(Class * container, UmlClass * to, Q3PtrList<UmlItem> & expected_order) { UmlClass * from = container->get_uml(); #ifdef DEBUG_BOUML cout << "FRIEND from '" << from->name() << "' to '" << to->name() << "'\n"; #endif const Q3PtrVector<UmlItem> & ch = from->children(); UmlItem ** v = ch.data(); UmlItem ** const vsup = v + ch.size(); for (;v != vsup; v += 1) { if (((*v)->kind() == aRelation) && (((UmlRelation *) *v)->relationKind() == aDependency) && (((UmlRelation *) *v)->roleType() == to) && !neq((*v)->stereotype(), "friend")) { expected_order.append(*v); ((UmlRelation *) *v)->set_usefull(); return TRUE; } } // relation not found UmlRelation * rel = UmlBaseRelation::create(aDependency, from, to); if (rel == 0) { UmlCom::trace(Q3CString("<font face=helvetica><b>cannot add friend relation in <i>") + from->name() + "</i> to <i>" + to->name() + "</i></b></font><br><hr><br>"); return FALSE; } expected_order.append(rel); container->set_updated(); rel->set_CppDecl("Generated"); return rel->set_Stereotype("friend"); }
void UmlClass::memo_ref() { classes.addElement(this); UmlItem::memo_ref(); const QVector<UmlItem> ch = children(); if (inherited_opers == 0) add_inherited_opers(0); for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if ((k == aGeneralisation) || (k == aRealization)) rel->roleType()->subClasses.addElement(this); } } unload(TRUE, FALSE); }
void UmlClass::add_inherited_opers(Vector * ops) { if (inherited_opers == 0) { const QVector<UmlItem*> ch = children(); inherited_opers = new Vector; for (int i = 0; i != ch.size(); i += 1) { switch (ch[i]->kind()) { case aRelation: { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if ((k == aGeneralisation) || (k == aRealization)) rel->roleType()->add_inherited_opers(inherited_opers); } break; case anOperation: { UmlOperation * op = (UmlOperation *) ch[i]; if ((op->visibility() == PublicVisibility) && (op->name()[0] != '~') && (op->name() != name())) inherited_opers->addElement(op); } default: break; } } } if (ops != 0) for (unsigned i = 0; i != inherited_opers->size(); i += 1) if (! ops->contains(inherited_opers->elementAt(i))) ops->addElement(inherited_opers->elementAt(i)); unload(TRUE, FALSE); }
bool UmlRelation::new_friend(UmlClass * from, UmlClass * to) { #ifdef DEBUG_BOUML cout << "FRIEND from '" << from->name() << "' to '" << to->name() << "'\n"; #endif UmlRelation * rel = UmlBaseRelation::create(aDependency, from, to); if (rel == 0) { UmlCom::trace(Q3CString("<font face=helvetica><b>cannot add friend relation in <i>") + from->name() + "</i> to <i>" + to->name() + "</i></b></font><br><hr><br>"); return FALSE; } #ifndef ROUNDTRIP Statistic::one_relation_more(); #endif rel->set_CppDecl("Generated"); return rel->set_Stereotype("friend"); }
bool UmlClass::bind(UmlClass * tmpl) { const Q3PtrVector<UmlItem> ch = children(); unsigned int n = ch.size(); int i; for (i = 0; i != (int) n; i += 1) { if ((ch[i]->kind() == aRelation) && (((UmlRelation *) ch[i])->roleType() == tmpl)) { switch (((UmlRelation *) ch[i])->relationKind()) { case aRealization: ((UmlRelation *) ch[i])->set_Stereotype("bind"); // no break case aGeneralisation: return TRUE; default: break; } } } // add realization UmlRelation * r = UmlRelation::create(aRealization, this, tmpl); if (r == 0) { UmlCom::trace("class reference '" + id() + "' can't realize class reference '" + tmpl->id() + "'<br>"); return FALSE; } r->set_Stereotype("bind"); return TRUE; }
bool Class::add_inherit(aRelationKind k, UmlTypeSpec & typespec) { UmlRelation * rel = UmlRelation::create(k, uml, typespec.type); if (rel == 0) { #ifdef TRACE QLOG_INFO() << "cannot create <|---\n"; #endif return FALSE; } #ifdef REVERSE Statistic::one_relation_more(); #endif if (!typespec.explicit_type.isEmpty()) rel->set_PhpDecl(typespec.explicit_type); else { rel->set_PhpDecl("${type}"); } return TRUE; }
void UmlClass::gen_php_decl(QCString s, bool descr) { QCString st = PhpSettings::classStereotype(stereotype()); if (st == "ignored") return; const char * p = bypass_comment(s); UmlRelation * extend = 0; while (*p != 0) { if (!strncmp(p, "${comment}", 10)) p += 10; else if (!strncmp(p, "${description}", 14)) p += 14; else if (!strncmp(p, "${visibility}", 13)) { p += 13; UmlItem::write(visibility(), phpLanguage); fw.write(' '); } else if (!strncmp(p, "${final}", 8)) { p += 8; if (isPhpFinal()) fw.write("final "); } else if (!strncmp(p, "${abstract}", 11)) { p += 11; if (isAbstract()) fw.write("abstract "); } else if (!strncmp(p, "${name}", 7)) { p += 7; writeq(name()); generics(); } else if (!strncmp(p, "${extends}", 10)) { p += 10; const QVector<UmlItem> ch = children(); for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if (((k == aGeneralisation) || (k == aRealization)) && (!rel->phpDecl().isEmpty()) && ((st == "interface") || (PhpSettings::classStereotype(rel->roleType()->stereotype()) != "interface"))) { extend = rel; fw.write(" extends "); rel->roleType()->write(); break; } } } } else if (!strncmp(p, "${implements}", 13)) { p += 13; const QVector<UmlItem> ch = children(); const char * sep = " implements "; for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if ((rel != extend) && ((k == aGeneralisation) || (k == aRealization)) && (!rel->phpDecl().isEmpty())) { fw.write(sep); sep = ", "; rel->roleType()->write(); } } } } else if (*p == '\r') p += 1; else if (*p == '\n') { if (descr) { fw.write("<br />"); p += 1; } else { fw.write(' '); do p += 1; while ((*p != 0) && (*p <= ' ')); } } else if ((*p == '{') || (*p == ';')) { if (descr) fw.write(*p++); else break; } else if (*p == '@') manage_alias(p); else writeq(*p++); } }
void UmlRelation::import(File & f) { if (scanning) f.skipBlock(); else { Q3CString s; if (f.read(s) != STRING) f.syntaxError(s, "relation's name"); else if (*s == '$') // unnamed s = ""; 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()); for (;;) { if (k == ATOM) { if (s2 == "roles") break; f.skipNextForm(); k = f.read(s2); } else f.syntaxError(s); } f.read("("); f.read("list"); f.read("role_list"); Role role_1; Role role_2; Role * role1 = &role_1; Role * role2 = &role_2; role_1.import(f); role_2.import(f); UmlRelation * r = 0; bool bidir = role_1.is_navigable && role_2.is_navigable; // place information in the logical side ! bool b = role_1.is_aggregate; role_1.is_aggregate = role_2.is_aggregate; role_2.is_aggregate = b; role_1.is_aggregate |= role_1.is_byvalue; role_2.is_aggregate |= role_2.is_byvalue; if (bidir && role_2.is_aggregate) { // manage bouml limitation : only role1 may be an aggregate if (role_1.is_aggregate) bidir = FALSE; else { // exchange roles role1 = &role_2; role2 = &role_1; } } if ((role1->target != 0) && (role2->target != 0)) { if (role1->is_navigable) { r = UmlRelation::create(role1->rel_kind(bidir), role2->target, role1->target); if (r == 0) { UmlCom::trace("<br>cannot create relation '" + role1->name + "' from '" + role2->target->fullName() + "' to '" + role1->target->fullName() + "'"); f.read(")"); f.skipBlock(); return; } if (!ste.isEmpty()) r->set_Stereotype(ste); if (! s.isEmpty()) r->set_Name(s); r->import(role1); } if (role2->is_navigable) { if (bidir) { const Q3PtrVector<UmlItem> ch = role2->target->children(); r = (UmlRelation *) ch.at(ch.count() - 1); } else { r = UmlRelation::create(role2->rel_kind(FALSE),role1->target, role2->target); if (r == 0) { UmlCom::trace("<br>cannot create relation '" + role2->name + "' from '" + role1->target->fullName() + "' to '" + role2->target->fullName() + "'"); f.read(")"); f.skipBlock(); return; } if (!ste.isEmpty()) r->set_Stereotype(ste); if (! s.isEmpty()) r->set_Name(s); } r->import(role2); } } f.read(")"); f.skipBlock(); } }
void UmlRelation::write_relation_as_attribute(FileOut & out) { UmlRelation * first = side(TRUE); Q3CString s; UmlClass * base; if ((first->parent()->stereotype() == "stereotype") && (first->roleType()->stereotype() == "metaclass")) { if (this != first) return; base = first->roleType(); s = "base_" + base->name(); } else { base = 0; switch (_lang) { case Uml: s = roleName(); break; case Cpp: if (cppDecl().isEmpty()) return; s = true_name(roleName(), cppDecl()); break; default: // Java if (javaDecl().isEmpty()) return; s = true_name(roleName(), javaDecl()); } } out.indent(); out << "<ownedAttribute xmi:type=\"uml:Property\" name=\"" << s << '"'; out.id(this); if (base != 0) out.ref(first, "association", "EXT_"); else { write_visibility(out); write_scope(out); if (isReadOnly()) out << " isReadOnly=\"true\""; if (isDerived()) { out << " isDerived=\"true\""; if (isDerivedUnion()) out << " isDerivedUnion=\"true\""; } if (isOrdered()) out << " isOrdered=\"true\""; if (isUnique()) out << " isUnique=\"true\""; if (first->_assoc_class != 0) out.ref(first->_assoc_class, "association"); else out.ref(first, "association", "ASSOC_"); out << " aggregation=\""; if (this == first) { parent()->memo_relation(this); if (_gen_eclipse) { switch (relationKind()) { case anAggregation: case aDirectionalAggregation: out << "shared"; break; case anAggregationByValue: case aDirectionalAggregationByValue: out << "composite"; break; default: out << "none"; } } else out << "none"; } else if (_gen_eclipse) out << "none"; else { switch (relationKind()) { case anAggregation: case aDirectionalAggregation: out << "shared"; break; case anAggregationByValue: case aDirectionalAggregationByValue: out << "composite"; break; default: out << "none"; } } out << '"'; } out << ">\n"; out.indent(+1); out.indent(); out << "<type xmi:type=\"uml:Class\""; if (base != 0) { if (! base->propertyValue("metaclassPath", s)) s = (_uml_20) ? "http://schema.omg.org/spec/UML/2.0/uml.xml" : "http://schema.omg.org/spec/UML/2.1/uml.xml"; out << " href=\"" << s << '#' << base->name() << '"'; } else out.idref(roleType()); out << "/>\n"; write_multiplicity(out, multiplicity(), this); write_default_value(out, defaultValue(), this); write_constraint(out); write_annotation(out); write_description_properties(out); out.indent(-1); out.indent(); out << "</ownedAttribute>\n"; unload(); }
void UmlRelation::set_unidir() { UmlRelation * r1 = side(TRUE); UmlRelation * r2 = (r1 != this) ? this : side(FALSE); if (r1->isReadOnly() || r2->isReadOnly()) { UmlCom::trace(WrapperStr("<font face=helvetica>in <i>") + WrapperStr(Lex::filename().toAscii().constData()) + "</i> line " + WrapperStr().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()); WrapperStr role = roleName(); rel->moveAfter(this); rel->set_Visibility(visibility()); if (!description().isEmpty()) rel->set_Description(description()); if (isReadOnly()) rel->set_isReadOnly(TRUE); if (isJavaTransient()) rel->set_isJavaTransient(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 (!javaAnnotations().isEmpty()) rel->set_JavaAnnotations(javaAnnotations()); if (!stereotype().isEmpty()) rel->set_Stereotype(stereotype()); rel->set_JavaDecl(javaDecl()); 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); } }
// not from a form 'generic<...C...> var' where C is a class bool UmlRelation::new_one(Class * container, const WrapperStr & name, UmlTypeSpec & dest, WrapperStr str_actuals, aVisibility visibility, bool staticp, bool constp, bool transientp, bool volatilep, const WrapperStr & array, const WrapperStr & value, WrapperStr comment, WrapperStr description, WrapperStr annotation #ifdef ROUNDTRIP , bool roundtrip, QList<UmlItem *> & expected_order #endif ) { #ifdef TRACE QLOG_INFO() << "RELATION '" << name << "' from '" << cl->Name() << "' to '" << dest.type->Name() << "' array '" << array << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } UmlClass * cl = container->get_uml(); UmlRelation * rel; #ifdef ROUNDTRIP bool created; if (!roundtrip || ((rel = search_rel(container, name, dest.type, "")) == 0)) { #endif rel = UmlBaseRelation::create(aDirectionalAssociation, cl, dest.type); if (rel == 0) { JavaCatWindow::trace(WrapperStr("<font face=helvetica><b>cannot add relation <i>") + name + "</i> in <i>" + cl->name() + "</i> to <i>" + dest.type->name() + "</i></b></font><br>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_relation_more(); # else if (roundtrip) container->set_updated(); created = TRUE; } else created = FALSE; # endif #endif WrapperStr decl = JavaSettings::relationDecl(array); UmlClass::manage_generic(decl, dest, str_actuals, "${type}"); Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); #ifdef ROUNDTRIP if (roundtrip && !created) { if (rel->visibility() != visibility) { rel->set_Visibility(visibility); container->set_updated(); } if (decl.find("${description}") != -1) { if (nequal(rel->description(), description)) { rel->set_Description(description); container->set_updated(); } } else if (nequal(rel->description(), Lex::simplify_comment(comment))) { rel->set_Description(comment); // comment was set container->set_updated(); } if (rel->isReadOnly() != constp) { rel->set_isReadOnly(constp); container->set_updated(); } if (rel->isJavaTransient() != transientp) { rel->set_isJavaTransient(transientp); container->set_updated(); } if (rel->isVolatile() != volatilep) { rel->set_isVolatile(volatilep); container->set_updated(); } if (rel->isClassMember() != staticp) { rel->set_isClassMember(staticp); container->set_updated(); } if (neq(rel->multiplicity(), array)) { rel->set_Multiplicity(array); container->set_updated(); } WrapperStr v = rel->defaultValue(); if (!v.isEmpty() && (((const char *) v)[0] == '=')) v = v.mid(1); if (nequal(v, value)) { rel->set_DefaultValue(value); container->set_updated(); } if (nequal(rel->javaAnnotations(), annotation)) { rel->set_JavaAnnotations(annotation); container->set_updated(); } if (neq(rel->javaDecl(), decl)) { rel->set_JavaDecl(decl); container->set_updated(); } rel->set_usefull(); expected_order.append(rel); } else { #endif rel->set_Visibility(visibility); if (!comment.isEmpty()) rel->set_Description((decl.find("${description}") != -1) ? description : comment); if (constp) rel->set_isReadOnly(TRUE); if (transientp) rel->set_isJavaTransient(TRUE); if (volatilep) rel->set_isVolatile(TRUE); if (staticp) rel->set_isClassMember(TRUE); if (!array.isEmpty()) rel->set_Multiplicity(array); if (! value.isEmpty()) rel->set_DefaultValue(value); if (! annotation.isEmpty()) rel->set_JavaAnnotations(annotation); rel->set_JavaDecl(decl); rel->set_RoleName(name); #ifdef ROUNDTRIP if (roundtrip) expected_order.append(rel); } #endif return TRUE; }
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; }
bool UmlRelation::new_one(Class * container, const Q3CString & name, UmlClass * dest, const Q3CString & modifier, const Q3CString & pretype, const Q3CString & array, const Q3CString & typeform, aVisibility visibility, bool staticp, bool constp, bool mutablep, bool volatilep, const Q3CString & value, Q3CString comment, Q3CString description #ifdef ROUNDTRIP , bool roundtrip, Q3PtrList<UmlItem> & expected_order #endif ) { #ifdef DEBUG_BOUML cout << "RELATION '" << name << "' from '" << cl->name() << "' to '" << dest->name() << "' modifier '" << modifier << "' array '" << array << "' typeform '" << typeform << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } UmlClass * cl = container->get_uml(); UmlRelation * rel; #ifdef ROUNDTRIP if (roundtrip && ((rel = search_rel(container, name, dest, "")) != 0)) { rel->set_usefull(); expected_order.append(rel); } else { #endif rel = UmlBaseRelation::create((modifier.isEmpty() && ((typeform == "${type}") || (typeform[typeform.find("${type}") + 7] != '*'))) ? aDirectionalAggregationByValue : aDirectionalAssociation, cl, dest); if (rel == 0) { UmlCom::trace(Q3CString("<font face=helvetica><b>cannot add relation <i>") + name + "</i> in <i>" + cl->name() + "</i> to <i>" + dest->name() + "</i></b></font><br><hr>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_relation_more(); # else if (roundtrip) { expected_order.append(rel); container->set_updated(); roundtrip = FALSE; } } # endif #endif Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); #ifdef ROUNDTRIP if (roundtrip) { if (rel->visibility() != visibility) { rel->set_Visibility(visibility); container->set_updated(); } if (rel->isReadOnly() != constp) { rel->set_isReadOnly(constp); container->set_updated(); } if (rel->isClassMember() != staticp) { rel->set_isClassMember(staticp); container->set_updated(); } if (rel->isCppMutable() != mutablep) { rel->set_isCppMutable(mutablep); container->set_updated(); } if (rel->isVolatile() != volatilep) { rel->set_isVolatile(volatilep); container->set_updated(); } } else { #endif rel->set_Visibility(visibility); if (constp) rel->set_isReadOnly(TRUE); if (staticp) rel->set_isClassMember(TRUE); if (mutablep) rel->set_isCppMutable(TRUE); if (volatilep) rel->set_isVolatile(TRUE); #ifdef ROUNDTRIP } #endif Q3CString decl; if (typeform != "${type}") { // array & modified are empty, pretype is empty ? decl = CppSettings::relationDecl(TRUE, "*"); int index = typeform.find("<"); // cannot be -1 Q3CString st = typeform.left(index); Q3CString st_uml = CppSettings::umlType(st); #ifdef ROUNDTRIP if (roundtrip) { if (st_uml.isEmpty()) st_uml = st; if (neq(rel->stereotype(), st_uml)) { rel->set_Stereotype(st_uml); container->set_updated(); } } else #endif rel->set_Stereotype((st_uml.isEmpty()) ? st : st_uml); int index2; if ((index2 = decl.find("<${type}>")) == -1) { decl = " ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type}> ${name}${value};"; index2 = decl.find("<${type}>"); } decl.replace(index2, 9, typeform.mid(index)); } else { if (!array.isEmpty()) { #ifdef ROUNDTRIP if (roundtrip) { if (neq(rel->multiplicity(), array)) { rel->set_Multiplicity(array); container->set_updated(); } } else #endif rel->set_Multiplicity(array); } decl = CppSettings::relationDecl(modifier != "*", array); int index; if (!pretype.isEmpty() && ((index = decl.find("${type}")) != 0)) decl.insert(index,(const char*)( pretype + " ")); if ((modifier == "&") && ((index = decl.find("${type}")) != 0)) decl.insert(index + 7, " &"); } if (! value.isEmpty()) { int index = decl.find("${value}"); if (index != -1) decl.insert(index + 2, "h_"); #ifdef ROUNDTRIP if (roundtrip) { if (!staticp) { Q3CString v = rel->defaultValue(); if (!v.isEmpty() && (((const char *) v)[0] == '=')) v = v.mid(1); if (nequal(v, value)) { rel->set_DefaultValue(value); container->set_updated(); } } } else #endif rel->set_DefaultValue(value); } #ifdef ROUNDTRIP if (roundtrip) { if (neq(rel->cppDecl(), decl)) { rel->set_CppDecl(decl); container->set_updated(); } if (decl.find("${description}") != -1) { if (nequal(rel->description(), description)) { rel->set_Description(description); container->set_updated(); } } else if (nequal(rel->description(), Lex::simplify_comment(comment))) { rel->set_Description(comment); // comment was set container->set_updated(); } // role name is the right one return TRUE; } #endif rel->set_CppDecl(decl); if (!comment.isEmpty()) rel->set_Description((decl.find("${description") != -1) ? description : Lex::simplify_comment(comment)); return rel->set_RoleName(name); }
// from a form 'generic<...C...> var' where C is a class bool UmlRelation::new_one(Class * container, const QCString & name, UmlClass * type, QCString type_def, QCString genericname, aVisibility visibility, bool staticp, bool constp, bool transientp, bool volatilep, const QCString & array, const QCString & value, QCString comment, QCString description, QCString annotation #ifdef ROUNDTRIP , bool roundtrip, QList<UmlItem> & expected_order #endif ) { #ifdef TRACE cout << "RELATION '" << name << "' from '" << cl->Name() << "' to '" << type->Name() << "' array '" << array << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } QCString st = JavaSettings::umlType(genericname); if (st.isEmpty()) st = genericname; UmlClass * cl = container->get_uml(); UmlRelation * rel; #ifdef ROUNDTRIP bool created; if (!roundtrip || ((rel = search_rel(container, name, type, st)) == 0)) { #endif rel = UmlBaseRelation::create(aDirectionalAssociation, cl, type); if (rel == 0) { JavaCatWindow::trace(QCString("<font face=helvetica><b>cannot add relation <i>") + name + "</i> in <i>" + cl->name() + "</i> to <i>" + type->name() + "</i></b></font><br>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_relation_more(); # else if (roundtrip) container->set_updated(); created = TRUE; } else created = FALSE; # endif #endif Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); QCString decl = JavaSettings::relationDecl(array); type_def.replace(0, genericname.length(), "${stereotype}"); decl.replace(decl.find("${type}"), 7, type_def); #ifdef ROUNDTRIP if (roundtrip && !created) { if (rel->visibility() != visibility) { rel->set_Visibility(visibility); container->set_updated(); } if (decl.find("${description}") != -1) { if (nequal(rel->description(), description)) { rel->set_Description(description); container->set_updated(); } } else if (nequal(rel->description(), Lex::simplify_comment(comment))) { rel->set_Description(comment); // comment was set container->set_updated(); } if (rel->isReadOnly() != constp) { rel->set_isReadOnly(constp); container->set_updated(); } if (rel->isJavaTransient() != transientp) { rel->set_isJavaTransient(transientp); container->set_updated(); } if (rel->isVolatile() != volatilep) { rel->set_isVolatile(volatilep); container->set_updated(); } if (rel->isClassMember() != staticp) { rel->set_isClassMember(staticp); container->set_updated(); } if (neq(rel->multiplicity(), array)) { rel->set_Multiplicity(array); container->set_updated(); } if (neq(rel->defaultValue(), value)) { rel->set_DefaultValue(value); container->set_updated(); } if (nequal(rel->javaAnnotations(), annotation)) { rel->set_JavaAnnotations(annotation); container->set_updated(); } if (neq(rel->stereotype(), st) && (rel->stereotype().isEmpty() || (JavaSettings::relationAttributeStereotype(rel->stereotype()) != st))) { rel->set_Stereotype(st); container->set_updated(); } if (neq(rel->javaDecl(), decl)) { rel->set_JavaDecl(decl); container->set_updated(); } // role name is the right one rel->set_usefull(); expected_order.append(rel); } else { #endif rel->set_Visibility(visibility); if (!comment.isEmpty()) rel->set_Description((decl.find("${description}") != -1) ? description : Lex::simplify_comment(comment)); if (constp) rel->set_isReadOnly(TRUE); if (transientp) rel->set_isJavaTransient(TRUE); if (volatilep) rel->set_isVolatile(TRUE); if (staticp) rel->set_isClassMember(TRUE); if (!array.isEmpty()) rel->set_Multiplicity(array); if (! value.isEmpty()) rel->set_DefaultValue(value); if (! annotation.isEmpty()) rel->set_JavaAnnotations(annotation); rel->set_Stereotype(st); rel->set_JavaDecl(decl); rel->set_RoleName(name); #ifdef ROUNDTRIP if (roundtrip) expected_order.append(rel); } #endif return TRUE; }
void UmlClass::gen_java_decl(QByteArray s, bool descr) { const char * p = bypass_comment(s); UmlRelation * extend = 0; while (*p != 0) { if (!strncmp(p, "${comment}", 10)) p += 10; else if (!strncmp(p, "${description}", 14)) p += 14; else if (!strncmp(p, "${public}", 9)) { p += 9; if (isJavaPublic()) fw.write("public "); } else if (!strncmp(p, "${visibility}", 13)) { p += 13; UmlItem::write(visibility(), javaLanguage); fw.write(' '); } else if (!strncmp(p, "${final}", 8)) { p += 8; if (isJavaFinal()) fw.write("final "); } else if (!strncmp(p, "${abstract}", 11)) { p += 11; if (isAbstract()) fw.write("abstract "); } else if (!strncmp(p, "${name}", 7)) { p += 7; writeq(name()); generics(); } else if (!strncmp(p, "${extends}", 10)) { p += 10; const QVector<UmlItem*> ch = children(); for (int i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if (((k == aGeneralisation) || (k == aRealization)) && (!rel->javaDecl().isEmpty()) && ((JavaSettings::classStereotype(stereotype()) == "interface") || (JavaSettings::classStereotype(rel->roleType()->stereotype()) != "interface"))) { extend = rel; fw.write(" extends "); rel->roleType()->write(); generate(actuals(), rel->roleType(), FALSE); break; } } } } else if (!strncmp(p, "${implements}", 13)) { p += 13; const QVector<UmlItem*> ch = children(); const char * sep = " implements "; for (int i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if ((rel != extend) && ((k == aGeneralisation) || (k == aRealization)) && (!rel->javaDecl().isEmpty())) { fw.write(sep); sep = ", "; rel->roleType()->write(); generate(actuals(), rel->roleType(), FALSE); } } } } else if (!strncmp(p, "${@}", 4)) p += 4; else if (*p == '\r') p += 1; else if (*p == '\n') { if (descr) { fw.write("<br />"); p += 1; } else { fw.write(' '); do p += 1; while ((*p != 0) && (*p <= ' ')); } } else if ((*p == '{') || (*p == ';')) { if (descr) fw.write(*p++); else break; } else if (*p == '@') manage_alias(p); else writeq(*p++); } }
void UmlClass::gen_cpp_decl(QCString s, bool descr) { const char * p = (descr) ? (const char *) s : (const char *) bypass_comment(s); while (*p) { if (!strncmp(p, "${comment}", 10)) p += 10; else if (!strncmp(p, "${description}", 14)) p += 14; else if (!strncmp(p, "${type}", 7)) { p += 7; bool find = FALSE; if (baseType().type != 0) { UmlClass * mother = baseType().type; const QVector<UmlItem> ch = children(); for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if (((k == aGeneralisation) || (k == aRealization)) && (rel->roleType() == mother)) { rel->roleType()->write(); generate(actuals(), mother, TRUE); find = TRUE; break; } } } } if (! find) UmlItem::write(baseType(), cppLanguage); } else if (!strncmp(p, "${template}", 11)) { p += 11; generate(formals()); } else if (!strncmp(p, "${name}", 7)) { p += 7; writeq(name()); } else if (!strncmp(p, "${inherit}", 10)) { p += 10; const QVector<UmlItem> ch = children(); const char * sep = " : "; for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if (((k == aGeneralisation) || (k == aRealization)) && !rel->cppDecl().isEmpty()) { fw.write(sep); // UmlItem::write else G++ call UmlClass::write(QCString) ! UmlItem::write((rel->cppVisibility() == DefaultVisibility) ? rel->visibility() : rel->cppVisibility(), cppLanguage); fw.write((rel->cppVirtualInheritance()) ? " virtual " : " "); rel->roleType()->write(); generate(actuals(), rel->roleType(), TRUE); sep = ", "; } } } } else if (*p == '{') { if (descr) fw.write(*p++); else break; } else if (*p == '\r') p += 1; else if (*p == '\n') { if (descr) { fw.write("<br />"); p += 1; } else { fw.write(' '); do p += 1; while ((*p != 0) && (*p <= ' ')); } } else if (*p == '@') manage_alias(p); else writeq(*p++); } }
void UmlRelation::generate(QTextStream & f, const Q3CString &, Q3CString indent, int &) { switch (relationKind()) { case aDependency: case aGeneralisation: case aRealization: break; default: if (!phpDecl().isEmpty()) { const char * p = phpDecl(); const char * pp = 0; Q3CString s; while ((*p == ' ') || (*p == '\t')) indent += *p++; f << indent; for (;;) { if (*p == 0) { if (pp == 0) break; // comment management done p = pp; pp = 0; if (*p == 0) break; f << indent; } if (*p == '\n') { f << *p++; if (*p) f << indent; } else if (*p == '@') manage_alias(p, f); else if (*p != '$') f << *p++; else if (!strncmp(p, "${comment}", 10)) manage_comment(p, pp, PhpSettings::isGenerateJavadocStyleComment()); else if (!strncmp(p, "${description}", 14)) manage_description(p, pp); else if (!strncmp(p, "${visibility}", 13)) { p += 13; generate_visibility(f); } else if (!strncmp(p, "${static}", 9)) { p += 9; if (isClassMember()) f << "static "; } else if (!strncmp(p, "${type}", 7)) { p += 7; roleType()->write(f); } else if (!strncmp(p, "${name}", 7)) { p += 7; if (!isReadOnly()) f << "$"; f << roleName(); } else if (!strncmp(p, "${inverse_name}", 15)) { p += 15; switch (relationKind()) { case anAssociation: case anAggregation: case anAggregationByValue: { UmlRelation * inverse = side(side(TRUE) != this); if (!inverse->isReadOnly()) f << "$"; f << inverse->roleName(); } default: break; } } else if (!strncmp(p, "${var}", 6)) { p += 6; if (!isReadOnly() && !isClassMember() && (visibility() == PackageVisibility)) f << "var "; } else if (!strncmp(p, "${value}", 8)) { if (!defaultValue().isEmpty()) { if (need_equal(p, defaultValue())) f << " = "; f << defaultValue(); } p += 8; } else if (!strncmp(p, "${const}", 8)) { p += 8; if (isReadOnly()) f << "const "; } else f << *p++; } f << '\n'; } } }
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); } } }