// ************************************************************************* // // Copyleft 2004-2007 Bruno PAGES . // // This file is part of the BOUML Uml Toolkit. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // e-mail : bouml@free.fr // home : http://bouml.free.fr // // ************************************************************************* #include "UmlClass.h" #include "UmlClassView.h" #include "UmlDeploymentView.h" #include "UmlRelation.h" #include "UmlArtifact.h" #include "UmlOperation.h" #include "UmlAttribute.h" #include "UmlCom.h" #include "CppSettings.h" #include "JavaSettings.h" #include "UmlExtraClassMember.h" #include "util.h" void UmlClass::made(UmlClassView * base_class_view, UmlClassView * user_class_view, UmlDeploymentView * base_depl_view, UmlDeploymentView * user_depl_view, UmlClass * base_item, QCString s, UmlClass *& base, UmlClass *& user, UmlClass * user_interf) { unsigned uid = UmlCom::user_id(); UmlRelation * rel; UmlCom::set_user_id(0); base = made(base_class_view, base_depl_view, "UmlBase" + s); base->set_isAbstract(TRUE); if ((rel = UmlBaseRelation::create(aGeneralisation, base, this)) == 0) { QCString msg = base->name() + " can't inherit " + name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_CppDecl("${type}"); rel->set_JavaDecl("${type}"); } if ((rel = UmlBaseRelation::create(aDependency, base_item, base)) == 0) { QCString msg = "Cannot add a friend dependency from " + base_item->name() + " to " + base->name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_Stereotype("friend"); rel->set_CppDecl("Generated"); rel->set_JavaDecl(""); } UmlCom::set_user_id(uid); user = made(user_class_view, user_depl_view, "Uml" + s); if ((rel = UmlBaseRelation::create(aGeneralisation, user, base)) == 0) { QCString msg = user->name() + " can't inherit " + base->name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_CppDecl("${type}"); rel->set_JavaDecl("${type}"); } if (user_interf) { if ((rel = UmlBaseRelation::create(aGeneralisation, user, user_interf)) == 0) { QCString msg = user->name() + " can't inherit " + user_interf->name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_CppDecl("${type}"); rel->set_JavaDecl("${type}"); } } } void UmlClass::made(UmlClassView * base_class_view, UmlClassView * user_class_view, UmlArtifact * base_art, UmlArtifact * user_art, UmlClass * base_item, QCString s, UmlClass *& base, UmlClass *& user, UmlClass * user_interf) { unsigned uid = UmlCom::user_id(); UmlRelation * rel; UmlCom::set_user_id(0); base = made(base_class_view, base_art, "UmlBase" + s); base->set_isAbstract(TRUE); if ((rel = UmlBaseRelation::create(aGeneralisation, base, this)) == 0) { QCString msg = base->name() + " can't inherit " + name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_CppDecl("${type}"); rel->set_JavaDecl("${type}"); } if ((rel = UmlBaseRelation::create(aDependency, base_item, base)) == 0) { QCString msg = "Cannot add a friend dependency from " + base_item->name() + " to " + base->name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_Stereotype("friend"); rel->set_CppDecl("Generated"); rel->set_JavaDecl(""); } UmlCom::set_user_id(uid); user = made(user_class_view, user_art, "Uml" + s); if ((rel = UmlBaseRelation::create(aGeneralisation, user, base)) == 0) { QCString msg = user->name() + " can't inherit " + base->name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_CppDecl("${type}"); rel->set_JavaDecl("${type}"); } if (user_interf) { if ((rel = UmlBaseRelation::create(aGeneralisation, user, user_interf)) == 0) { QCString msg = user->name() + " can't inherit " + user_interf->name() + "
\n"; UmlCom::trace(msg); throw 0; } else { rel->set_CppDecl("${type}"); rel->set_JavaDecl("${type}"); } } } UmlClass * UmlClass::made(UmlClassView * class_view, UmlDeploymentView * depl_view, QCString s, bool interf) { UmlClass * cl = UmlBaseClass::create(class_view, s); if (cl == 0) { QCString msg = "can't create class '" + s + "' in " + class_view->name() + "
\n"; UmlCom::trace(msg); throw 0; } if (interf) { UmlCom::trace("add interface " + s + "
\n"); cl->set_Stereotype("interface"); cl->set_JavaDecl(JavaSettings::interfaceDecl()); } else { UmlCom::trace("add class " + s + "
\n"); cl->set_JavaDecl(JavaSettings::classDecl()); } cl->set_CppDecl(CppSettings::classDecl()); UmlArtifact::made(depl_view, s)->addAssociatedClass(cl); return cl; } UmlClass * UmlClass::made(UmlClassView * class_view, UmlArtifact * art, QCString s, bool interf) { UmlClass * cl = UmlBaseClass::create(class_view, s); if (cl == 0) { QCString msg = "can't create class '" + s + "' in " + class_view->name() + "
\n"; UmlCom::trace(msg); throw 0; } if (interf) { UmlCom::trace("add interface " + s + "
\n"); cl->set_Stereotype("interface"); cl->set_JavaDecl(JavaSettings::interfaceDecl()); } else { UmlCom::trace("add class " + s + "
\n"); cl->set_JavaDecl(JavaSettings::classDecl()); } cl->set_CppDecl(CppSettings::classDecl()); art->addAssociatedClass(cl); return cl; } void UmlClass::add_kind(const char * k) { UmlOperation * op = UmlOperation::create(this, "kind"); if (op == 0) { QCString msg = "can't add operation 'kind' in " + name() + "
\n"; UmlCom::trace(msg); throw 0; } UmlCom::trace("add operation " + name() + "::kind" + "
\n"); op->set_Description(" returns the kind of the item"); UmlTypeSpec t; t.type = UmlClass::get("anItemKind", 0); op->set_ReturnType(t); op->remove_cpp_throw(); op->set_isCppVirtual(TRUE); op->set_CppBody(QCString(" return ") + k + ";"); op->set_JavaDef(JavaSettings::operationDef()); op->set_JavaBody(QCString(" return anItemKind.") + k + ";"); } void UmlClass::add_default_base_op(UmlClass * super, UmlClass * user, UmlClass * parent, QCString s, const char * k, bool unnamed) { unsigned uid = UmlCom::user_id(); UmlCom::set_user_id(0); UmlOperation * op = add_op("create", PublicVisibility, user, TRUE); if (op == 0) { QCString msg = "can't add operation 'create' in " + name() + "
\n"; UmlCom::trace(msg); throw 0; } op->set_isClassMember(TRUE); op->add_param(0, InputOutputDirection, "parent", parent); if (unnamed) { op->set_Description(" returns a new " + s + " created under 'parent'\n\ \n\ In case it cannot be created ('parent' cannot contain it etc ...)\n\ return 0 in C++ and produce a RuntimeException in Java\n"); op->set_cpp("${type} *", "${t0} * ${p0}", " return (" + user->name() + " *) parent->create_(" + k + ", \"\");\n", FALSE, 0, 0); op->set_java("${type}", "${t0} ${p0}", " return (" + user->name() + ") parent.create_(anItemKind." + k + ", \"\");\n", FALSE); } else { op->set_Description(" returns a new " + s + " named 's' created under 'parent'\n\ \n\ In case it cannot be created (the name is already used or\n\ invalid, 'parent' cannot contain it etc ...) return 0 in C++\n\ and produce a RuntimeException in Java"); op->add_param(1, InputOutputDirection, "s", "str"); op->set_cpp("${type} *", "${t0} * ${p0}, const ${t1} ${p1}", " return (" + user->name() + " *) parent->create_(" + k + ", s);\n", FALSE, 0, 0); op->set_java("${type}", "${t0} ${p0}, ${t1} ${p1}", " return (" + user->name() + ") parent.create_(anItemKind." + k + ", s);\n", FALSE); } add_kind(k); add_constr(super, ProtectedVisibility, FALSE); UmlCom::set_user_id(uid); } UmlOperation * UmlClass::add_constr(UmlClass * super, aVisibility v, bool unnamed) { UmlOperation * op = UmlOperation::create(this, name()); if (op == 0) { QCString msg = "can't add constructor in " + name() + "
\n"; UmlCom::trace(msg); throw 0; } UmlCom::trace("add operation " + name() + "::" + name() + "
\n"); op->remove_cpp_throw(); op->set_Visibility(v); op->set_Description(" the constructor, do not call it yourself !!!!!!!!!!"); if (super != 0) { op->add_param(0, InputDirection, "id", "item_id"); if (unnamed) { op->set_cpp(": " + super->name() + "(id, \"\")", "${t0} ${p0}", "", TRUE, 0, 0); op->set_java("", "${t0} ${p0}", " super(id, \"\");\n", TRUE); } else { op->add_param(1, InputDirection, "s", "string"); op->set_cpp(": " + super->name() + "(id, s)", "${t0} ${p0}, const ${t1} & ${p1}", "", TRUE, 0, 0); op->set_java("", "${t0} ${p0}, ${t1} ${p1}", " super(id, s);\n", TRUE); } } return op; } UmlOperation * UmlClass::add_destr(aVisibility v, const char * comment) { QCString s = "~" + name(); UmlOperation * op = UmlOperation::create(this, s); if (op == 0) { QCString msg = "can't add destructor in " + name() + "
\n"; UmlCom::trace(msg); throw 0; } UmlCom::trace("add operation " + name() + "::~" + name() + "
\n"); op->remove_cpp_throw(); op->set_Visibility(v); if (comment != 0) op->set_Description(comment); op->set_cpp("", "", "", FALSE, 0, 0); op->set_JavaDecl(""); return op; } UmlOperation * UmlClass::add_op(const char * name, aVisibility v, UmlClass * return_type, bool excpt) { UmlTypeSpec t; t.type = return_type; return add_op(name, v, t, excpt); } UmlOperation * UmlClass::add_op(const char * name, aVisibility v, const char * return_type, bool excpt) { UmlTypeSpec t; t.explicit_type = return_type; return add_op(name, v, t, excpt); } UmlOperation * UmlClass::add_op(const char * name, aVisibility v, UmlTypeSpec & return_type, bool excpt) { UmlOperation * op = UmlOperation::create(this, name); if (op == 0) { QCString msg = QCString("can't add operation '") + name + "' in " + this->name() + "
\n"; UmlCom::trace(msg); throw 0; } UmlCom::trace("add operation " + this->name() + "::" + name + "
\n"); op->remove_cpp_throw(); op->set_ReturnType(return_type); op->set_Visibility(v); if (excpt) { UmlTypeSpec t; t.explicit_type = "RuntimeException"; op->addException(0, t); } return op; } UmlAttribute * UmlClass::add_attribute(const char * name, aVisibility v, const char * type, const char * if_def, const char * end_if) { UmlTypeSpec t; t.explicit_type = type; return add_attribute(name, v, t, if_def, end_if); } UmlAttribute * UmlClass::add_attribute(const char * name, aVisibility v, UmlClass * type, const char * if_def, const char * end_if) { UmlTypeSpec t; t.type = type; return add_attribute(name, v, t, if_def, end_if); } UmlAttribute * UmlClass::add_attribute(const char * name, aVisibility v, UmlTypeSpec & type, const char * if_def, const char * end_if) { UmlAttribute * ar = UmlAttribute::create(this, name); if (ar == 0) { QCString msg = QCString("can't add attribute '") + name + "' in " + this->name() + "
\n"; UmlCom::trace(msg); throw 0; } UmlCom::trace("add attribute " + this->name() + "::" + name + "
\n"); ar->set_Type(type); ar->set_Visibility(v); QCString s = CppSettings::attributeDecl(""); conditional(s, if_def, end_if); ar->set_CppDecl(s); ar->set_JavaDecl(JavaSettings::attributeDecl("")); return ar; } UmlAttribute * UmlClass::add_enum_item(const char * name) { UmlAttribute * at = UmlBaseAttribute::create(this, name); if (at == 0) { UmlCom::trace("cannot add enum item " + this->name() + "::" + name + "
\n"); throw 0; } else { UmlCom::trace("add enum item " + this->name() + "::" + name + "
\n"); at->set_CppDecl(CppSettings::enumItemDecl()); at->set_JavaDecl(JavaSettings::enumPatternItemDecl()); at->set_Visibility(PublicVisibility); } return at; } UmlRelation * UmlClass::add_relation(aRelationKind k, const char * name, aVisibility v, UmlClass * type, const char * if_def, const char * end_if) { UmlRelation * rel = UmlRelation::create(k, this, type); if (rel == 0) { QCString msg = QCString("can't add relation '") + name + "' in " + this->name() + "
\n"; UmlCom::trace(msg); throw 0; } UmlCom::trace("add relation " + this->name() + "::" + name + "
\n"); rel->set_RoleName(name); rel->set_Visibility(v); bool byValue; switch (k) { case anAggregationByValue: case aDirectionalAggregationByValue: byValue = TRUE; break; default: byValue = FALSE; } QCString s = CppSettings::relationDecl(byValue, ""); conditional(s, if_def, end_if); rel->set_CppDecl(s); rel->set_JavaDecl(JavaSettings::relationDecl("")); return rel; } UmlRelation * UmlClass::add_vect_assoc(const char * name, aVisibility v, UmlClass * type, const char * if_def, const char * end_if) { UmlRelation * rel = UmlRelation::create(aDirectionalAggregationByValue, this, type); if (rel == 0) { QCString msg = QCString("can't add relation '") + name + "' in " + this->name() + "
\n"; UmlCom::trace(msg); throw 0; } UmlCom::trace("add relation " + this->name() + "::" + name + "
\n"); rel->set_RoleName(name); rel->set_Visibility(v); rel->set_Multiplicity("*"); rel->set_Stereotype("vector"); QCString s; s = CppSettings::relationDecl(TRUE, ""); s.replace(s.find("${type}"), 7, "QVector<${type}>"); conditional(s, if_def, end_if); rel->set_CppDecl(s); s = JavaSettings::relationDecl(""); s.insert(s.find("${type}") + 7, "[]"); rel->set_JavaDecl(s); return rel; } UmlOperation * UmlClass::get_operation(const char * who) { const QVector ch = children(); for (unsigned i = 0; i != ch.size(); i += 1) if ((ch[i]->kind() == anOperation) && (ch[i]->name() == who)) return (UmlOperation *) ch[i]; return 0; } UmlAttribute * UmlClass::get_attribute(const char * who) { const QVector ch = children(); for (unsigned i = 0; i != ch.size(); i += 1) if ((ch[i]->kind() == anAttribute) && (ch[i]->name() == who)) return (UmlAttribute *) ch[i]; return 0; } UmlRelation * UmlClass::get_relation(aRelationKind k, const char * who) { const QVector ch = children(); for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; if ((rel->relationKind() == k) && ((who == 0) || (rel->roleName() == who))) return rel; } } return 0; } UmlRelation * UmlClass::get_relation(const char * who) { const QVector ch = children(); for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; if (rel->roleName() == who) return rel; } } return 0; } void UmlClass::replace_friend() { QCString s; const QVector ch = children(); unsigned i = ch.size(); while (i--) { if ((ch[i]->kind() == aRelation) && (((UmlRelation *) ch[i])->relationKind() == aDependency) && (ch[i]->stereotype() == "friend")) { s += " friend class " + ((UmlRelation *) ch[i])->roleType()->name() + ";\n"; ch[i]->deleteIt(); } } if (!s.isEmpty()) UmlExtraClassMember::create(this, "friend")->set_CppDecl(s); } void UmlClass::add_friend(const char * scl) { QCString s = QCString(" friend class ") + scl + ";\n"; const QVector ch = children(); unsigned i = ch.size(); while (i--) { if ((ch[i]->kind() == anExtraClassMember) && (ch[i]->name() == "friend")) { UmlExtraClassMember * x = (UmlExtraClassMember *) ch[i]; QCString f = x->cppDecl() + s; x->set_CppDecl(f); return; } } UmlExtraClassMember::create(this, "friend")->set_CppDecl(s); }