[Mobies-commit] [commit] r3597 - UDM/trunk/src/UML GME/Interpreter
endre at redhat1.isis.vanderbilt.edu
endre at redhat1.isis.vanderbilt.edu
Wed Jan 5 01:03:52 CST 2011
Author: endre
Date: Wed Jan 5 01:03:52 2011
New Revision: 3597
Log:
UML2XML interpreter sets the rp_helper associations by looking at the name of the associations in the model
For an association with an association class, the roles will have "rp_helper"
associations if the association class has simple associations with role
names suffixed with either "__rp_helper" or "__rp_container".
For example, if the association roles are called "src_end" and "dst_end",
they will have "rp_helper" associations if there are association roles of
the association class called "src_end__rp_helper" (or "src_end__rp_container")
, respectively "dst_end__rp_helper" (or "dst_end__rp_containter").
Modified:
UDM/trunk/src/UML GME/Interpreter/BONComponent.cpp
Modified: UDM/trunk/src/UML GME/Interpreter/BONComponent.cpp
==============================================================================
--- UDM/trunk/src/UML GME/Interpreter/BONComponent.cpp Wed Jan 5 01:00:49 2011 (r3596)
+++ UDM/trunk/src/UML GME/Interpreter/BONComponent.cpp Wed Jan 5 01:03:52 2011 (r3597)
@@ -1,1656 +1,1677 @@
-/*
- * Copyright (c) Vanderbilt University, 2000-2001
- * ALL RIGHTS RESERVED
- *
- * Vanderbilt University disclaims all warranties with regard to this
- * software, including all implied warranties of merchantability
- * and fitness. In no event shall Vanderbilt University be liable for
- * any special, indirect or consequential damages or any damages
- * whatsoever resulting from loss of use, data or profits, whether
- * in an action of contract, negligence or other tortious action,
- * arising out of or in connection with the use or performance of
- * this software.
- */
-
-/*
- - 05/20/06 - endre
- - add support for nested UML namespaces
-
- - 03/20/06 - endre
-
- - set association and composition names even if they have not
- been changed from the default "Association", respectively
- "Composition"
-
- - 12/31/05 - endre
-
- - use UdmDom data networks and UdmProjects to build the result of interpretation
-
- - 11/24/05 - endre
-
- - change cross class names to class_name + "_cross_ph_" + diagram_name [ + "_cross_ph_" + namespace_name ]
- - add CAssociationBase::DumpCrossXML to fix the generation of Association elements in the cross XML file
- (previously no XML was generated if the association was in a namespace)
-
- - 11/10/04 - endre
-
- - support for silent mode added.
-
- - 13/07/04 - endre
-
- - isNavigable property was not saved correctly in the XML file.
- (if there is no role name, the role is considered not navigable)
-
- - 03/04/04 - endre
-
- - an attempt to use the cross-link machinery for temporary links between the objects of the same datanetworks
- the rule as suggested by Adi: Associations that are among classes of the same package, but the connection itself
- is drawn outside the package are considered semi-cross associations, and will be instantiated in the cross-datanetwork
- of the Udm project files.
-
-
- - 27/02/04 - endre
-
- - added the call GetPackage() for CClassBuilder and CCompositeClassBuilder
-
- - 26/02/04 - endre
-
- - changed all CompositeClass->GetFolder() calls to GetParent()->GetParent() calls because
- the parent of classes now are Models.
- - 24/02/04 - endre
-
- - changed the code to:
- - work with package models instead of package folders
- - ignore class diagram in the root folder
- - generate the version information in the output XML
- - 12/12/03 - endre
-
- Bugfix: replaced the "_" delimiter characther with the
- "_cross_ph_" delimiter string, to allow regular class-names
- and diagram names to contain the "_" character
-
-
- - 12/02/03 - endre
-
- bugfix: cross-link generation bug in situation of multiple inheritence
-
- - 11/28/03 - endre
-
- XSD support added
-
- - 11/118/03 - aditya
- added support for interpterer to work with UMT
- changed error messages to int_exceptions that are caught by
- ComponentDll.cpp
-
- - 10/17/02 - Attribute specifier now is conformant with
- the UML Notation Guide standard 1.4
-
- - 06/17/02 - endre
-
- Added support for attribute arrays
-
-
- - 06/03/02 - endre
-
- CCompositionBuilder::GetRoleID() - had a bug which could not handle self-containment.
- Removed thsi functions and introduced two, GetParentRoleId(), and getChildrenRoleId(),
- which undoubtly code-doubling, but at least works;)
-
- */
-
-#include "stdafx.h"
-
-#include "Lattrib.hpp"
-#include "Pattrib.hpp"
-
-
-#include "CardinalityObject.h"
-#include "AttributeObject.h"
-#include <afxdlgs.h>
-#include <set>
-
-
-#include "BONComponent.h"
-#include "int_exception.h"
-#include "Console.h"
-
-#include "Resource.h"
-
-#include "Uml.h"
-#include "UmlExt.h"
-#include "UdmDom.h"
-#include "UdmProject.h"
-#include "UdmStatic.h"
-
-char* GetRelativeFilename(const char *currentDirectory,const char *absoluteFilename);
-
-CComponent *CComponent::theInstance = 0;
-#ifdef _DEBUG
-#define DLL_NAME "UML2XMLD.dll"
-#else
-#define DLL_NAME "UML2XML.dll"
-#endif
-
-
-
-
-//////////////////////////////// CComponent //////////////////////////////////
-
-
-BOOL CALLBACK resenum(
- HMODULE hModule, // module handle
- LPCTSTR lpszType, // resource type
- LPTSTR lpszName, // resource name
- long lParam // application-defined parameter
-)
-{
-
- AfxMessageBox(CString(lpszName) + CString(":") + CString(lpszType));
- return TRUE;
-};
-
-
-//void CComponent::Invoke(CBuilder &builder,CBuilderObjectList &selected, long param)
-void CComponent::InvokeEx(CBuilder &builder,CBuilderObject *focus, CBuilderObjectList &selected, long param)
-{
- try
- {
- CBuilderFolder *root = builder.GetRootFolder();
- IMgaProject *proj = builder.GetProject();
- CComPtr<IMgaMetaProject> mproj;
- COMVERIFY( proj->get_RootMeta(&mproj));
- CBstr pn;
- COMVERIFY( mproj->get_Name(pn) );
- CString paradigmName = pn;
- if(paradigmName == "UMLModelTransformer") isUMT = true;
- else isUMT = false;
-
- theInstance = this; // cannot use this in Initialize() functions!!!
-
- name = root->GetName();
-
- //getting the packages
- CPackageBuilderList *packages = &packageList;
- GatherPackageFolders(root, *packages);
-
- if(packages->GetCount() == 0)
- { throw int_exception("Uml2Xml Error: There are no class diagrams in the project. No output will be generated");
- }
-
- if(packages->GetCount() == 1)
- {
- //only one diagram
- CPackageBuilder * package = packages->GetHead();
- package->Build();
- package->BuildInheritance();
- package->CheckInheritance();
- package->BuildCompositions();
- package->BuildAssociations();
-
- CString name = package->GetNameorAlias();
-
- CString filepath;
-
- if (param & GME_SILENT_MODE && (!isUMT) )
- filepath = name + "_udm.xml";
- else
- filepath = GetFilePath(builder, focus, "xml", "XML files (*.xml)|*.xml||");
-
- if(filepath == "")
- { throw int_exception("");
- }
-
- ::UdmDom::DomDataNetwork dn(::Uml::diagram);
- dn.CreateNew((LPCTSTR) filepath, "Uml", ::Uml::Diagram::meta, Udm::CHANGES_LOST_DEFAULT);
-
- package->SetUmlDiagram(::Uml::Diagram::Cast(dn.GetRootObject()));
- package->BuildUML();
- package->BuildUMLClasses();
- package->BuildUMLInheritance();
- package->BuildUMLCompositions();
- package->BuildUMLAssociations();
-
- dn.CloseWithUpdate();
-
- if(isUMT)
- {
- CString sysCall = "call \"%UDM_PATH%\\bin\\Udm.exe\" \"" + filepath + "\"";
- if (!(param & GME_SILENT_MODE))
- sysCall += "|| pause";
- if(system(LPCSTR(sysCall))!=0)
- throw int_exception("Uml2Xml Error: Unable to run command: "+ sysCall);
- }
-
- return;
- }
-
-
- CString filepath;
-
- if (param & GME_SILENT_MODE && (!isUMT) )
- filepath = name + "_udm.udm";
- else
- filepath = GetFilePath(builder, focus,"udm","Udm Project Files (*.udm)|*.udm||");
- if(filepath == "")
- { throw int_exception("");
-
- }
-
- {
- vector<Udm::DataNetworkSpecifier> dnsvec;
- POSITION mPos = packages->GetHeadPosition();
- while (mPos)
- {
- CPackageBuilder * package = packages->GetNext(mPos);
- dnsvec.push_back(Udm::DataNetworkSpecifier((LPCTSTR) (package->GetNameorAlias() + ".xml"), "Uml", ::Uml::Diagram::meta));
- }
-
- Udm::UdmProject pr;
- pr.CreateNewMeta((LPCTSTR) name, (LPCTSTR) filepath, dnsvec, Udm::CHANGES_PERSIST_ALWAYS);
- cross_uml_dgr = ::Uml::Diagram::Cast(pr.GetCrossMetaNetwork().GetRootObject());
-
- mPos = packages->GetHeadPosition();
- while (mPos)
- packages->GetNext(mPos)->Build();
-
- mPos = packages->GetHeadPosition();
- while (mPos)
- {
- CPackageBuilder * package = packages->GetNext(mPos);
- package->BuildInheritance();
- package->CheckInheritance();
- package->BuildCompositions();
- package->BuildAssociations();
-
- ::Uml::Diagram dgr = ::Uml::Diagram::Cast(pr.GetDataNetwork((LPCTSTR) (package->GetNameorAlias() + ".xml")).GetRootObject());
-
- package->SetUmlDiagram(dgr);
- package->BuildUML();
- package->BuildUMLClasses();
- package->BuildUMLInheritance();
- package->BuildUMLCompositions();
- package->BuildUMLAssociations();
- }
-
- mPos = packages->GetHeadPosition();
- while (mPos)
- packages->GetNext(mPos)->BuildCrossUMLClasses();
-
- mPos = packages->GetHeadPosition();
- while (mPos)
- packages->GetNext(mPos)->BuildCrossUMLInheritance();
-
- mPos = packages->GetHeadPosition();
- while (mPos)
- {
- CPackageBuilder * package = packages->GetNext(mPos);
- package->BuildCrossUMLCompositions();
- package->BuildCrossUMLAssociations();
- }
- }
-
- if(isUMT)
- { CString sysCall = "call \"%UDM_PATH%\\bin\\Udm.exe\" \"" + filepath + "\"";
- if (!(param & GME_SILENT_MODE))
- sysCall += "|| pause";
- if(system(LPCSTR(sysCall))!=0)
- throw int_exception("Uml2Xml Error: Unable to run command: "+ sysCall);
- }
-
- }
- catch (int_exception &e)
- {
- if (param & GME_SILENT_MODE) return;
-
- std::string str = e.what();
- //do we have stg to say?
- if (str.length())
- AfxMessageBox(e.what().c_str());
- }
- catch (udm_exception &e)
- {
- std::string err = std::string("Caught udm_exception in UML2XML: \"") + e.what() + "\"";
- GMEConsole::Console::SetupConsole(builder.GetProject());
- GMEConsole::Console::Error::WriteLine(err.c_str());
- if (!(param & GME_SILENT_MODE))
- AfxMessageBox(err.c_str());
- }
-}
-
-int CComponent::GatherPackageFolders(CBuilderFolder *folder,CPackageBuilderList &packages)
-{
- int foldercount = 0;
- if(folder->GetKindName() == "RootFolder")
- {
-
- const CBuilderFolderList *subfolders = folder->GetSubFolders();
- if(subfolders)
- {
- POSITION pos = subfolders->GetHeadPosition();
- while(pos)
- {
- CBuilderFolder *subfolder = subfolders->GetNext(pos);
- foldercount += GatherPackageFolders(subfolder, packages);
- }
- }
-
- const CBuilderModelList *models = folder->GetRootModels();
- if(models)
- {
- POSITION pos = models->GetHeadPosition();
- while(pos)
- {
- CBuilderModel *model = models->GetNext(pos);
- if (model->IsKindOf(RUNTIME_CLASS(CPackageBuilder)))
- {
- packages.AddTail(BUILDER_CAST(CPackageBuilder, model));
- foldercount = 1;
- }
- }
- }
-
- return foldercount;
- }
- return foldercount;
-}
-
-
-///////////////////////////// CContainer ///////////////////////////////
-
-CContainer::~CContainer()
-{
- POSITION pos = compositeClasses.GetHeadPosition();
- while(pos)
- delete compositeClasses.GetNext(pos);
-}
-
-void CContainer::TraverseModels(void *pointer)
-{
- if (pointer == NULL) return;
- CBuilderModelList *models = (CBuilderModelList *) pointer;
- POSITION pos = models->GetHeadPosition();
- while(pos)
- {
- CBuilderModel *model = models->GetNext(pos);
- if(model->GetKindName() == "ClassDiagram")
- {
- CClassDiagramBuilder *sheet = dynamic_cast<CClassDiagramBuilder *>(model);
- if(!sheet)
- {
- AfxMessageBox("Unexpected model kind found: " + sheet->GetName());
- continue;
- }
- sheet->Build();
- TraverseModels((void *) sheet->GetModels());
- }
- if(model->GetKindName() == "Namespace")
- {
- CNamespaceBuilder *ns = dynamic_cast<CNamespaceBuilder *>(model);
- namespaces.AddTail(ns);
- ns->Build();
- }
- }
-}
-
-void CContainer::AddCompositeClass(CCompositeClass *cls)
-{
- compositeClasses.AddTail(cls);
-}
-
-void CContainer::AddComposition(CCompositionBuilder *comp)
-{
- compositions.AddTail(comp);
-}
-
-void CContainer::AddAssociation(CAssociationBase *ass)
-{
- associations.AddTail(ass);
-}
-
-void CContainer::BuildInheritance()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildInheritance();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->FindSubClasses();
-}
-
-bool CContainer::CheckInheritance()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- if(!namespaces.GetNext(pos)->CheckInheritance())
- return false;
-
- pos = compositeClasses.GetHeadPosition();
- while(pos) {
- CStringList trace;
- CCompositeClass *comp = compositeClasses.GetNext(pos);
- if(!comp->CheckInheritance(trace)) {
- ASSERT(!trace.IsEmpty());
- CString traceTxt;
- POSITION pos = trace.GetHeadPosition();
- while(pos)
- traceTxt += trace.GetNext(pos) + " -> ";
- traceTxt += trace.GetHead();
- AfxMessageBox("Loop detected in the inheritance hierarchy: \n" + traceTxt,MB_OK | MB_ICONSTOP);
- return false;
- }
- }
- return true;
-}
-
-void CContainer::BuildCompositions()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildCompositions();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->BuildCompositions();
-}
-
-void CContainer::BuildAssociations()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildAssociations();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->BuildAssociations();
-}
-
-void CContainer::BuildUMLClasses()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildUMLClasses();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->BuildUML();
-}
-
-void CContainer::BuildUMLInheritance()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildUMLInheritance();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->BuildUMLInheritance();
-}
-
-void CContainer::BuildUMLAssociations()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildUMLAssociations();
-
- pos = associations.GetHeadPosition();
- while(pos)
- associations.GetNext(pos)->BuildUML();
-}
-
-void CContainer::BuildUMLCompositions()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildUMLCompositions();
-
- pos = compositions.GetHeadPosition();
- while(pos)
- compositions.GetNext(pos)->BuildUML();
-}
-
-void CContainer::BuildCrossUMLClasses()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildCrossUMLClasses();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->BuildCrossUML();
-}
-
-void CContainer::BuildCrossUMLInheritance()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildCrossUMLInheritance();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->BuildCrossUMLInheritance();
-}
-
-void CContainer::BuildCrossUMLAssociations()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildCrossUMLAssociations();
-
- pos = associations.GetHeadPosition();
- while(pos)
- associations.GetNext(pos)->BuildCrossUML();
-}
-
-void CContainer::BuildCrossUMLCompositions()
-{
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildCrossUMLCompositions();
-
- pos = compositeClasses.GetHeadPosition();
- while(pos)
- compositeClasses.GetNext(pos)->BuildCrossUMLCompositions();
-}
-
-///////////////////////////// CPackage /////////////////////////////////
-
-IMPLEMENT_CUSTOMMODEL(CPackageBuilder, CBuilderModel, "Package")
-
-CString CPackageBuilder::GetVersion() const
-{
- CString ret;
- GetAttribute("version", ret);
- return ret;
-};
-
-CString CPackageBuilder::GetNameorAlias() const
-{
- CString ret;
- GetAttribute("alias", ret);
- if (ret.GetLength()) return ret;
- else return GetName();
-};
-
-void CPackageBuilder::Build()
-{
- CContainer::TraverseModels((void *) GetModels());
-};
-
-void CPackageBuilder::BuildUML()
-{
- uml_dgr.name() = (LPCTSTR) GetNameorAlias();
- uml_dgr.version() = (LPCTSTR) GetVersion();
-
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildUML();
-}
-
-///////////////////////////// CNamespace ////////////////////////////////////
-
-IMPLEMENT_CUSTOMMODEL(CNamespaceBuilder, CBuilderModel, "Namespace")
-
-void CNamespaceBuilder::Build()
-{
- CContainer::TraverseModels((void *) GetModels());
-};
-
-CPackageBuilder * CNamespaceBuilder::GetPackage() const
-{
- CPackageBuilder * package;
- const CBuilderModel * parent = GetParent();
- while (parent && parent->GetKindName() != "Package")
- parent = parent->GetParent();
- package = BUILDER_CAST(CPackageBuilder, parent);
- ASSERT(package);
- return package;
-
-};
-
-CNamespaceBuilder * CNamespaceBuilder::GetNamespace() const
-{
- CNamespaceBuilder * ns;
- const CBuilderModel *parent = GetParent();
- while (parent && parent->GetKindName() != "Namespace")
- parent = parent->GetParent();
- ns = BUILDER_CAST(CNamespaceBuilder, parent);
- return ns;
-};
-
-void CNamespaceBuilder::BuildUML()
-{
- const CBuilderModel *parent = GetParent();
- if (parent->GetKindName() == "Namespace") {
- uml_ns = ::Uml::Namespace::Create(BUILDER_CAST(CNamespaceBuilder, parent)->GetUmlNamespace());
- } else if (parent->GetKindName() == "Package") {
- uml_ns = ::Uml::Namespace::Create(BUILDER_CAST(CPackageBuilder, parent)->GetUmlDiagram());
- }
- uml_ns.name() = (LPCTSTR) GetName();
-
- POSITION pos = namespaces.GetHeadPosition();
- while(pos)
- namespaces.GetNext(pos)->BuildUML();
-}
-
-///////////////////////////// CClassDiagram /////////////////////////////////
-
-IMPLEMENT_CUSTOMMODEL(CClassDiagramBuilder, CBuilderModel, "ClassDiagram")
-
-CNamespaceBuilder * CClassDiagramBuilder::GetNamespace() const
-{
- CNamespaceBuilder * ns;
- const CBuilderModel *parent = GetParent();
- while (parent && parent->GetKindName() != "Namespace")
- parent = parent->GetParent();
- ns = BUILDER_CAST(CNamespaceBuilder, parent);
- return ns;
-};
-
-void CClassDiagramBuilder::Build()
-{
- const CBuilderAtomList *classes = GetAtoms("Class");
- POSITION pos = classes->GetHeadPosition();
- while(pos) {
- CClassBuilder *cls = dynamic_cast<CClassBuilder *>(classes->GetNext(pos));
- ASSERT(cls);
- CBuilderObjectList copies;
- cls->GetReferencedBy(copies);
-
- CCompositeClass *comp = new CCompositeClass(cls,copies);
- CNamespaceBuilder *ns = GetNamespace();
- if (ns)
- ns->AddCompositeClass(comp);
- else
- GetPackage()->AddCompositeClass(comp);
- }
-}
-
-CPackageBuilder * CClassDiagramBuilder::GetPackage() const
-{
- CPackageBuilder * package;
- const CBuilderModel * parent = GetParent();
- while (parent && parent->GetKindName() != "Package")
- parent = parent->GetParent();
- package = BUILDER_CAST(CPackageBuilder, parent);
- ASSERT(package);
- return package;
-
-};
-
-////////////////////////////// CCompositeClass ////////////////////////////////
-
-CCompositeClass::CCompositeClass(CClassBuilder *c,CBuilderObjectList &copies) : cls(c), association(0), flag(false)
-{
- cls->composite = this;
- parts.AddHead(cls);
- POSITION pos = copies.GetHeadPosition();
- while(pos)
- { CBuilderObject *cpy = copies.GetNext(pos);
- if(cpy->GetKindName() != "ClassCopy")
- continue;
- CClassCopyBuilder *copy = dynamic_cast<CClassCopyBuilder *>(cpy);
- copy->composite = this;
- ASSERT(copy);
- parts.AddTail(copy);
- }
-}
-
-void CCompositeClass::BuildUML()
-{
- CNamespaceBuilder *ns = cls->GetClassDiagram()->GetNamespace();
- if (ns)
- uml_cls = ::Uml::Class::Create(ns->GetUmlNamespace());
- else
- uml_cls = ::Uml::Class::Create(cls->GetClassDiagram()->GetPackage()->GetUmlDiagram());
-
- uml_cls.name() = (LPCTSTR) GetName();
- if(!cls->stereotype.IsEmpty())
- uml_cls.stereotype() = (LPCTSTR) cls->stereotype;
- uml_cls.isAbstract() = IsAbstract();
-
- std::vector<AttributeObject>::iterator aoi = cls->attributes.begin();
- while (aoi != cls->attributes.end())
- {
- aoi->BuildUML(uml_cls);
- aoi++;
- }
-
- //Dump the constraints, if any
- const CBuilderConnectionList * constraints = cls->GetInConnections("HasConstraint");
-
- POSITION mPos = constraints->GetHeadPosition();
- while (mPos)
- //this line should not fail. The paradigm allows only constraint source
- //for HasConstraint type connection
- BUILDER_CAST(CConstraintBuilder, constraints->GetNext(mPos)->GetSource())->BuildUML(uml_cls);
-
- //Dump the constraintDefinitions, if any
- const CBuilderConnectionList * constraintdefs = cls->GetInConnections("HasDefinition");
- POSITION cdPos = constraintdefs->GetHeadPosition();
- while (cdPos)
- //this line should not fail. The paradigm allows only constraint source
- //for HasConstraint type connection
- BUILDER_CAST(CConstraintDefinitionBuilder, constraintdefs->GetNext(cdPos)->GetSource())->BuildUML(uml_cls);
-}
-
-void CCompositeClass::BuildUMLInheritance()
-{
- if(!baseClasses.IsEmpty())
- {
- POSITION pos = baseClasses.GetHeadPosition();
- while(pos)
- uml_cls.baseTypes() += baseClasses.GetNext(pos)->GetUmlClass();
- }
- if(!subClasses.IsEmpty()) {
- POSITION pos = subClasses.GetHeadPosition();
- while(pos)
- uml_cls.subTypes() += subClasses.GetNext(pos)->GetUmlClass();
- }
-}
-
-void CCompositeClass::BuildCrossUML()
-{
- if(!IsCrossClass()) return;
-
- CNamespaceBuilder * cls_ns = cls->GetClassDiagram()->GetNamespace();
-
- CString class_ph_name = GetName() + "_cross_ph_" + cls->GetPackage()->GetNameorAlias();
- CString from = cls->GetPackage()->GetNameorAlias();
-
- if(cls_ns)
- {
- // name of parent namespaces, from bottom to the top
- vector<CString> ns_names;
- while(cls_ns)
- {
- ns_names.push_back(cls_ns->GetName());
- cls_ns = cls_ns->GetNamespace();
- }
- for(vector<CString>::reverse_iterator i = ns_names.rbegin(); i != ns_names.rend(); i++)
- {
- class_ph_name += "_cross_ph_" + *i;
- from += ":" + *i;
- }
- }
-
- cross_uml_cls = ::Uml::Class::Create(CComponent::theInstance->GetCrossUmlDiagram());
- cross_uml_cls.name() = (LPCTSTR) class_ph_name;
- cross_uml_cls.isAbstract() = false;
- cross_uml_cls.from() = (LPCTSTR) from;
-
- if(!HasCrossBases())
- {
- AttributeObject rem_sysname("rem_sysname:String[1..1]");
- rem_sysname.BuildUML(cross_uml_cls);
- AttributeObject rem_id("rem_id:Integer[1..1]");
- rem_id.BuildUML(cross_uml_cls);
- }
-}
-
-bool CCompositeClass::HasCrossBases()
-{
- bool has_cross_bases = false;
-
- if (!baseClasses.IsEmpty())
- {
- //we only care about baseclasses when this class actually inherits a cross-package association
- //so we simply check if any of the baseclasses is part of a cross-package association
- POSITION bc_pos = baseClasses.GetHeadPosition();
- while (!has_cross_bases && bc_pos)
- {
- CCompositeClass * cccl = baseClasses.GetNext(bc_pos);
- has_cross_bases = cccl->IsCrossClass();
- };
- }
-
- return has_cross_bases;
-}
-
-void CCompositeClass::BuildCrossUMLInheritance()
-{
- if(!IsCrossClass()) return;
-
- if(HasCrossBases())
- {
- /*
- Multiple inheritence bug: Only base-classes which are CrossClasses (or inherited from cross-classes)
- should be listed here, because for the other ones no placeholders classes are generated.
-
- Although we sure that at least one such class will exist once HasCrossBases() is true ...
- */
- POSITION pos = baseClasses.GetHeadPosition();
- while (pos)
- {
- CCompositeClass * cccl = baseClasses.GetNext(pos);
- if (cccl->IsCrossClass())
- cross_uml_cls.baseTypes() += cccl->GetCrossUmlClass();
- };
- }
-
- if(!subClasses.IsEmpty()) {
- POSITION pos = subClasses.GetHeadPosition();
- while(pos)
- cross_uml_cls.subTypes() += subClasses.GetNext(pos)->GetCrossUmlClass();
- }
-}
-
-void CCompositeClass::BuildCrossUMLCompositions()
-{
- if(!IsCrossClass()) return;
-
- // if it's a derived class, no composition is generated - it uses the base's composition */
- if(HasCrossBases()) return;
-
- ::Uml::Diagram cross_dgr = CComponent::theInstance->GetCrossUmlDiagram();
- ::Uml::Class cont_class = ::Uml::classByName(cross_dgr, "_gen_cont");
- ASSERT(cont_class != ::Uml::Class(NULL));
-
- ::Uml::Composition comp = ::Uml::Composition::Create(cross_dgr);
- ::Uml::CompositionChildRole crole = ::Uml::CompositionChildRole::Create(comp);
- crole.target() = cross_uml_cls;
- crole.min() = 0;
- crole.max() = -1;
-
- ::Uml::CompositionParentRole prole = ::Uml::CompositionParentRole::Create(comp);
- prole.target() = cont_class;
-}
-
-CString CCompositeClass::GetName()
-{
- return cls ? cls->GetName() : "";
-}
-
-void CCompositeClass::FindSubClasses(CBuilderObjectList &triangles)
-{
- POSITION pos = triangles.GetHeadPosition();
- while(pos) {
- CBuilderObject *triangle = triangles.GetNext(pos);
- CBuilderObjectList subs;
- triangle->GetOutConnectedObjects("Sub",subs);
- RegisterSubClasses(subs);
- }
-}
-
-void CCompositeClass::FindSubClasses()
-{
- POSITION pos = parts.GetHeadPosition();
- while(pos) {
- CClassBase *part = parts.GetNext(pos);
- CBuilderObjectList triangles;
- part->builder->GetOutConnectedObjects("Base",triangles);
- FindSubClasses(triangles);
- }
-}
-
-void CCompositeClass::RegisterSubClasses(CBuilderObjectList &subs)
-{
- POSITION pos = subs.GetHeadPosition();
- while(pos) {
- CBuilderObject *obj = subs.GetNext(pos);
- CClassBase *subClass = dynamic_cast<CClassBase *>(obj);
- if(subClass == 0)
- AfxMessageBox("Unexpected subclass " + obj->GetName() + " of " + GetName(),MB_OK | MB_ICONSTOP);
- else {
- subClass->composite->AddBaseClass(this);
- AddSubClass(subClass->composite);
- }
- }
-}
-
-void CCompositeClass::AddSubClass(CCompositeClass *sub)
-{
- if(!subClasses.Find(sub))
- subClasses.AddTail(sub);
-}
-
-void CCompositeClass::AddBaseClass(CCompositeClass *base)
-{
- if(!baseClasses.Find(base))
- baseClasses.AddTail(base);
-}
-
-bool CCompositeClass::CheckInheritance(CStringList &trace)
-{
- if(flag) {
- flag = false;
- return false;
- }
- flag = true;
- trace.AddTail(GetName());
-
- POSITION pos = subClasses.GetHeadPosition();
- while(pos) {
- if(!subClasses.GetNext(pos)->CheckInheritance(trace)) {
- flag = false;
- return false;
- }
- }
-
- trace.RemoveTail();
- flag = false;
- return true;
-}
-
-void CCompositeClass::DumpInheritance()
-{
- POSITION pos = baseClasses.GetHeadPosition();
- while(pos)
- AfxMessageBox("Base class of " + GetName() + " is " + baseClasses.GetNext(pos)->GetName());
-}
-
-void CCompositeClass::BuildCompositions()
-{
- POSITION pos = parts.GetHeadPosition();
- while(pos) {
- CClassBase *part = parts.GetNext(pos);
- const CBuilderConnectionList *conns= part->builder->GetInConnections("Composition");
-
- CString name = GetName();
-
- if(conns) {
- POSITION cpos = conns->GetHeadPosition();
- while(cpos) {
- CBuilderConnection *conn = conns->GetNext(cpos);
- CCompositionBuilder *composition = dynamic_cast<CCompositionBuilder *>(conn);
- ASSERT(composition);
- composition->parent.cls = this;
- CClassBase *src = dynamic_cast<CClassBase *>(composition->GetSource());
- ASSERT(src);
- composition->child.cls = src->composite;
- RegisterComposition(composition);
- }
- }
- }
-}
-
-void CCompositeClass::RegisterComposition(CCompositionBuilder *composition)
-{
- POSITION pos = parentCompositions.GetHeadPosition();
- while(pos) {
- CCompositionBuilder *candidate = parentCompositions.GetNext(pos);
- if(candidate->child.cls == composition->child.cls &&
- candidate->child.name == composition->child.name)
- return;
- }
-
- parentCompositions.AddTail(composition);
- composition->child.cls->childCompositions.AddTail(composition);
-
- CNamespaceBuilder *comp_ns = composition->GetNamespace();
- if (comp_ns)
- comp_ns->AddComposition(composition);
- else
- {
- CPackageBuilder *comp_package = composition->GetPackage();
- comp_package->AddComposition(composition);
- }
-}
-
-void CCompositeClass::BuildAssociations()
-{
- POSITION pos = parts.GetHeadPosition();
- while(pos)
- {
- CClassBase *part = parts.GetNext(pos);
- CBuilderObjectList connectors;
- part->builder->GetOutConnectedObjects("Src",connectors);
- POSITION cpos = connectors.GetHeadPosition();
- while(cpos)
- {
- CAssociationBuilder *connector = dynamic_cast<CAssociationBuilder *>(connectors.GetNext(cpos));
- CBuilderObjectList dstList;
- connector->GetOutConnectedObjects("Dst",dstList);
- if(dstList.IsEmpty())
- AfxMessageBox("Partially specified association for class " + GetName());
- else if(dstList.GetCount() > 1)
- AfxMessageBox("Overspecified association for class " + GetName());
- else
- {
- CClassBase *dst = dynamic_cast<CClassBase *>(dstList.GetHead());
-
- ASSERT(dst && dst->composite);
- RegisterAssociation(connector,dst->composite);
- }
- }
- const CBuilderConnectionList *directs = part->builder->GetOutConnections("Association");
- if(directs) {
- cpos = directs->GetHeadPosition();
- while(cpos) {
- CDirectAssociationBuilder *direct = dynamic_cast<CDirectAssociationBuilder *>(directs->GetNext(cpos));
- ASSERT(direct);
- CClassBase *dst = dynamic_cast<CClassBase *>(direct->GetDestination());
- ASSERT(dst && dst->composite);
- if (!dst) {
- // UDM-47
- CComPtr<IMgaFCO> destFco;
- COMVERIFY(direct->GetIConnection()->get_Dst(&destFco));
- CBstr name;
- COMVERIFY(destFco->get_Name(name));
- throw udm_exception(static_cast<CString>(name) + " is a null reference");
- }
- RegisterAssociation(direct,dst->composite);
- }
- }
- }
-}
-
-void CCompositeClass::RegisterAssociation(CAssociationBase *assoc,CCompositeClass *dst)
-{
- assoc->SetSourceAndDestination(this,dst);
- assoc->SetRolesAndCardinalities();
- POSITION pos = srcAssociations.GetHeadPosition();
- while(pos) {
- CAssociationBase *ass = srcAssociations.GetNext(pos);
- if(assoc->IsEquivalent(ass))
- return;
- }
- srcAssociations.AddTail(assoc);
- dst->dstAssociations.AddTail(assoc);
-
- CNamespaceBuilder *ass_ns = assoc->GetNamespace();
- if (ass_ns)
- ass_ns->AddAssociation(assoc);
- else
- {
- CPackageBuilder *ass_package = assoc->GetPackage();
- ass_package->AddAssociation(assoc);
- }
-}
-
-bool CCompositeClass::IsAbstract()
-{
- POSITION pos = parts.GetHeadPosition();
- while(pos) {
- CBuilderObject *part = parts.GetNext(pos)->builder;
- bool abstract;
- part->GetAttribute("IsAbstract",abstract);
- if(abstract)
- return true;
- }
- return false;
-}
-bool CCompositeClass::IsCrossClass()
-{
- bool cross_package = false;
-
- cross_package = association && (association->IsCrossPackage());
-
- POSITION pos = dstAssociations.GetHeadPosition();
-
- while (!cross_package && pos)
- cross_package = dstAssociations.GetNext(pos)->IsCrossPackage();
-
- pos = srcAssociations.GetHeadPosition();
- while (!cross_package && pos)
- cross_package = srcAssociations.GetNext(pos)->IsCrossPackage();
-
-
- pos = baseClasses.GetHeadPosition();
- while (!cross_package && pos)
- cross_package = baseClasses.GetNext(pos)->IsCrossClass();
-
- return cross_package;
-
-
-};
-
-
-////////////////////////////////// CRole //////////////////////////////////////
-
-CRole::CRole() : cls(0), minc(1), maxc(1)
-{
-}
-
-void CRole::ParseCardinality()
-{
- //Invoke ANTLR to parse the cardinality string
- try
- {
- CardinalityObject c_obj((LPCTSTR)cardinality);
- minc = c_obj.getmin();
- maxc = c_obj.getmax();
-
- }
- catch(const CardinalityObjectException &e)
- {
- AfxMessageBox(CString("Parser error occurred while parsing cardinality string: ") + e.what());
- }
-
-};
-
-
-/////////////////////////////// CClassBuilder /////////////////////////////////
-
-IMPLEMENT_CUSTOMATOM(CClassBuilder, CBuilderAtom, "Class")
-
-void CClassBuilder::Initialize()
-{
- CBuilderAtom::Initialize();
- builder = this;
- GetAttribute("Stereotype",stereotype);
- GetUMLAttributes();
-
-}
-
-void CClassBuilder::GetConstraints()
-{
-
-};
-
-void CClassBuilder::GetConstraintDefinitions()
-{
-
-};
-
-CPackageBuilder * CClassBuilder::GetPackage()
-{
- CPackageBuilder *package = BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetPackage();
- ASSERT(package);
- return package;
-
-};
-
-CClassDiagramBuilder * CClassBuilder::GetClassDiagram()
-{
- CClassDiagramBuilder * cd = BUILDER_CAST(CClassDiagramBuilder, GetParent());
- ASSERT(cd);
- return cd;
-};
-
-
-
-void CClassBuilder::GetUMLAttributes()
-{
- CString str_attributes;
-
- GetAttribute("Attributes",str_attributes);
- str_attributes.Trim();
- char buf[4096];
- char *string = buf;
- strcpy(string,(LPCSTR)str_attributes);
- const char * endbuf = buf + strlen(buf);
- char seps[16];
- sprintf(seps,"%c\n",13);
- char *token;
-
- token = strtok(string,seps);
- while(token)
- {
-
- try
- {
- //antlr will do the parsing
- AttributeObject curr_atto(token);
- attributes.push_back(curr_atto);
- }
-
- //catch any parsing exceptions
- catch (AttributeObjectException &e)
- {
- AfxMessageBox(CString("Attribute Object Exception: ") + e.what());
- }
-
- //step to the next token
- string = token + strlen(token) + 1;
-
- //(if there is one)
- if (string > endbuf) string = 0;
-
- //get the next token
- token = strtok(string,seps);
- }
-}
-
-///////////////////////////// CClassCopyBuilder ///////////////////////////////
-
-IMPLEMENT_CUSTOMATOMREF(CClassCopyBuilder, CBuilderAtomReference, "ClassCopy")
-
-void CClassCopyBuilder::Initialize()
-{
- CBuilderAtomReference::Initialize();
- builder = this;
-}
-
-CPackageBuilder * CClassCopyBuilder::GetPackage()
-{
- CPackageBuilder *package = BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetPackage();
- ASSERT(package);
- return package;
-
-};
-
-
-///////////////////////////// CCompositionBuilder ///////////////////////////////
-
-IMPLEMENT_CUSTOMCONNECTION(CCompositionBuilder, CBuilderConnection, "Composition")
-
-void CCompositionBuilder::Initialize()
-{
- CBuilderConnection::Initialize();
- GetAttribute("ChildRole",child.name);
- GetAttribute("ParentRole",parent.name);
- GetAttribute("Cardinality",child.cardinality);
- child.ParseCardinality();
-}
-
-CPackageBuilder* CCompositionBuilder::GetPackage() const
-{
- CPackageBuilder *package = BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetPackage();
- ASSERT(package);
- return package;
-}
-
-CNamespaceBuilder* CCompositionBuilder::GetNamespace() const
-{
- return BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetNamespace();
-}
-
-void CCompositionBuilder::BuildUML()
-{
- CString childName = child.name;
- CString parentName = parent.name;
- CString nm = GetName();
-
- CNamespaceBuilder *ns = GetNamespace();
- if(ns)
- uml_comp = ::Uml::Composition::Create(ns->GetUmlNamespace());
- else
- uml_comp = ::Uml::Composition::Create(GetPackage()->GetUmlDiagram());
-
- if(!nm.IsEmpty())
- uml_comp.name() = (LPCTSTR) nm;
-
- ::Uml::CompositionChildRole crole = ::Uml::CompositionChildRole::Create(uml_comp);
- if(!child.name.IsEmpty())
- crole.name() = (LPCTSTR) child.name;
- crole.min() = child.minc;
- crole.max() = child.maxc;
- crole.target() = child.cls->GetUmlClass();
-
- ::Uml::CompositionParentRole prole = ::Uml::CompositionParentRole::Create(uml_comp);
- if(!parent.name.IsEmpty())
- prole.name() = (LPCTSTR) parent.name;
- prole.target() = parent.cls->GetUmlClass();
-}
-
-
-//////////////////////////////// CAssociationBase /////////////////////////////////
-
-CAssociationBase::CAssociationBase() : associationClass(0)
-{
-}
-bool CAssociationBase::IsCrossPackage()
-{
-
-
- if (dest.cls->cls->GetPackage() != source.cls->cls->GetPackage()) return true;
-
- //at this time dest and source for sure are in the same package
-
- //return associationClass ? (associationClass->cls->GetPackage() != source.cls->cls->GetPackage()) : false;
- if (associationClass && (associationClass->cls->GetPackage() != source.cls->cls->GetPackage()) ) return true;
- //at this time dest and source and assoc class are in the same package.
- //or there is no assoc, and dest and source are in the same package
-
-
-
- const CPackageBuilder * owner_package;
- if (associationClass)
- {
- //there is an assoc class,
- //so this is really a CAssociationBuilder
- const CAssociationBuilder * cab = (CAssociationBuilder *)this;
- owner_package = BUILDER_CAST(CClassDiagramBuilder, cab->GetParent())->GetPackage();
-
- }
- else
- {
- //there isn't an association class
- //so this is a CDirectConnectionBuilder
- const CDirectAssociationBuilder * cdab =(CDirectAssociationBuilder *) this;
- owner_package = BUILDER_CAST(CClassDiagramBuilder, cdab->GetParent())->GetPackage();
-
-
- }
-
- ASSERT(owner_package);
- //we have the package where the connection was drawn.
- //if the connection was drawn in a different package, but the peers are in the same package,
- //the user meant to use the cross link machinery to create temporary links between the objects
- //of the same datanetwork
-
-
- //source and dest (and assoc class, if there is one) are in the same packagefor sure
- //no need to re-check them, just one.
- if (owner_package != source.cls->cls->GetPackage()) return true;
-
-
-
-
- return false;
-
-};
-bool CAssociationBase::IsEquivalent(CAssociationBase *ass)
-{
- //if(source.cls != ass->source.cls || dest.cls != ass->dest.cls || association != ass->association)
- if(source.cls != ass->source.cls || dest.cls != ass->dest.cls || association.Compare(ass->association))
- return false;
- //if(source.name != ass->source.name || dest.name != ass->dest.name)
- if(source.name.Compare(ass->source.name ) || dest.name.Compare(ass->dest.name))
- return false;
- if(associationClass && ass->associationClass && associationClass != ass->associationClass)
- AfxMessageBox("Conflicting association classes: "
- + associationClass->GetName() + " and " + ass->associationClass->GetName());
- return true;
-}
-
-void CAssociationBase::BuildUML()
-{
- if (!IsCrossPackage())
- {
- CNamespaceBuilder *ns = GetNamespace();
- if(ns)
- uml_ass = ::Uml::Association::Create(ns->GetUmlNamespace());
- else
- uml_ass = ::Uml::Association::Create(GetPackage()->GetUmlDiagram());
- _BuildUML(uml_ass, false);
- }
-
-}
-
-void CAssociationBase::BuildCrossUML()
-{
- if (IsCrossPackage())
- {
- cross_uml_ass = ::Uml::Association::Create(CComponent::theInstance->GetCrossUmlDiagram());
- _BuildUML(cross_uml_ass, true);
- }
-}
-
-void CAssociationBase::_BuildUML(::Uml::Association &ass, bool is_cross)
-{
- CString srcName = source.name;
- bool src_isnavig = true;
- if(srcName.IsEmpty())
- {
- srcName = source.cls->GetName();
- src_isnavig = false;
- }
-
- CString dstName = dest.name;
- bool dst_isnavig = true;
- if(dstName.IsEmpty())
- {
- dstName = dest.cls->GetName();
- dst_isnavig = false;
- }
-
- CString nm = association;
- if(!nm.IsEmpty())
- ass.name() = (LPCTSTR) nm;
-
- if(associationClass)
- ass.assocClass() = is_cross ? associationClass->GetCrossUmlClass() : associationClass->GetUmlClass();
-
- ::Uml::AssociationRole role = ::Uml::AssociationRole::Create(ass);
- role.name() = (LPCTSTR) srcName;
- role.min() = source.minc;
- role.max() = source.maxc;
- role.target() = is_cross ? source.cls->GetCrossUmlClass() : source.cls->GetUmlClass();
- role.isNavigable() = src_isnavig;
- //role.isPrimary() = true;
-
- ::Uml::AssociationRole orole = ::Uml::AssociationRole::Create(ass);
- orole.name() = (LPCTSTR) dstName;
- orole.min() = dest.minc;
- orole.max() = dest.maxc;
- orole.target() = is_cross ? dest.cls->GetCrossUmlClass() : dest.cls->GetUmlClass();
- orole.isNavigable() = dst_isnavig;
-}
-
-
-///////////////////////////// CDirectAssociationBuilder ///////////////////////////////
-
-IMPLEMENT_CUSTOMCONNECTION(CDirectAssociationBuilder, CBuilderConnection, "Association")
-
-void CDirectAssociationBuilder::Initialize()
-{
- CBuilderConnection::Initialize();
- parent_classdgr = GetParent();
-}
-
-void CDirectAssociationBuilder::SetSourceAndDestination(CCompositeClass *s,CCompositeClass *d)
-{
- source.cls = s;
- dest.cls = d;
- associationClass = 0;
- association = name;
-}
-
-void CDirectAssociationBuilder::SetRolesAndCardinalities()
-{
- GetAttribute("srcRolename",source.name);
- GetAttribute("srcCardinality",source.cardinality);
- source.ParseCardinality();
- GetAttribute("dstRolename",dest.name);
- GetAttribute("dstCardinality",dest.cardinality);
- dest.ParseCardinality();
-}
-
-
-/////////////////////////////// CAssociationBuilder ///////////////////////////////
-
-IMPLEMENT_CUSTOMATOM(CAssociationBuilder, CBuilderAtom, "Connector")
-
-void CAssociationBuilder::Initialize()
-{
- CBuilderAtom::Initialize();
- parent_classdgr = GetParent();
-}
-
-void CAssociationBuilder::SetSourceAndDestination(CCompositeClass *s,CCompositeClass *d)
-{
- source.cls = s;
- dest.cls = d;
- CBuilderObjectList assClasses;
- GetOutConnectedObjects("AssociationClass",assClasses);
- GetInConnectedObjects("AssociationClass",assClasses);
- if(assClasses.GetCount() > 1)
- AfxMessageBox("Multiple association classes defined for association!");
- else if(!assClasses.IsEmpty()) {
- CClassBase *cls = dynamic_cast<CClassBase *>(assClasses.GetHead());
- ASSERT(cls);
- associationClass = cls->GetComposite();
- associationClass->SetAssociation(this);
- association = associationClass->GetName();
- }
-}
-
-void CAssociationBuilder::SetRolesAndCardinalities()
-{
- const CBuilderConnectionList *srcs = GetInConnections("Src");
- if(srcs == 0 || srcs->GetCount() != 1)
- AfxMessageBox("Invalid source specification for association " + association);
- else {
- CBuilderObject *obj = srcs->GetHead();
- obj->GetAttribute("Cardinality",source.cardinality);
- source.ParseCardinality();
- obj->GetAttribute("srcRolename",source.name);
- }
- const CBuilderConnectionList *dsts = GetOutConnections("Dst");
- if(dsts == 0 || dsts->GetCount() != 1)
- AfxMessageBox("Invalid destination specification for association " + association);
- else {
- CBuilderObject *obj = dsts->GetHead();
- obj->GetAttribute("Cardinality",dest.cardinality);
- dest.ParseCardinality();
- obj->GetAttribute("dstRolename",dest.name);
- }
-}
-
-
-//////////////////////////////CConstraintBuilder//////////////////////////////
-
-IMPLEMENT_CUSTOMATOM(CConstraintBuilder, CBuilderAtom, "Constraint")
-
-void CConstraintBuilder::Initialize()
-{
- CBuilderAtom::Initialize();
- GetAttribute("ConstraintDescription", desc);
- desc.Replace( "\"" , "\\\"" );
- GetAttribute("ConstraintEqn", expr);
- expr.Replace( "\n" , "\\n" );
- expr.Replace( "\r" , "\\r" );
- expr.Replace( "\"" , "\\\"" );
-};
-
-void CConstraintBuilder::BuildUML(::Uml::Class ¨_class)
-{
- ::Uml::Constraint c = ::Uml::Constraint::Create(uml_class);
- c.name() = (LPCTSTR) GetName();
- c.description() = (LPCTSTR) desc;
- c.expression() = (LPCTSTR) expr;
-}
-
-
-//////////////////////////////CConstraintDefinitionBuilder//////////////////////////////
-
-IMPLEMENT_CUSTOMATOM(CConstraintDefinitionBuilder, CBuilderAtom, "ConstraintDefinition")
-
-void CConstraintDefinitionBuilder::Initialize()
-{
- CBuilderAtom::Initialize();
-
- GetAttribute( "DefinitionEqn", expr );
- expr.Replace( "\n" , "\\n" );
- expr.Replace( "\r" , "\\r" );
- expr.Replace( "\"" , "\\\"" );
-
- CString sStereo;
- GetAttribute( "DefinitionStereo", sStereo );
- stereo = sStereo == "method";
-
- GetAttribute( "DefinitionRetType", retType );
-
- GetAttribute( "DefinitionParamList", paramList );
- paramList.Replace( ",", ";" );
-};
-
-void CConstraintDefinitionBuilder::BuildUML(::Uml::Class ¨_class)
-{
- ::Uml::ConstraintDefinition c = ::Uml::ConstraintDefinition::Create(uml_class);
- c.name() = (LPCTSTR) GetName();
- c.expression() = (LPCTSTR) expr;
- c.stereotype() = ( stereo ) ? "method" : "attribute";
- c.returnType() = (LPCTSTR) retType;
- c.parameterList() = (LPCTSTR) paramList;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////
-// Writing back information to config
-/////////////////////////////////////////////////////////////////////////////////////
-CString CComponent::GetFilePath(CBuilder &builder, CBuilderObject *focus, char *FILE_EXT, char *UDM_FILTER)
-{
- CBuilderFolder *root = builder.GetRootFolder();
-/* IMgaProject *proj = builder.GetProject();
- CComPtr<IMgaMetaProject> mproj;
- COMVERIFY( proj->get_RootMeta(&mproj));
- CBstr pn;
- COMVERIFY( mproj->get_Name(pn) );
- CString paradigmName = pn;
- if(paradigmName == "UMLModelTransformer")
- { isUMT = true;
-*/
- if(isUMT)
- {
- CBuilderFolder *root = builder.GetRootFolder();
- const CBuilderFolderList *subfolders = root->GetSubFolders();
- CBuilderModel *theCfg;
- if(focus != NULL && focus->GetKindName() == "Configuration")
- theCfg = BUILDER_CAST(CBuilderModel, focus);
- else
- { POSITION spos = subfolders->GetHeadPosition();
- CBuilderModelList configs;
- while(spos)
- {
- CBuilderFolder *subfolder = subfolders->GetNext(spos);
- if(subfolder->GetKindName() != "Configurations")
- continue;
-
- const CBuilderModelList *cfgs = subfolder->GetRootModels();
- POSITION cmpos = cfgs->GetHeadPosition();
- while(cmpos)
- {
- CBuilderModel *curr_model = cfgs->GetNext(cmpos);
- if ( curr_model->GetKindName() == "Configuration")
- configs.AddTail( curr_model);
- }
- }
- if(configs.GetCount() == 0)
- { throw int_exception("Uml2Xml Error: No Configuration model found. Use UMT Master Interpreter.");
- }
- else if(configs.GetCount() > 1)
- { throw int_exception("Uml2Xml Error: More than one Configuration model found. Either Start interpretation from one or delete the others.");
- }
- else
- { theCfg = configs.GetHead();
- }
- }
-
- CBuilderAtom *theMetaIcon;
- const CBuilderAtomList *mis = theCfg->GetAtoms("MetaInformation");
- if(!mis || mis->GetCount() == 0)
- theMetaIcon = theCfg->CreateNewAtom("MetaInformation");
- else
- theMetaIcon = mis->GetHead();
- CString cfgFileName;
- CString cfgDirName;
- theCfg->GetAttribute("ConfigFile",cfgFileName);
- if(cfgFileName == "" || cfgFileName.GetLength() <3 || cfgFileName.GetAt(1) != ':')
- { throw int_exception("Uml2Xml Error: Config file name is not absolute. Run UMT Master interpreter.");
- }
-
- int p = cfgFileName.ReverseFind('\\');
- cfgDirName = cfgFileName.Left(p+1);
-
- CString transFileName;
- theMetaIcon->GetAttribute("UdmProjectFile",transFileName);
- if(transFileName == "")
- { throw int_exception("Uml2Xml Error: Udm file is blank. Run UMT Master interpreter.");
- }
-
- CString transFilePath = cfgDirName + transFileName;
- CString transDirName;
-
- p = transFilePath.ReverseFind('\\');
- transDirName = transFilePath.Left(p+1);
-
- if(CreateDirectory((LPCSTR)transDirName, NULL)==0)
- { int le = GetLastError();
- if(le != 183)
- { LPTSTR lpMsgBuf;
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, le, 0, (LPTSTR) &lpMsgBuf, 0, NULL );
- CString msg = "Uml2Xml Error: Unable to create directory " + transDirName + "\n";
- msg += (LPCSTR)lpMsgBuf;
- LocalFree(lpMsgBuf);
- throw int_exception(std::string((LPCSTR)msg));
- }
- }
- SetCurrentDirectory((LPCSTR)transDirName);
- return transFilePath;
- }
- else
- { //static char UDM_FILTER[] = "XML files (*.xml)|*.xml";
- CFileDialog cfdlg(false, FILE_EXT, root->GetName(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, UDM_FILTER);
- cfdlg.m_ofn.lpstrTitle = "UDM Meta File Location";
- if (cfdlg.DoModal() != IDOK)
- { throw int_exception("");
- }
- return cfdlg.GetPathName();
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (c) Vanderbilt University, 2000-2001
+ * ALL RIGHTS RESERVED
+ *
+ * Vanderbilt University disclaims all warranties with regard to this
+ * software, including all implied warranties of merchantability
+ * and fitness. In no event shall Vanderbilt University be liable for
+ * any special, indirect or consequential damages or any damages
+ * whatsoever resulting from loss of use, data or profits, whether
+ * in an action of contract, negligence or other tortious action,
+ * arising out of or in connection with the use or performance of
+ * this software.
+ */
+
+/*
+ - 05/20/06 - endre
+ - add support for nested UML namespaces
+
+ - 03/20/06 - endre
+
+ - set association and composition names even if they have not
+ been changed from the default "Association", respectively
+ "Composition"
+
+ - 12/31/05 - endre
+
+ - use UdmDom data networks and UdmProjects to build the result of interpretation
+
+ - 11/24/05 - endre
+
+ - change cross class names to class_name + "_cross_ph_" + diagram_name [ + "_cross_ph_" + namespace_name ]
+ - add CAssociationBase::DumpCrossXML to fix the generation of Association elements in the cross XML file
+ (previously no XML was generated if the association was in a namespace)
+
+ - 11/10/04 - endre
+
+ - support for silent mode added.
+
+ - 13/07/04 - endre
+
+ - isNavigable property was not saved correctly in the XML file.
+ (if there is no role name, the role is considered not navigable)
+
+ - 03/04/04 - endre
+
+ - an attempt to use the cross-link machinery for temporary links between the objects of the same datanetworks
+ the rule as suggested by Adi: Associations that are among classes of the same package, but the connection itself
+ is drawn outside the package are considered semi-cross associations, and will be instantiated in the cross-datanetwork
+ of the Udm project files.
+
+
+ - 27/02/04 - endre
+
+ - added the call GetPackage() for CClassBuilder and CCompositeClassBuilder
+
+ - 26/02/04 - endre
+
+ - changed all CompositeClass->GetFolder() calls to GetParent()->GetParent() calls because
+ the parent of classes now are Models.
+ - 24/02/04 - endre
+
+ - changed the code to:
+ - work with package models instead of package folders
+ - ignore class diagram in the root folder
+ - generate the version information in the output XML
+ - 12/12/03 - endre
+
+ Bugfix: replaced the "_" delimiter characther with the
+ "_cross_ph_" delimiter string, to allow regular class-names
+ and diagram names to contain the "_" character
+
+
+ - 12/02/03 - endre
+
+ bugfix: cross-link generation bug in situation of multiple inheritence
+
+ - 11/28/03 - endre
+
+ XSD support added
+
+ - 11/118/03 - aditya
+ added support for interpterer to work with UMT
+ changed error messages to int_exceptions that are caught by
+ ComponentDll.cpp
+
+ - 10/17/02 - Attribute specifier now is conformant with
+ the UML Notation Guide standard 1.4
+
+ - 06/17/02 - endre
+
+ Added support for attribute arrays
+
+
+ - 06/03/02 - endre
+
+ CCompositionBuilder::GetRoleID() - had a bug which could not handle self-containment.
+ Removed thsi functions and introduced two, GetParentRoleId(), and getChildrenRoleId(),
+ which undoubtly code-doubling, but at least works;)
+
+ */
+
+#include "stdafx.h"
+
+#include "Lattrib.hpp"
+#include "Pattrib.hpp"
+
+
+#include "CardinalityObject.h"
+#include "AttributeObject.h"
+#include <afxdlgs.h>
+#include <set>
+
+
+#include "BONComponent.h"
+#include "int_exception.h"
+#include "Console.h"
+
+#include "Resource.h"
+
+#include "Uml.h"
+#include "UmlExt.h"
+#include "UdmDom.h"
+#include "UdmProject.h"
+#include "UdmStatic.h"
+
+char* GetRelativeFilename(const char *currentDirectory,const char *absoluteFilename);
+
+CComponent *CComponent::theInstance = 0;
+#ifdef _DEBUG
+#define DLL_NAME "UML2XMLD.dll"
+#else
+#define DLL_NAME "UML2XML.dll"
+#endif
+
+
+
+
+//////////////////////////////// CComponent //////////////////////////////////
+
+
+BOOL CALLBACK resenum(
+ HMODULE hModule, // module handle
+ LPCTSTR lpszType, // resource type
+ LPTSTR lpszName, // resource name
+ long lParam // application-defined parameter
+)
+{
+
+ AfxMessageBox(CString(lpszName) + CString(":") + CString(lpszType));
+ return TRUE;
+};
+
+
+//void CComponent::Invoke(CBuilder &builder,CBuilderObjectList &selected, long param)
+void CComponent::InvokeEx(CBuilder &builder,CBuilderObject *focus, CBuilderObjectList &selected, long param)
+{
+ try
+ {
+ CBuilderFolder *root = builder.GetRootFolder();
+ IMgaProject *proj = builder.GetProject();
+ CComPtr<IMgaMetaProject> mproj;
+ COMVERIFY( proj->get_RootMeta(&mproj));
+ CBstr pn;
+ COMVERIFY( mproj->get_Name(pn) );
+ CString paradigmName = pn;
+ if(paradigmName == "UMLModelTransformer") isUMT = true;
+ else isUMT = false;
+
+ theInstance = this; // cannot use this in Initialize() functions!!!
+
+ name = root->GetName();
+
+ //getting the packages
+ CPackageBuilderList *packages = &packageList;
+ GatherPackageFolders(root, *packages);
+
+ if(packages->GetCount() == 0)
+ { throw int_exception("Uml2Xml Error: There are no class diagrams in the project. No output will be generated");
+ }
+
+ if(packages->GetCount() == 1)
+ {
+ //only one diagram
+ CPackageBuilder * package = packages->GetHead();
+ package->Build();
+ package->BuildInheritance();
+ package->CheckInheritance();
+ package->BuildCompositions();
+ package->BuildAssociations();
+
+ CString name = package->GetNameorAlias();
+
+ CString filepath;
+
+ if (param & GME_SILENT_MODE && (!isUMT) )
+ filepath = name + "_udm.xml";
+ else
+ filepath = GetFilePath(builder, focus, "xml", "XML files (*.xml)|*.xml||");
+
+ if(filepath == "")
+ { throw int_exception("");
+ }
+
+ ::UdmDom::DomDataNetwork dn(::Uml::diagram);
+ dn.CreateNew((LPCTSTR) filepath, "Uml", ::Uml::Diagram::meta, Udm::CHANGES_LOST_DEFAULT);
+
+ package->SetUmlDiagram(::Uml::Diagram::Cast(dn.GetRootObject()));
+ package->BuildUML();
+ package->BuildUMLClasses();
+ package->BuildUMLInheritance();
+ package->BuildUMLCompositions();
+ package->BuildUMLAssociations();
+
+ dn.CloseWithUpdate();
+
+ if(isUMT)
+ {
+ CString sysCall = "call \"%UDM_PATH%\\bin\\Udm.exe\" \"" + filepath + "\"";
+ if (!(param & GME_SILENT_MODE))
+ sysCall += "|| pause";
+ if(system(LPCSTR(sysCall))!=0)
+ throw int_exception("Uml2Xml Error: Unable to run command: "+ sysCall);
+ }
+
+ return;
+ }
+
+
+ CString filepath;
+
+ if (param & GME_SILENT_MODE && (!isUMT) )
+ filepath = name + "_udm.udm";
+ else
+ filepath = GetFilePath(builder, focus,"udm","Udm Project Files (*.udm)|*.udm||");
+ if(filepath == "")
+ { throw int_exception("");
+
+ }
+
+ {
+ vector<Udm::DataNetworkSpecifier> dnsvec;
+ POSITION mPos = packages->GetHeadPosition();
+ while (mPos)
+ {
+ CPackageBuilder * package = packages->GetNext(mPos);
+ dnsvec.push_back(Udm::DataNetworkSpecifier((LPCTSTR) (package->GetNameorAlias() + ".xml"), "Uml", ::Uml::Diagram::meta));
+ }
+
+ Udm::UdmProject pr;
+ pr.CreateNewMeta((LPCTSTR) name, (LPCTSTR) filepath, dnsvec, Udm::CHANGES_PERSIST_ALWAYS);
+ cross_uml_dgr = ::Uml::Diagram::Cast(pr.GetCrossMetaNetwork().GetRootObject());
+
+ mPos = packages->GetHeadPosition();
+ while (mPos)
+ packages->GetNext(mPos)->Build();
+
+ mPos = packages->GetHeadPosition();
+ while (mPos)
+ {
+ CPackageBuilder * package = packages->GetNext(mPos);
+ package->BuildInheritance();
+ package->CheckInheritance();
+ package->BuildCompositions();
+ package->BuildAssociations();
+
+ ::Uml::Diagram dgr = ::Uml::Diagram::Cast(pr.GetDataNetwork((LPCTSTR) (package->GetNameorAlias() + ".xml")).GetRootObject());
+
+ package->SetUmlDiagram(dgr);
+ package->BuildUML();
+ package->BuildUMLClasses();
+ package->BuildUMLInheritance();
+ package->BuildUMLCompositions();
+ package->BuildUMLAssociations();
+ }
+
+ mPos = packages->GetHeadPosition();
+ while (mPos)
+ packages->GetNext(mPos)->BuildCrossUMLClasses();
+
+ mPos = packages->GetHeadPosition();
+ while (mPos)
+ packages->GetNext(mPos)->BuildCrossUMLInheritance();
+
+ mPos = packages->GetHeadPosition();
+ while (mPos)
+ {
+ CPackageBuilder * package = packages->GetNext(mPos);
+ package->BuildCrossUMLCompositions();
+ package->BuildCrossUMLAssociations();
+ }
+ }
+
+ if(isUMT)
+ { CString sysCall = "call \"%UDM_PATH%\\bin\\Udm.exe\" \"" + filepath + "\"";
+ if (!(param & GME_SILENT_MODE))
+ sysCall += "|| pause";
+ if(system(LPCSTR(sysCall))!=0)
+ throw int_exception("Uml2Xml Error: Unable to run command: "+ sysCall);
+ }
+
+ }
+ catch (int_exception &e)
+ {
+ if (param & GME_SILENT_MODE) return;
+
+ std::string str = e.what();
+ //do we have stg to say?
+ if (str.length())
+ AfxMessageBox(e.what().c_str());
+ }
+ catch (udm_exception &e)
+ {
+ std::string err = std::string("Caught udm_exception in UML2XML: \"") + e.what() + "\"";
+ GMEConsole::Console::SetupConsole(builder.GetProject());
+ GMEConsole::Console::Error::WriteLine(err.c_str());
+ if (!(param & GME_SILENT_MODE))
+ AfxMessageBox(err.c_str());
+ }
+}
+
+int CComponent::GatherPackageFolders(CBuilderFolder *folder,CPackageBuilderList &packages)
+{
+ int foldercount = 0;
+ if(folder->GetKindName() == "RootFolder")
+ {
+
+ const CBuilderFolderList *subfolders = folder->GetSubFolders();
+ if(subfolders)
+ {
+ POSITION pos = subfolders->GetHeadPosition();
+ while(pos)
+ {
+ CBuilderFolder *subfolder = subfolders->GetNext(pos);
+ foldercount += GatherPackageFolders(subfolder, packages);
+ }
+ }
+
+ const CBuilderModelList *models = folder->GetRootModels();
+ if(models)
+ {
+ POSITION pos = models->GetHeadPosition();
+ while(pos)
+ {
+ CBuilderModel *model = models->GetNext(pos);
+ if (model->IsKindOf(RUNTIME_CLASS(CPackageBuilder)))
+ {
+ packages.AddTail(BUILDER_CAST(CPackageBuilder, model));
+ foldercount = 1;
+ }
+ }
+ }
+
+ return foldercount;
+ }
+ return foldercount;
+}
+
+
+///////////////////////////// CContainer ///////////////////////////////
+
+CContainer::~CContainer()
+{
+ POSITION pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ delete compositeClasses.GetNext(pos);
+}
+
+void CContainer::TraverseModels(void *pointer)
+{
+ if (pointer == NULL) return;
+ CBuilderModelList *models = (CBuilderModelList *) pointer;
+ POSITION pos = models->GetHeadPosition();
+ while(pos)
+ {
+ CBuilderModel *model = models->GetNext(pos);
+ if(model->GetKindName() == "ClassDiagram")
+ {
+ CClassDiagramBuilder *sheet = dynamic_cast<CClassDiagramBuilder *>(model);
+ if(!sheet)
+ {
+ AfxMessageBox("Unexpected model kind found: " + sheet->GetName());
+ continue;
+ }
+ sheet->Build();
+ TraverseModels((void *) sheet->GetModels());
+ }
+ if(model->GetKindName() == "Namespace")
+ {
+ CNamespaceBuilder *ns = dynamic_cast<CNamespaceBuilder *>(model);
+ namespaces.AddTail(ns);
+ ns->Build();
+ }
+ }
+}
+
+void CContainer::AddCompositeClass(CCompositeClass *cls)
+{
+ compositeClasses.AddTail(cls);
+}
+
+void CContainer::AddComposition(CCompositionBuilder *comp)
+{
+ compositions.AddTail(comp);
+}
+
+void CContainer::AddAssociation(CAssociationBase *ass)
+{
+ associations.AddTail(ass);
+}
+
+void CContainer::BuildInheritance()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildInheritance();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->FindSubClasses();
+}
+
+bool CContainer::CheckInheritance()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ if(!namespaces.GetNext(pos)->CheckInheritance())
+ return false;
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos) {
+ CStringList trace;
+ CCompositeClass *comp = compositeClasses.GetNext(pos);
+ if(!comp->CheckInheritance(trace)) {
+ ASSERT(!trace.IsEmpty());
+ CString traceTxt;
+ POSITION pos = trace.GetHeadPosition();
+ while(pos)
+ traceTxt += trace.GetNext(pos) + " -> ";
+ traceTxt += trace.GetHead();
+ AfxMessageBox("Loop detected in the inheritance hierarchy: \n" + traceTxt,MB_OK | MB_ICONSTOP);
+ return false;
+ }
+ }
+ return true;
+}
+
+void CContainer::BuildCompositions()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildCompositions();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->BuildCompositions();
+}
+
+void CContainer::BuildAssociations()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildAssociations();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->BuildAssociations();
+}
+
+void CContainer::BuildUMLClasses()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildUMLClasses();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->BuildUML();
+}
+
+void CContainer::BuildUMLInheritance()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildUMLInheritance();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->BuildUMLInheritance();
+}
+
+void CContainer::BuildUMLAssociations()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildUMLAssociations();
+
+ pos = associations.GetHeadPosition();
+ while(pos)
+ associations.GetNext(pos)->BuildUML();
+}
+
+void CContainer::BuildUMLCompositions()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildUMLCompositions();
+
+ pos = compositions.GetHeadPosition();
+ while(pos)
+ compositions.GetNext(pos)->BuildUML();
+}
+
+void CContainer::BuildCrossUMLClasses()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildCrossUMLClasses();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->BuildCrossUML();
+}
+
+void CContainer::BuildCrossUMLInheritance()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildCrossUMLInheritance();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->BuildCrossUMLInheritance();
+}
+
+void CContainer::BuildCrossUMLAssociations()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildCrossUMLAssociations();
+
+ pos = associations.GetHeadPosition();
+ while(pos)
+ associations.GetNext(pos)->BuildCrossUML();
+}
+
+void CContainer::BuildCrossUMLCompositions()
+{
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildCrossUMLCompositions();
+
+ pos = compositeClasses.GetHeadPosition();
+ while(pos)
+ compositeClasses.GetNext(pos)->BuildCrossUMLCompositions();
+}
+
+///////////////////////////// CPackage /////////////////////////////////
+
+IMPLEMENT_CUSTOMMODEL(CPackageBuilder, CBuilderModel, "Package")
+
+CString CPackageBuilder::GetVersion() const
+{
+ CString ret;
+ GetAttribute("version", ret);
+ return ret;
+};
+
+CString CPackageBuilder::GetNameorAlias() const
+{
+ CString ret;
+ GetAttribute("alias", ret);
+ if (ret.GetLength()) return ret;
+ else return GetName();
+};
+
+void CPackageBuilder::Build()
+{
+ CContainer::TraverseModels((void *) GetModels());
+};
+
+void CPackageBuilder::BuildUML()
+{
+ uml_dgr.name() = (LPCTSTR) GetNameorAlias();
+ uml_dgr.version() = (LPCTSTR) GetVersion();
+
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildUML();
+}
+
+///////////////////////////// CNamespace ////////////////////////////////////
+
+IMPLEMENT_CUSTOMMODEL(CNamespaceBuilder, CBuilderModel, "Namespace")
+
+void CNamespaceBuilder::Build()
+{
+ CContainer::TraverseModels((void *) GetModels());
+};
+
+CPackageBuilder * CNamespaceBuilder::GetPackage() const
+{
+ CPackageBuilder * package;
+ const CBuilderModel * parent = GetParent();
+ while (parent && parent->GetKindName() != "Package")
+ parent = parent->GetParent();
+ package = BUILDER_CAST(CPackageBuilder, parent);
+ ASSERT(package);
+ return package;
+
+};
+
+CNamespaceBuilder * CNamespaceBuilder::GetNamespace() const
+{
+ CNamespaceBuilder * ns;
+ const CBuilderModel *parent = GetParent();
+ while (parent && parent->GetKindName() != "Namespace")
+ parent = parent->GetParent();
+ ns = BUILDER_CAST(CNamespaceBuilder, parent);
+ return ns;
+};
+
+void CNamespaceBuilder::BuildUML()
+{
+ const CBuilderModel *parent = GetParent();
+ if (parent->GetKindName() == "Namespace") {
+ uml_ns = ::Uml::Namespace::Create(BUILDER_CAST(CNamespaceBuilder, parent)->GetUmlNamespace());
+ } else if (parent->GetKindName() == "Package") {
+ uml_ns = ::Uml::Namespace::Create(BUILDER_CAST(CPackageBuilder, parent)->GetUmlDiagram());
+ }
+ uml_ns.name() = (LPCTSTR) GetName();
+
+ POSITION pos = namespaces.GetHeadPosition();
+ while(pos)
+ namespaces.GetNext(pos)->BuildUML();
+}
+
+///////////////////////////// CClassDiagram /////////////////////////////////
+
+IMPLEMENT_CUSTOMMODEL(CClassDiagramBuilder, CBuilderModel, "ClassDiagram")
+
+CNamespaceBuilder * CClassDiagramBuilder::GetNamespace() const
+{
+ CNamespaceBuilder * ns;
+ const CBuilderModel *parent = GetParent();
+ while (parent && parent->GetKindName() != "Namespace")
+ parent = parent->GetParent();
+ ns = BUILDER_CAST(CNamespaceBuilder, parent);
+ return ns;
+};
+
+void CClassDiagramBuilder::Build()
+{
+ const CBuilderAtomList *classes = GetAtoms("Class");
+ POSITION pos = classes->GetHeadPosition();
+ while(pos) {
+ CClassBuilder *cls = dynamic_cast<CClassBuilder *>(classes->GetNext(pos));
+ ASSERT(cls);
+ CBuilderObjectList copies;
+ cls->GetReferencedBy(copies);
+
+ CCompositeClass *comp = new CCompositeClass(cls,copies);
+ CNamespaceBuilder *ns = GetNamespace();
+ if (ns)
+ ns->AddCompositeClass(comp);
+ else
+ GetPackage()->AddCompositeClass(comp);
+ }
+}
+
+CPackageBuilder * CClassDiagramBuilder::GetPackage() const
+{
+ CPackageBuilder * package;
+ const CBuilderModel * parent = GetParent();
+ while (parent && parent->GetKindName() != "Package")
+ parent = parent->GetParent();
+ package = BUILDER_CAST(CPackageBuilder, parent);
+ ASSERT(package);
+ return package;
+
+};
+
+////////////////////////////// CCompositeClass ////////////////////////////////
+
+CCompositeClass::CCompositeClass(CClassBuilder *c,CBuilderObjectList &copies) : cls(c), association(0), flag(false)
+{
+ cls->composite = this;
+ parts.AddHead(cls);
+ POSITION pos = copies.GetHeadPosition();
+ while(pos)
+ { CBuilderObject *cpy = copies.GetNext(pos);
+ if(cpy->GetKindName() != "ClassCopy")
+ continue;
+ CClassCopyBuilder *copy = dynamic_cast<CClassCopyBuilder *>(cpy);
+ copy->composite = this;
+ ASSERT(copy);
+ parts.AddTail(copy);
+ }
+}
+
+void CCompositeClass::BuildUML()
+{
+ CNamespaceBuilder *ns = cls->GetClassDiagram()->GetNamespace();
+ if (ns)
+ uml_cls = ::Uml::Class::Create(ns->GetUmlNamespace());
+ else
+ uml_cls = ::Uml::Class::Create(cls->GetClassDiagram()->GetPackage()->GetUmlDiagram());
+
+ uml_cls.name() = (LPCTSTR) GetName();
+ if(!cls->stereotype.IsEmpty())
+ uml_cls.stereotype() = (LPCTSTR) cls->stereotype;
+ uml_cls.isAbstract() = IsAbstract();
+
+ std::vector<AttributeObject>::iterator aoi = cls->attributes.begin();
+ while (aoi != cls->attributes.end())
+ {
+ aoi->BuildUML(uml_cls);
+ aoi++;
+ }
+
+ //Dump the constraints, if any
+ const CBuilderConnectionList * constraints = cls->GetInConnections("HasConstraint");
+
+ POSITION mPos = constraints->GetHeadPosition();
+ while (mPos)
+ //this line should not fail. The paradigm allows only constraint source
+ //for HasConstraint type connection
+ BUILDER_CAST(CConstraintBuilder, constraints->GetNext(mPos)->GetSource())->BuildUML(uml_cls);
+
+ //Dump the constraintDefinitions, if any
+ const CBuilderConnectionList * constraintdefs = cls->GetInConnections("HasDefinition");
+ POSITION cdPos = constraintdefs->GetHeadPosition();
+ while (cdPos)
+ //this line should not fail. The paradigm allows only constraint source
+ //for HasConstraint type connection
+ BUILDER_CAST(CConstraintDefinitionBuilder, constraintdefs->GetNext(cdPos)->GetSource())->BuildUML(uml_cls);
+}
+
+void CCompositeClass::BuildUMLInheritance()
+{
+ if(!baseClasses.IsEmpty())
+ {
+ POSITION pos = baseClasses.GetHeadPosition();
+ while(pos)
+ uml_cls.baseTypes() += baseClasses.GetNext(pos)->GetUmlClass();
+ }
+ if(!subClasses.IsEmpty()) {
+ POSITION pos = subClasses.GetHeadPosition();
+ while(pos)
+ uml_cls.subTypes() += subClasses.GetNext(pos)->GetUmlClass();
+ }
+}
+
+void CCompositeClass::BuildCrossUML()
+{
+ if(!IsCrossClass()) return;
+
+ CNamespaceBuilder * cls_ns = cls->GetClassDiagram()->GetNamespace();
+
+ CString class_ph_name = GetName() + "_cross_ph_" + cls->GetPackage()->GetNameorAlias();
+ CString from = cls->GetPackage()->GetNameorAlias();
+
+ if(cls_ns)
+ {
+ // name of parent namespaces, from bottom to the top
+ vector<CString> ns_names;
+ while(cls_ns)
+ {
+ ns_names.push_back(cls_ns->GetName());
+ cls_ns = cls_ns->GetNamespace();
+ }
+ for(vector<CString>::reverse_iterator i = ns_names.rbegin(); i != ns_names.rend(); i++)
+ {
+ class_ph_name += "_cross_ph_" + *i;
+ from += ":" + *i;
+ }
+ }
+
+ cross_uml_cls = ::Uml::Class::Create(CComponent::theInstance->GetCrossUmlDiagram());
+ cross_uml_cls.name() = (LPCTSTR) class_ph_name;
+ cross_uml_cls.isAbstract() = false;
+ cross_uml_cls.from() = (LPCTSTR) from;
+
+ if(!HasCrossBases())
+ {
+ AttributeObject rem_sysname("rem_sysname:String[1..1]");
+ rem_sysname.BuildUML(cross_uml_cls);
+ AttributeObject rem_id("rem_id:Integer[1..1]");
+ rem_id.BuildUML(cross_uml_cls);
+ }
+}
+
+bool CCompositeClass::HasCrossBases()
+{
+ bool has_cross_bases = false;
+
+ if (!baseClasses.IsEmpty())
+ {
+ //we only care about baseclasses when this class actually inherits a cross-package association
+ //so we simply check if any of the baseclasses is part of a cross-package association
+ POSITION bc_pos = baseClasses.GetHeadPosition();
+ while (!has_cross_bases && bc_pos)
+ {
+ CCompositeClass * cccl = baseClasses.GetNext(bc_pos);
+ has_cross_bases = cccl->IsCrossClass();
+ };
+ }
+
+ return has_cross_bases;
+}
+
+void CCompositeClass::BuildCrossUMLInheritance()
+{
+ if(!IsCrossClass()) return;
+
+ if(HasCrossBases())
+ {
+ /*
+ Multiple inheritence bug: Only base-classes which are CrossClasses (or inherited from cross-classes)
+ should be listed here, because for the other ones no placeholders classes are generated.
+
+ Although we sure that at least one such class will exist once HasCrossBases() is true ...
+ */
+ POSITION pos = baseClasses.GetHeadPosition();
+ while (pos)
+ {
+ CCompositeClass * cccl = baseClasses.GetNext(pos);
+ if (cccl->IsCrossClass())
+ cross_uml_cls.baseTypes() += cccl->GetCrossUmlClass();
+ };
+ }
+
+ if(!subClasses.IsEmpty()) {
+ POSITION pos = subClasses.GetHeadPosition();
+ while(pos)
+ cross_uml_cls.subTypes() += subClasses.GetNext(pos)->GetCrossUmlClass();
+ }
+}
+
+void CCompositeClass::BuildCrossUMLCompositions()
+{
+ if(!IsCrossClass()) return;
+
+ // if it's a derived class, no composition is generated - it uses the base's composition */
+ if(HasCrossBases()) return;
+
+ ::Uml::Diagram cross_dgr = CComponent::theInstance->GetCrossUmlDiagram();
+ ::Uml::Class cont_class = ::Uml::classByName(cross_dgr, "_gen_cont");
+ ASSERT(cont_class != ::Uml::Class(NULL));
+
+ ::Uml::Composition comp = ::Uml::Composition::Create(cross_dgr);
+ ::Uml::CompositionChildRole crole = ::Uml::CompositionChildRole::Create(comp);
+ crole.target() = cross_uml_cls;
+ crole.min() = 0;
+ crole.max() = -1;
+
+ ::Uml::CompositionParentRole prole = ::Uml::CompositionParentRole::Create(comp);
+ prole.target() = cont_class;
+}
+
+CString CCompositeClass::GetName()
+{
+ return cls ? cls->GetName() : "";
+}
+
+void CCompositeClass::FindSubClasses(CBuilderObjectList &triangles)
+{
+ POSITION pos = triangles.GetHeadPosition();
+ while(pos) {
+ CBuilderObject *triangle = triangles.GetNext(pos);
+ CBuilderObjectList subs;
+ triangle->GetOutConnectedObjects("Sub",subs);
+ RegisterSubClasses(subs);
+ }
+}
+
+void CCompositeClass::FindSubClasses()
+{
+ POSITION pos = parts.GetHeadPosition();
+ while(pos) {
+ CClassBase *part = parts.GetNext(pos);
+ CBuilderObjectList triangles;
+ part->builder->GetOutConnectedObjects("Base",triangles);
+ FindSubClasses(triangles);
+ }
+}
+
+void CCompositeClass::RegisterSubClasses(CBuilderObjectList &subs)
+{
+ POSITION pos = subs.GetHeadPosition();
+ while(pos) {
+ CBuilderObject *obj = subs.GetNext(pos);
+ CClassBase *subClass = dynamic_cast<CClassBase *>(obj);
+ if(subClass == 0)
+ AfxMessageBox("Unexpected subclass " + obj->GetName() + " of " + GetName(),MB_OK | MB_ICONSTOP);
+ else {
+ subClass->composite->AddBaseClass(this);
+ AddSubClass(subClass->composite);
+ }
+ }
+}
+
+void CCompositeClass::AddSubClass(CCompositeClass *sub)
+{
+ if(!subClasses.Find(sub))
+ subClasses.AddTail(sub);
+}
+
+void CCompositeClass::AddBaseClass(CCompositeClass *base)
+{
+ if(!baseClasses.Find(base))
+ baseClasses.AddTail(base);
+}
+
+bool CCompositeClass::CheckInheritance(CStringList &trace)
+{
+ if(flag) {
+ flag = false;
+ return false;
+ }
+ flag = true;
+ trace.AddTail(GetName());
+
+ POSITION pos = subClasses.GetHeadPosition();
+ while(pos) {
+ if(!subClasses.GetNext(pos)->CheckInheritance(trace)) {
+ flag = false;
+ return false;
+ }
+ }
+
+ trace.RemoveTail();
+ flag = false;
+ return true;
+}
+
+void CCompositeClass::DumpInheritance()
+{
+ POSITION pos = baseClasses.GetHeadPosition();
+ while(pos)
+ AfxMessageBox("Base class of " + GetName() + " is " + baseClasses.GetNext(pos)->GetName());
+}
+
+void CCompositeClass::BuildCompositions()
+{
+ POSITION pos = parts.GetHeadPosition();
+ while(pos) {
+ CClassBase *part = parts.GetNext(pos);
+ const CBuilderConnectionList *conns= part->builder->GetInConnections("Composition");
+
+ CString name = GetName();
+
+ if(conns) {
+ POSITION cpos = conns->GetHeadPosition();
+ while(cpos) {
+ CBuilderConnection *conn = conns->GetNext(cpos);
+ CCompositionBuilder *composition = dynamic_cast<CCompositionBuilder *>(conn);
+ ASSERT(composition);
+ composition->parent.cls = this;
+ CClassBase *src = dynamic_cast<CClassBase *>(composition->GetSource());
+ ASSERT(src);
+ composition->child.cls = src->composite;
+ RegisterComposition(composition);
+ }
+ }
+ }
+}
+
+void CCompositeClass::RegisterComposition(CCompositionBuilder *composition)
+{
+ POSITION pos = parentCompositions.GetHeadPosition();
+ while(pos) {
+ CCompositionBuilder *candidate = parentCompositions.GetNext(pos);
+ if(candidate->child.cls == composition->child.cls &&
+ candidate->child.name == composition->child.name)
+ return;
+ }
+
+ parentCompositions.AddTail(composition);
+ composition->child.cls->childCompositions.AddTail(composition);
+
+ CNamespaceBuilder *comp_ns = composition->GetNamespace();
+ if (comp_ns)
+ comp_ns->AddComposition(composition);
+ else
+ {
+ CPackageBuilder *comp_package = composition->GetPackage();
+ comp_package->AddComposition(composition);
+ }
+}
+
+void CCompositeClass::BuildAssociations()
+{
+ POSITION pos = parts.GetHeadPosition();
+ while(pos)
+ {
+ CClassBase *part = parts.GetNext(pos);
+ CBuilderObjectList connectors;
+ part->builder->GetOutConnectedObjects("Src",connectors);
+ POSITION cpos = connectors.GetHeadPosition();
+ while(cpos)
+ {
+ CAssociationBuilder *connector = dynamic_cast<CAssociationBuilder *>(connectors.GetNext(cpos));
+ CBuilderObjectList dstList;
+ connector->GetOutConnectedObjects("Dst",dstList);
+ if(dstList.IsEmpty())
+ AfxMessageBox("Partially specified association for class " + GetName());
+ else if(dstList.GetCount() > 1)
+ AfxMessageBox("Overspecified association for class " + GetName());
+ else
+ {
+ CClassBase *dst = dynamic_cast<CClassBase *>(dstList.GetHead());
+
+ ASSERT(dst && dst->composite);
+ RegisterAssociation(connector,dst->composite);
+ }
+ }
+ const CBuilderConnectionList *directs = part->builder->GetOutConnections("Association");
+ if(directs) {
+ cpos = directs->GetHeadPosition();
+ while(cpos) {
+ CDirectAssociationBuilder *direct = dynamic_cast<CDirectAssociationBuilder *>(directs->GetNext(cpos));
+ ASSERT(direct);
+ CClassBase *dst = dynamic_cast<CClassBase *>(direct->GetDestination());
+ ASSERT(dst && dst->composite);
+ if (!dst) {
+ // UDM-47
+ CComPtr<IMgaFCO> destFco;
+ COMVERIFY(direct->GetIConnection()->get_Dst(&destFco));
+ CBstr name;
+ COMVERIFY(destFco->get_Name(name));
+ throw udm_exception(static_cast<CString>(name) + " is a null reference");
+ }
+ RegisterAssociation(direct,dst->composite);
+ }
+ }
+ }
+}
+
+void CCompositeClass::RegisterAssociation(CAssociationBase *assoc,CCompositeClass *dst)
+{
+ assoc->SetSourceAndDestination(this,dst);
+ assoc->SetRolesAndCardinalities();
+ POSITION pos = srcAssociations.GetHeadPosition();
+ while(pos) {
+ CAssociationBase *ass = srcAssociations.GetNext(pos);
+ if(assoc->IsEquivalent(ass))
+ return;
+ }
+ srcAssociations.AddTail(assoc);
+ dst->dstAssociations.AddTail(assoc);
+
+ CNamespaceBuilder *ass_ns = assoc->GetNamespace();
+ if (ass_ns)
+ ass_ns->AddAssociation(assoc);
+ else
+ {
+ CPackageBuilder *ass_package = assoc->GetPackage();
+ ass_package->AddAssociation(assoc);
+ }
+}
+
+bool CCompositeClass::IsAbstract()
+{
+ POSITION pos = parts.GetHeadPosition();
+ while(pos) {
+ CBuilderObject *part = parts.GetNext(pos)->builder;
+ bool abstract;
+ part->GetAttribute("IsAbstract",abstract);
+ if(abstract)
+ return true;
+ }
+ return false;
+}
+bool CCompositeClass::IsCrossClass()
+{
+ bool cross_package = false;
+
+ cross_package = association && (association->IsCrossPackage());
+
+ POSITION pos = dstAssociations.GetHeadPosition();
+
+ while (!cross_package && pos)
+ cross_package = dstAssociations.GetNext(pos)->IsCrossPackage();
+
+ pos = srcAssociations.GetHeadPosition();
+ while (!cross_package && pos)
+ cross_package = srcAssociations.GetNext(pos)->IsCrossPackage();
+
+
+ pos = baseClasses.GetHeadPosition();
+ while (!cross_package && pos)
+ cross_package = baseClasses.GetNext(pos)->IsCrossClass();
+
+ return cross_package;
+
+
+};
+
+
+////////////////////////////////// CRole //////////////////////////////////////
+
+CRole::CRole() : cls(0), minc(1), maxc(1)
+{
+}
+
+void CRole::ParseCardinality()
+{
+ //Invoke ANTLR to parse the cardinality string
+ try
+ {
+ CardinalityObject c_obj((LPCTSTR)cardinality);
+ minc = c_obj.getmin();
+ maxc = c_obj.getmax();
+
+ }
+ catch(const CardinalityObjectException &e)
+ {
+ AfxMessageBox(CString("Parser error occurred while parsing cardinality string: ") + e.what());
+ }
+
+};
+
+
+/////////////////////////////// CClassBuilder /////////////////////////////////
+
+IMPLEMENT_CUSTOMATOM(CClassBuilder, CBuilderAtom, "Class")
+
+void CClassBuilder::Initialize()
+{
+ CBuilderAtom::Initialize();
+ builder = this;
+ GetAttribute("Stereotype",stereotype);
+ GetUMLAttributes();
+
+}
+
+void CClassBuilder::GetConstraints()
+{
+
+};
+
+void CClassBuilder::GetConstraintDefinitions()
+{
+
+};
+
+CPackageBuilder * CClassBuilder::GetPackage()
+{
+ CPackageBuilder *package = BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetPackage();
+ ASSERT(package);
+ return package;
+
+};
+
+CClassDiagramBuilder * CClassBuilder::GetClassDiagram()
+{
+ CClassDiagramBuilder * cd = BUILDER_CAST(CClassDiagramBuilder, GetParent());
+ ASSERT(cd);
+ return cd;
+};
+
+
+
+void CClassBuilder::GetUMLAttributes()
+{
+ CString str_attributes;
+
+ GetAttribute("Attributes",str_attributes);
+ str_attributes.Trim();
+ char buf[4096];
+ char *string = buf;
+ strcpy(string,(LPCSTR)str_attributes);
+ const char * endbuf = buf + strlen(buf);
+ char seps[16];
+ sprintf(seps,"%c\n",13);
+ char *token;
+
+ token = strtok(string,seps);
+ while(token)
+ {
+
+ try
+ {
+ //antlr will do the parsing
+ AttributeObject curr_atto(token);
+ attributes.push_back(curr_atto);
+ }
+
+ //catch any parsing exceptions
+ catch (AttributeObjectException &e)
+ {
+ AfxMessageBox(CString("Attribute Object Exception: ") + e.what());
+ }
+
+ //step to the next token
+ string = token + strlen(token) + 1;
+
+ //(if there is one)
+ if (string > endbuf) string = 0;
+
+ //get the next token
+ token = strtok(string,seps);
+ }
+}
+
+///////////////////////////// CClassCopyBuilder ///////////////////////////////
+
+IMPLEMENT_CUSTOMATOMREF(CClassCopyBuilder, CBuilderAtomReference, "ClassCopy")
+
+void CClassCopyBuilder::Initialize()
+{
+ CBuilderAtomReference::Initialize();
+ builder = this;
+}
+
+CPackageBuilder * CClassCopyBuilder::GetPackage()
+{
+ CPackageBuilder *package = BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetPackage();
+ ASSERT(package);
+ return package;
+
+};
+
+
+///////////////////////////// CCompositionBuilder ///////////////////////////////
+
+IMPLEMENT_CUSTOMCONNECTION(CCompositionBuilder, CBuilderConnection, "Composition")
+
+void CCompositionBuilder::Initialize()
+{
+ CBuilderConnection::Initialize();
+ GetAttribute("ChildRole",child.name);
+ GetAttribute("ParentRole",parent.name);
+ GetAttribute("Cardinality",child.cardinality);
+ child.ParseCardinality();
+}
+
+CPackageBuilder* CCompositionBuilder::GetPackage() const
+{
+ CPackageBuilder *package = BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetPackage();
+ ASSERT(package);
+ return package;
+}
+
+CNamespaceBuilder* CCompositionBuilder::GetNamespace() const
+{
+ return BUILDER_CAST(CClassDiagramBuilder, GetParent())->GetNamespace();
+}
+
+void CCompositionBuilder::BuildUML()
+{
+ CString childName = child.name;
+ CString parentName = parent.name;
+ CString nm = GetName();
+
+ CNamespaceBuilder *ns = GetNamespace();
+ if(ns)
+ uml_comp = ::Uml::Composition::Create(ns->GetUmlNamespace());
+ else
+ uml_comp = ::Uml::Composition::Create(GetPackage()->GetUmlDiagram());
+
+ if(!nm.IsEmpty())
+ uml_comp.name() = (LPCTSTR) nm;
+
+ ::Uml::CompositionChildRole crole = ::Uml::CompositionChildRole::Create(uml_comp);
+ if(!child.name.IsEmpty())
+ crole.name() = (LPCTSTR) child.name;
+ crole.min() = child.minc;
+ crole.max() = child.maxc;
+ crole.target() = child.cls->GetUmlClass();
+
+ ::Uml::CompositionParentRole prole = ::Uml::CompositionParentRole::Create(uml_comp);
+ if(!parent.name.IsEmpty())
+ prole.name() = (LPCTSTR) parent.name;
+ prole.target() = parent.cls->GetUmlClass();
+}
+
+
+//////////////////////////////// CAssociationBase /////////////////////////////////
+
+CAssociationBase::CAssociationBase() : associationClass(0)
+{
+}
+bool CAssociationBase::IsCrossPackage()
+{
+
+
+ if (dest.cls->cls->GetPackage() != source.cls->cls->GetPackage()) return true;
+
+ //at this time dest and source for sure are in the same package
+
+ //return associationClass ? (associationClass->cls->GetPackage() != source.cls->cls->GetPackage()) : false;
+ if (associationClass && (associationClass->cls->GetPackage() != source.cls->cls->GetPackage()) ) return true;
+ //at this time dest and source and assoc class are in the same package.
+ //or there is no assoc, and dest and source are in the same package
+
+
+
+ const CPackageBuilder * owner_package;
+ if (associationClass)
+ {
+ //there is an assoc class,
+ //so this is really a CAssociationBuilder
+ const CAssociationBuilder * cab = (CAssociationBuilder *)this;
+ owner_package = BUILDER_CAST(CClassDiagramBuilder, cab->GetParent())->GetPackage();
+
+ }
+ else
+ {
+ //there isn't an association class
+ //so this is a CDirectConnectionBuilder
+ const CDirectAssociationBuilder * cdab =(CDirectAssociationBuilder *) this;
+ owner_package = BUILDER_CAST(CClassDiagramBuilder, cdab->GetParent())->GetPackage();
+
+
+ }
+
+ ASSERT(owner_package);
+ //we have the package where the connection was drawn.
+ //if the connection was drawn in a different package, but the peers are in the same package,
+ //the user meant to use the cross link machinery to create temporary links between the objects
+ //of the same datanetwork
+
+
+ //source and dest (and assoc class, if there is one) are in the same packagefor sure
+ //no need to re-check them, just one.
+ if (owner_package != source.cls->cls->GetPackage()) return true;
+
+
+
+
+ return false;
+
+};
+bool CAssociationBase::IsEquivalent(CAssociationBase *ass)
+{
+ //if(source.cls != ass->source.cls || dest.cls != ass->dest.cls || association != ass->association)
+ if(source.cls != ass->source.cls || dest.cls != ass->dest.cls || association.Compare(ass->association))
+ return false;
+ //if(source.name != ass->source.name || dest.name != ass->dest.name)
+ if(source.name.Compare(ass->source.name ) || dest.name.Compare(ass->dest.name))
+ return false;
+ if(associationClass && ass->associationClass && associationClass != ass->associationClass)
+ AfxMessageBox("Conflicting association classes: "
+ + associationClass->GetName() + " and " + ass->associationClass->GetName());
+ return true;
+}
+
+void CAssociationBase::BuildUML()
+{
+ if (!IsCrossPackage())
+ {
+ CNamespaceBuilder *ns = GetNamespace();
+ if(ns)
+ uml_ass = ::Uml::Association::Create(ns->GetUmlNamespace());
+ else
+ uml_ass = ::Uml::Association::Create(GetPackage()->GetUmlDiagram());
+ _BuildUML(uml_ass, false);
+ }
+
+}
+
+void CAssociationBase::BuildCrossUML()
+{
+ if (IsCrossPackage())
+ {
+ cross_uml_ass = ::Uml::Association::Create(CComponent::theInstance->GetCrossUmlDiagram());
+ _BuildUML(cross_uml_ass, true);
+ }
+}
+
+void CAssociationBase::_BuildUML(::Uml::Association &ass, bool is_cross)
+{
+ CString srcName = source.name;
+ bool src_isnavig = true;
+ if(srcName.IsEmpty())
+ {
+ srcName = source.cls->GetName();
+ src_isnavig = false;
+ }
+
+ CString dstName = dest.name;
+ bool dst_isnavig = true;
+ if(dstName.IsEmpty())
+ {
+ dstName = dest.cls->GetName();
+ dst_isnavig = false;
+ }
+
+ CString nm = association;
+ if(!nm.IsEmpty())
+ ass.name() = (LPCTSTR) nm;
+
+ if(associationClass)
+ ass.assocClass() = is_cross ? associationClass->GetCrossUmlClass() : associationClass->GetUmlClass();
+
+ ::Uml::AssociationRole role = ::Uml::AssociationRole::Create(ass);
+ role.name() = (LPCTSTR) srcName;
+ role.min() = source.minc;
+ role.max() = source.maxc;
+ role.target() = is_cross ? source.cls->GetCrossUmlClass() : source.cls->GetUmlClass();
+ role.isNavigable() = src_isnavig;
+ //role.isPrimary() = true;
+
+ ::Uml::AssociationRole orole = ::Uml::AssociationRole::Create(ass);
+ orole.name() = (LPCTSTR) dstName;
+ orole.min() = dest.minc;
+ orole.max() = dest.maxc;
+ orole.target() = is_cross ? dest.cls->GetCrossUmlClass() : dest.cls->GetUmlClass();
+ orole.isNavigable() = dst_isnavig;
+
+ // set reference port helper relations by looking for simple associations of
+ // the association class that have roles ending in "__rp_helper" or "__rp_container"
+ if (associationClass) {
+ POSITION cpos = associationClass->srcAssociations.GetHeadPosition();
+ while (cpos) {
+ CAssociationBase *assoc = dynamic_cast<CAssociationBase *>(associationClass->srcAssociations.GetNext(cpos));
+ ASSERT(assoc);
+ ::Uml::Association uml_ass = assoc->GetUmlAssociation();
+ set< ::Uml::AssociationRole> aroles = uml_ass.roles();
+ for (set< ::Uml::AssociationRole>::const_iterator i = aroles.begin(); i != aroles.end(); i++) {
+ string role_name = ::Uml::MakeRoleName(*i);
+ if (role_name == string(srcName) + "__rp_helper" || role_name == string(srcName) + "__rp_container") {
+ role.rp_helper() = *i;
+ }
+ if (role_name == string(dstName) + "__rp_helper" || role_name == string(dstName) + "__rp_container") {
+ orole.rp_helper() = *i;
+ }
+ }
+ }
+ }
+}
+
+
+///////////////////////////// CDirectAssociationBuilder ///////////////////////////////
+
+IMPLEMENT_CUSTOMCONNECTION(CDirectAssociationBuilder, CBuilderConnection, "Association")
+
+void CDirectAssociationBuilder::Initialize()
+{
+ CBuilderConnection::Initialize();
+ parent_classdgr = GetParent();
+}
+
+void CDirectAssociationBuilder::SetSourceAndDestination(CCompositeClass *s,CCompositeClass *d)
+{
+ source.cls = s;
+ dest.cls = d;
+ associationClass = 0;
+ association = name;
+}
+
+void CDirectAssociationBuilder::SetRolesAndCardinalities()
+{
+ GetAttribute("srcRolename",source.name);
+ GetAttribute("srcCardinality",source.cardinality);
+ source.ParseCardinality();
+ GetAttribute("dstRolename",dest.name);
+ GetAttribute("dstCardinality",dest.cardinality);
+ dest.ParseCardinality();
+}
+
+
+/////////////////////////////// CAssociationBuilder ///////////////////////////////
+
+IMPLEMENT_CUSTOMATOM(CAssociationBuilder, CBuilderAtom, "Connector")
+
+void CAssociationBuilder::Initialize()
+{
+ CBuilderAtom::Initialize();
+ parent_classdgr = GetParent();
+}
+
+void CAssociationBuilder::SetSourceAndDestination(CCompositeClass *s,CCompositeClass *d)
+{
+ source.cls = s;
+ dest.cls = d;
+ CBuilderObjectList assClasses;
+ GetOutConnectedObjects("AssociationClass",assClasses);
+ GetInConnectedObjects("AssociationClass",assClasses);
+ if(assClasses.GetCount() > 1)
+ AfxMessageBox("Multiple association classes defined for association!");
+ else if(!assClasses.IsEmpty()) {
+ CClassBase *cls = dynamic_cast<CClassBase *>(assClasses.GetHead());
+ ASSERT(cls);
+ associationClass = cls->GetComposite();
+ associationClass->SetAssociation(this);
+ association = associationClass->GetName();
+ }
+}
+
+void CAssociationBuilder::SetRolesAndCardinalities()
+{
+ const CBuilderConnectionList *srcs = GetInConnections("Src");
+ if(srcs == 0 || srcs->GetCount() != 1)
+ AfxMessageBox("Invalid source specification for association " + association);
+ else {
+ CBuilderObject *obj = srcs->GetHead();
+ obj->GetAttribute("Cardinality",source.cardinality);
+ source.ParseCardinality();
+ obj->GetAttribute("srcRolename",source.name);
+ }
+ const CBuilderConnectionList *dsts = GetOutConnections("Dst");
+ if(dsts == 0 || dsts->GetCount() != 1)
+ AfxMessageBox("Invalid destination specification for association " + association);
+ else {
+ CBuilderObject *obj = dsts->GetHead();
+ obj->GetAttribute("Cardinality",dest.cardinality);
+ dest.ParseCardinality();
+ obj->GetAttribute("dstRolename",dest.name);
+ }
+}
+
+
+//////////////////////////////CConstraintBuilder//////////////////////////////
+
+IMPLEMENT_CUSTOMATOM(CConstraintBuilder, CBuilderAtom, "Constraint")
+
+void CConstraintBuilder::Initialize()
+{
+ CBuilderAtom::Initialize();
+ GetAttribute("ConstraintDescription", desc);
+ desc.Replace( "\"" , "\\\"" );
+ GetAttribute("ConstraintEqn", expr);
+ expr.Replace( "\n" , "\\n" );
+ expr.Replace( "\r" , "\\r" );
+ expr.Replace( "\"" , "\\\"" );
+};
+
+void CConstraintBuilder::BuildUML(::Uml::Class ¨_class)
+{
+ ::Uml::Constraint c = ::Uml::Constraint::Create(uml_class);
+ c.name() = (LPCTSTR) GetName();
+ c.description() = (LPCTSTR) desc;
+ c.expression() = (LPCTSTR) expr;
+}
+
+
+//////////////////////////////CConstraintDefinitionBuilder//////////////////////////////
+
+IMPLEMENT_CUSTOMATOM(CConstraintDefinitionBuilder, CBuilderAtom, "ConstraintDefinition")
+
+void CConstraintDefinitionBuilder::Initialize()
+{
+ CBuilderAtom::Initialize();
+
+ GetAttribute( "DefinitionEqn", expr );
+ expr.Replace( "\n" , "\\n" );
+ expr.Replace( "\r" , "\\r" );
+ expr.Replace( "\"" , "\\\"" );
+
+ CString sStereo;
+ GetAttribute( "DefinitionStereo", sStereo );
+ stereo = sStereo == "method";
+
+ GetAttribute( "DefinitionRetType", retType );
+
+ GetAttribute( "DefinitionParamList", paramList );
+ paramList.Replace( ",", ";" );
+};
+
+void CConstraintDefinitionBuilder::BuildUML(::Uml::Class ¨_class)
+{
+ ::Uml::ConstraintDefinition c = ::Uml::ConstraintDefinition::Create(uml_class);
+ c.name() = (LPCTSTR) GetName();
+ c.expression() = (LPCTSTR) expr;
+ c.stereotype() = ( stereo ) ? "method" : "attribute";
+ c.returnType() = (LPCTSTR) retType;
+ c.parameterList() = (LPCTSTR) paramList;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Writing back information to config
+/////////////////////////////////////////////////////////////////////////////////////
+CString CComponent::GetFilePath(CBuilder &builder, CBuilderObject *focus, char *FILE_EXT, char *UDM_FILTER)
+{
+ CBuilderFolder *root = builder.GetRootFolder();
+/* IMgaProject *proj = builder.GetProject();
+ CComPtr<IMgaMetaProject> mproj;
+ COMVERIFY( proj->get_RootMeta(&mproj));
+ CBstr pn;
+ COMVERIFY( mproj->get_Name(pn) );
+ CString paradigmName = pn;
+ if(paradigmName == "UMLModelTransformer")
+ { isUMT = true;
+*/
+ if(isUMT)
+ {
+ CBuilderFolder *root = builder.GetRootFolder();
+ const CBuilderFolderList *subfolders = root->GetSubFolders();
+ CBuilderModel *theCfg;
+ if(focus != NULL && focus->GetKindName() == "Configuration")
+ theCfg = BUILDER_CAST(CBuilderModel, focus);
+ else
+ { POSITION spos = subfolders->GetHeadPosition();
+ CBuilderModelList configs;
+ while(spos)
+ {
+ CBuilderFolder *subfolder = subfolders->GetNext(spos);
+ if(subfolder->GetKindName() != "Configurations")
+ continue;
+
+ const CBuilderModelList *cfgs = subfolder->GetRootModels();
+ POSITION cmpos = cfgs->GetHeadPosition();
+ while(cmpos)
+ {
+ CBuilderModel *curr_model = cfgs->GetNext(cmpos);
+ if ( curr_model->GetKindName() == "Configuration")
+ configs.AddTail( curr_model);
+ }
+ }
+ if(configs.GetCount() == 0)
+ { throw int_exception("Uml2Xml Error: No Configuration model found. Use UMT Master Interpreter.");
+ }
+ else if(configs.GetCount() > 1)
+ { throw int_exception("Uml2Xml Error: More than one Configuration model found. Either Start interpretation from one or delete the others.");
+ }
+ else
+ { theCfg = configs.GetHead();
+ }
+ }
+
+ CBuilderAtom *theMetaIcon;
+ const CBuilderAtomList *mis = theCfg->GetAtoms("MetaInformation");
+ if(!mis || mis->GetCount() == 0)
+ theMetaIcon = theCfg->CreateNewAtom("MetaInformation");
+ else
+ theMetaIcon = mis->GetHead();
+ CString cfgFileName;
+ CString cfgDirName;
+ theCfg->GetAttribute("ConfigFile",cfgFileName);
+ if(cfgFileName == "" || cfgFileName.GetLength() <3 || cfgFileName.GetAt(1) != ':')
+ { throw int_exception("Uml2Xml Error: Config file name is not absolute. Run UMT Master interpreter.");
+ }
+
+ int p = cfgFileName.ReverseFind('\\');
+ cfgDirName = cfgFileName.Left(p+1);
+
+ CString transFileName;
+ theMetaIcon->GetAttribute("UdmProjectFile",transFileName);
+ if(transFileName == "")
+ { throw int_exception("Uml2Xml Error: Udm file is blank. Run UMT Master interpreter.");
+ }
+
+ CString transFilePath = cfgDirName + transFileName;
+ CString transDirName;
+
+ p = transFilePath.ReverseFind('\\');
+ transDirName = transFilePath.Left(p+1);
+
+ if(CreateDirectory((LPCSTR)transDirName, NULL)==0)
+ { int le = GetLastError();
+ if(le != 183)
+ { LPTSTR lpMsgBuf;
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, le, 0, (LPTSTR) &lpMsgBuf, 0, NULL );
+ CString msg = "Uml2Xml Error: Unable to create directory " + transDirName + "\n";
+ msg += (LPCSTR)lpMsgBuf;
+ LocalFree(lpMsgBuf);
+ throw int_exception(std::string((LPCSTR)msg));
+ }
+ }
+ SetCurrentDirectory((LPCSTR)transDirName);
+ return transFilePath;
+ }
+ else
+ { //static char UDM_FILTER[] = "XML files (*.xml)|*.xml";
+ CFileDialog cfdlg(false, FILE_EXT, root->GetName(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, UDM_FILTER);
+ cfdlg.m_ofn.lpstrTitle = "UDM Meta File Location";
+ if (cfdlg.DoModal() != IDOK)
+ { throw int_exception("");
+ }
+ return cfdlg.GetPathName();
+ }
+}
+////////////////////////////////////////////////////////////////////////////////////////////
More information about the Mobies-commit
mailing list