SMP2 Code Generation/ 40777 0 0 0 12460763424 7535 5 SMP2 Code Generation/Deployment/ 40777 0 0 0 12460757453 11662 5 SMP2 Code Generation/Deployment/RegAsm.txt 100777 0 0 366 12460757542 13665 0 If compiled as a .NET DLL, such as C# or VB.NET, register the DLL using the RegAsm command from the command prompt; for example:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe "C:\Program Files\MyCompany\EAAddin\EAAddin.dll" /codebase SMP2 Code Generation/Deployment/RegistryEntry.reg 100777 0 0 434 12157066155 15267 0 ÿþW i n d o w s R e g i s t r y E d i t o r V e r s i o n 5 . 0 0
[ H K E Y _ C U R R E N T _ U S E R \ S o f t w a r e \ S p a r x S y s t e m s \ E A A d d i n s \ S M P 2 C o d e G e n ]
@ = " S M P 2 C o d e G e n . S M P 2 C o d e G e n C l a s s "
SMP2 Code Generation/Deployment/SMP2_Template.xml 100777 0 0 230720 12460757653 15126 0
SMP2 Code Generation/README.txt 100777 0 0 2644 12462220267 11334 0 This document describes the Simubox’s code generation tool for SMP2 compliant components as part of the thesis
“THE ROLE OF COMPUTATIONAL STEERING IN SPACE ENGINEERING ACTIVITIES ASSISTED BY MODELLING AND SIMULATION”
developed by Leandro Toss Hoffmann in 2014, under supervision of Prof. Leonel Fernando Perondi, Ph.D.
at Brazilian Institute for Space Research (INPE).
The tool is implemented as an Enterprise Architect 9 add-in and currently supports the following features:
- C++ header file generation for Models derived from Smp::Management::IManagedModel;
- Corresponding C++ implementation file;
- Construction of projects for building the model libraries (.dll); and
- SMP2 Assembly artefact production.
The contents of the package is:
- SUM.pdf: Software User Manual
- Deployment/: diretory containing information on how to deploy the AddIn and the SMP2 template for EA.
- SMP2CodeGen: .NET project for building the Addin DLL.
- Test: Test plan documentation, example of an EA project, and examples of generated artefacts.
Copyright (c) 2014, Leandro Toss Hoffmann (INPE)>
Permission to use, copy, modify, and distribute this model for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
This component is provided “as is” and the author disclaims all warranties with regard to it.
SMP2 Code Generation/SMP2CodeGen/ 40777 0 0 0 12460761556 11507 5 SMP2 Code Generation/SMP2CodeGen/AssemblyGenClass.cs 100777 0 0 44264 12460761116 15357 0 // Copyright (c) 2014, Leandro Toss Hoffmann (INPE)>
// Permission to use, copy, modify, and distribute this model for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
// This model is provided "as is" and the author disclaims all warranties with regard to it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EA;
namespace SMP2CodeGen
{
class AssemblyGenClass
{
string path = "";
EA.Repository Repository;
Diagram diagram;
System.IO.StreamWriter file;
public void GenerateAssembly(EA.Repository a_Repository, string Location)
{
Repository = a_Repository;
diagram = Repository.GetCurrentDiagram();
if (diagram == null)
{
MessageBox.Show("Please, select a Diagram from the Tree View");
return;
}
// Gets the path to write files
CodeGenDialog dialog = new CodeGenDialog();
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK)
path = dialog.GetPath();
else
return;
file = new System.IO.StreamWriter(@path + "\\" + diagram.Name.Trim() + ".asb", false);
String idents = "";
// Assembly Header
string datetime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss+HH:mm");
file.WriteLine("");
file.WriteLine("");
idents += ("\t");
file.WriteLine(idents + "Root Model to hold unlimited number of IModels");
file.WriteLine(idents + "");
foreach (EA.DiagramObject obj in diagram.DiagramObjects)
{
Element element = Repository.GetElementByID(obj.ElementID);
// Checks if the model is eligible to be a root instance
// Is a object instance, has a name and is not contained by other objet
if (element.Type != "Object" || element.Name == "" || IsRootModelElement(element) == false)
continue;
// Class element of instantiated object
Element elementClass = Repository.GetElementByID(element.ClassifierID);
file.WriteLine(idents+"");
idents +=("\t");
ProcessModelInstance(element, elementClass, "ModelsContainer", idents); // RootModel's container. This should be more flexible in the future #??#
idents = idents.Remove(0, 1);
file.WriteLine(idents+"");
}
idents = idents.Remove(0, 1);
file.WriteLine("");
file.Close();
}
private void ProcessModelInstance(Element element, Element elementClass, string container, String idents)
{
string packageName = Repository.GetPackageByID(elementClass.PackageID).Name;
if(element.Notes != "")
file.WriteLine(idents+"" + element.Notes + "");
file.WriteLine(idents+"");
ProcessComposite(element, idents);
ProcessFieldValues(element, elementClass, packageName, idents);
ProcessFieldLinks(element, elementClass, packageName, idents);
// #??# Process Event Links (TODO)
ProcessReferences(element, elementClass, packageName, idents);
file.WriteLine(idents+"");
}
private void ProcessComposite(Element element, string idents)
{
foreach (Connector conn in element.Connectors)
{
if (conn.Stereotype != "SMP2composite" || conn.Type != "Aggregation")
continue;
Element client = Repository.GetElementByID(conn.ClientID);
if (client == null || client.Name == element.Name)
continue;
// Checks if the models is contained by only one object
if (HasElementSingleParent(client) == false)
{
string errorMsg = "!!!!!!!!!!!!!!!!!ERROR: element " + client.Name + " has multiple parents!";
file.WriteLine(errorMsg);
MessageBox.Show(errorMsg);
return;
}
// container name
string container = conn.ClientEnd.Role;
// Class element of client object
Element clientClass = Repository.GetElementByID(client.ClassifierID);
file.WriteLine(idents + "");
idents += ("\t");
ProcessModelInstance(client, clientClass, container, idents);
idents.Remove(0, 1);
file.WriteLine(idents + "");
}
}
private void ProcessFieldValues(Element element, Element elementClass, string packageName, String idents)
{
foreach (EA.Attribute att in elementClass.Attributes)
{
if (att.Default == "")
continue;
// If there is a default value for the instance, skip the value from the model
string defaultValue = UtilClass.GetTagValue(element.TaggedValues, att.Name);
if (defaultValue != "")
continue;
defaultValue = att.Default;
if (att.IsCollection && att.UpperBound != "")
{
file.WriteLine(idents + "");
string[] values = defaultValue.Split(',');
int i = 0;
idents += ("\t");
foreach (string value in values)
{
file.WriteLine(idents + "");
i++;
}
idents = idents.Remove(0,1);
file.WriteLine(idents + "");
} else
file.WriteLine(idents + "");
}
// Takes the default value of the instance, if specified by a Object's tagged value
foreach (TaggedValue tag in element.TaggedValues)
{
// Checks if the tag exist as a model's attribute
bool found = false;
bool array = false;
string attType="";
foreach (EA.Attribute att in elementClass.Attributes)
{
if (att.Name == tag.Name)
{
found = true;
attType = att.Type;
if (att.IsCollection && att.UpperBound != "")
array = true;
break;
}
}
if (!found)
continue;
string defaultValue = tag.Value;
if (array)
{
file.WriteLine(idents + "");
string[] values = defaultValue.Split(',');
int i = 0;
idents += ("\t");
foreach (string value in values)
{
file.WriteLine(idents + "");
i++;
}
idents = idents.Remove(0, 1);
file.WriteLine(idents + "");
}
else
file.WriteLine(idents + "");
}
}
private void ProcessFieldLinks(Element element, Element elementClass, string packageName, String idents)
{
foreach (Element port in element.EmbeddedElements)
{
// Only considerer ports without exposed interfaces
if (port.Type != "Port" || port.EmbeddedElements.Count > 0 || port.Stereotype == "SMP2interface")
continue;
//int fieldId = 0;
foreach (Connector conn in port.Connectors)
{
if (conn.Stereotype != "SMP2fieldLink")
continue;
// Gets the reference to the source's port
Element outputField = Repository.GetElementByID(conn.ClientID); // EA names the source as client, but in this case, the client is the output field
if (outputField == null || outputField.ParentID == 0 || outputField.Type != "Port" || outputField.Name == port.Name)
continue;
// And finally gets the reference to the port's object (Object)
Element source = Repository.GetElementByID(outputField.ParentID);
if (source == null || source.Type != "Object")
continue;
// Check if the link is based on input and onput fields
// #??# TODO: (1) get port's object; (2) then object's classifier; (3) then classifier's port; (4) then port's tag?
if (false)
{
string errorMsg = "!!!!!!!!!!!!!!!!!ERROR: fails to link fields " + outputField.Name + " -> " + port.Name + "!";
file.WriteLine(errorMsg);
MessageBox.Show(errorMsg);
return;
}
string instanceName = element.Name;
string sourceName = source.Name;
Element sourceClass = Repository.GetElementByID(source.ClassifierID);
string sourceClassName = sourceClass.Name;
string sourcePackage = Repository.GetPackageByID(sourceClass.PackageID).Name;
string inputFieldName = port.Name;
string outputFieldName = outputField.Name;
//fieldId++;
//file.WriteLine(idents + "");
file.WriteLine(idents + "");
idents += "\t";
{
string descr = conn.Notes;
if(descr != "")
file.WriteLine(idents + "" + descr + "");
file.WriteLine(idents + "");
file.WriteLine(idents + "");
file.WriteLine(idents + "");
}
idents = idents.Remove(0, 1);
file.WriteLine(idents + "");
}
}
}
private void ProcessReferences(Element element, Element elementClass, string packageName, String idents)
{
foreach (Element port in element.EmbeddedElements)
{
// Only considerer ports with Required SMP2interfaces
if (port.Type != "Port" || port.EmbeddedElements.Count <= 0 || port.Stereotype != "SMP2interface")
continue;
foreach (Element reqInt in port.EmbeddedElements)
{
if (reqInt.Type != "RequiredInterface")
continue;
string container = port.Name;
string objInstance = element.Name;
int containerId = 0;
foreach (Connector conn in reqInt.Connectors)
{
if (conn.Stereotype != "SMP2interfaceLink")
continue;
// Gets the reference to the assembly's target (Provided Interface)
Element e = Repository.GetElementByID(conn.SupplierID);
if (e == null || e.ParentID == 0 || e.Type != "ProvidedInterface")
continue;
// Gets the reference to the interface's port (Port)
e = Repository.GetElementByID(e.ParentID);
if (e == null || e.ParentID == 0 || e.Type != "Port")
continue;
// And finally gets the reference to the port's object (Object)
e = Repository.GetElementByID(e.ParentID);
if (e == null || e.Type != "Object")
continue;
string provider = e.Name;
containerId++;
file.WriteLine(idents + "");
idents += "\t";
{
string descr = conn.Notes;
if (descr != "")
file.WriteLine(idents + "" + descr + "");
file.WriteLine(idents + "");
file.WriteLine(idents + "");
}
idents = idents.Remove(0, 1);
file.WriteLine(idents + "");
}
}
}
}
private bool IsRootModelElement(Element element)
{
// Assumes that a root model can be a client in a composite relation (i.e. a root model is not contained by other model).
foreach (Connector conn in element.Connectors)
{
if (conn.Stereotype != "SMP2composite" || conn.Type != "Aggregation")
continue;
Element client = Repository.GetElementByID(conn.ClientID);
if (client == null)
continue;
if (client.Name == element.Name)
return false;
}
return true;
}
private bool HasElementSingleParent(Element element)
{
int parents = 0;
foreach (Connector conn in element.Connectors)
{
if (conn.Stereotype != "SMP2composite" || conn.Type != "Aggregation")
continue;
Element client = Repository.GetElementByID(conn.ClientID);
if (client == null)
continue;
if (client.Name == element.Name)
parents ++;
}
if(parents > 1)
return false;
return true;
}
} // end class
} // end namespace
SMP2 Code Generation/SMP2CodeGen/bin/ 40777 0 0 0 12460761556 12257 5 SMP2 Code Generation/SMP2CodeGen/bin/Debug/ 40777 0 0 0 12460761556 13305 5 SMP2 Code Generation/SMP2CodeGen/CodeGenDialog.cs 100777 0 0 3771 12460761111 14555 0 ///////////////////////////////////////////////////////////////////////////////
// INSTITUTO NACIONAL DE PESQUISAS ESPACIAIS
// Simubox - SMP2 Model Development Kit
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, Leandro Toss Hoffmann (INPE)>
// Permission to use, copy, modify, and distribute this model for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
// This model is provided "as is" and the author disclaims all warranties with regard to it.
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SMP2CodeGen
{
public partial class CodeGenDialog : Form
{
public CodeGenDialog()
{
InitializeComponent();
}
public string GetPath()
{
return textPath.Text;
}
private void buttonPath_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
textPath.Text = folderBrowserDialog1.SelectedPath;
}
if (textPath.Text != "")
buttonGenerate.Enabled = true;
else
buttonGenerate.Enabled = false;
}
private void buttonGenerate_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
private void onTextPath_changed(object sender, EventArgs e)
{
if(textPath.Text != "")
buttonGenerate.Enabled = true;
else
buttonGenerate.Enabled = false;
}
}
}
SMP2 Code Generation/SMP2CodeGen/CodeGenDialog.Designer.cs 100777 0 0 12537 12460761103 16335 0 // Copyright (c) 2014, Leandro Toss Hoffmann (INPE)>
// Permission to use, copy, modify, and distribute this model for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
// This model is provided "as is" and the author disclaims all warranties with regard to it.
namespace SMP2CodeGen
{
partial class CodeGenDialog
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
this.buttonPath = new System.Windows.Forms.Button();
this.buttonGenerate = new System.Windows.Forms.Button();
this.textPath = new System.Windows.Forms.TextBox();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67.30769F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 32.69231F));
this.tableLayoutPanel1.Controls.Add(this.buttonPath, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.textPath, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.buttonGenerate, 1, 1);
this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 12);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 36F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 64F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(260, 84);
this.tableLayoutPanel1.TabIndex = 0;
//
// buttonPath
//
this.buttonPath.Location = new System.Drawing.Point(178, 3);
this.buttonPath.Name = "buttonPath";
this.buttonPath.Size = new System.Drawing.Size(75, 23);
this.buttonPath.TabIndex = 0;
this.buttonPath.Text = "Select Path";
this.buttonPath.UseVisualStyleBackColor = true;
this.buttonPath.Click += new System.EventHandler(this.buttonPath_Click);
//
// buttonGenerate
//
this.buttonGenerate.Enabled = false;
this.buttonGenerate.Location = new System.Drawing.Point(178, 33);
this.buttonGenerate.Name = "buttonGenerate";
this.buttonGenerate.Size = new System.Drawing.Size(75, 23);
this.buttonGenerate.TabIndex = 1;
this.buttonGenerate.Text = "Generate";
this.buttonGenerate.UseVisualStyleBackColor = true;
this.buttonGenerate.Click += new System.EventHandler(this.buttonGenerate_Click);
//
// textPath
//
this.textPath.Location = new System.Drawing.Point(3, 3);
this.textPath.Name = "textPath";
this.textPath.Size = new System.Drawing.Size(169, 20);
this.textPath.TabIndex = 2;
this.textPath.TextChanged += new System.EventHandler(this.onTextPath_changed);
//
// CodeGenDialog
//
this.AcceptButton = this.buttonGenerate;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 76);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "CodeGenDialog";
this.Text = "SMP2 Code Generation";
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Button buttonPath;
private System.Windows.Forms.TextBox textPath;
private System.Windows.Forms.Button buttonGenerate;
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
}
} SMP2 Code Generation/SMP2CodeGen/CodeGenDialog.resx 100777 0 0 13611 12157236520 15147 0 
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e08917, 17