Get value of behaviour property from CallOperationAction in EA - enterprise-architect

Hi if we drag an drop an operation into an activity diagram it would create as a CallOperationAction type of action. In CallOperationAction we have a property called behaviour under the call tab .
The values which we give here will be stored in the table t_object.ClassifierGUID.But unfortunately there isn't any property called ClassifierGUID in the element class. Is there any other way to get the value other than querying ?
I even tried the classifierID property but no luck :(

No that property is not exposed by the API, but you can still get it.
In my framework I use the following code in the class CallOperationAction
/// <summary>
/// The operation to be invoked by the action execution.
/// </summary>
public UML.Classes.Kernel.Operation operation {
get{
// first get the operations guid which is stored in the Classifier_guid column
XmlDocument operationGUIDxml = this.model.SQLQuery(#"select o.Classifier_guid from t_object o
where o.Object_ID = " + this.id.ToString());
XmlNode operationGUIDNode = operationGUIDxml.SelectSingleNode(this.model.formatXPath("//Classifier_guid"));
return this.model.getOperationByGUID(operationGUIDNode.InnerText);
}
}

Related

Access shadow properties in IMaterializationInterceptor

Using the the new IMaterializationInterceptor, is it possible to access shadow properties of executed queries? When inspecting the query string with ToQueryString() I can see that all shadow properties are queried, but they are null when accessed in the interceptor.
public class MyInterceptor : IMaterializationInterceptor
{
public object InitializedInstance(MaterializationInterceptionData materializationData, object instance)
{
var entry = materializationData.Context.Entry(instance);
entry.CurrentValues["SomeOtherProperty"] = entry.CurrentValues["MyShadowProperty"];
}
}
During interception object is not yet registered in ChangeTracker and you cannot access Entry values. For this situation new interception API has MaterializationInterceptionData instance as parameter which contains values retrieved from database.
Using this class you can access to Shadow Property values:
materializationData.GetPropertyValue("MyShadowProperty");

WF 4 different IDs on the same activities

Due to a strange behavior in my application, i am forced to reload the designer before calling WorkflowInvoker.Invoke on it.
wd.Flush();
SaveXamlFile(currentXamlPath, wd.Text);
I just flush the content, and write the wd.Text to a file.
//cleanup the previous designer
if (wd != null)
{
wd.ModelChanged -= new EventHandler(Designer_ModelChanged);
}
//designer
wd = new WorkflowDesigner();
designerArea.Child = wd.View;
this.DebuggerService = this.wd.DebugManagerView;
//property grid
propertiesArea.Child = wd.PropertyInspectorView;
//event handler
wd.ModelChanged += new EventHandler(Designer_ModelChanged);
//error service
wd.Context.Services.Publish<IValidationErrorService>(errorService);
wd.Context.Items.Subscribe<Selection>(OnItemSelected);
I then recreate a new instance of the WorkflowDesigner and load the previously saved file.
wd.Load(currentXamlPath);
I call WorkflowInvoker.Invoke and inside my custom activity which derives from CodeActivity i am taking it's name:
OK, fine until now, i have a 1.2 Id there.
I want to update some of the fields of this Activity via its ModelItem in order to display them in the GUI right away.
IEnumerable<ModelItem> activityCollection = currentWorkflow.Find(currentWorkflow.Root, typeof(Activity));
But here comes the issue:
I can't find that my Activity id there. Is now transformed from 1.2 to 2. Why is this happening?
I've tried to send a this reference from my Activity Execute method and searched it by ref but all i get is nulls.
ModelItem temp = activityCollection.FirstOrDefault((m) => (m.GetCurrentValue() == a));
I am sure i am missing something here, but i can't figure out what is it.
I found a workaround on this :
On my custom activities i am adding a Guid property and I override CacheMetadata:
public Guid unique { get; set; }
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
if (unique.ToString() == "00000000-0000-0000-0000-000000000000")
unique = Guid.NewGuid();
}
When i drag the activity on the designer, the unique id is generated. I make sure that this portion of code is called only once.
Why is that?
Because after a call like this,
IEnumerable<ModelItem> activityCollection = currentWorkflow.Find(currentWorkflow.Root, typeof(Activity));
each model in the activity collection contains that property ( unique of type Guid ) with the value of the first assignment made in CacheMetadata. I can't explain this behavior, i've just taken it into consideration.
Who calls again that CacheMetadata ? something like this :
Activity root = ActivityXamlServices.Load(currentXamlPath);
WorkflowInspectionServices.CacheMetadata(root);
And so, the Guid is changed and its utility is gone.
This way, i am able to get the ModelItem for my custom activity and update some of its properties which are immediately displayed in the GUI.

Entity Framework refuses to save value on new column

I just changed our database, adding a new column to a table and setting it as a foreign key. We're using EF4 Database first, so I updated the model from the DB, added my new field to the DTOs and everything looked great until I tried to save data to it.
The new column is called DiaryEventId, and because it's a FK there's also a virtual property on the object called DiaryEvent. Here's what the code looks like:
public void SaveDocument(Guid CaseId, string diaryText, string ActivityType)
{
Guid eventTypeId = RepositoryHelper.GetDiaryEventFromCache("Document Uploaded", _commonQueryContext);
//this wanders off and created a diary event object, adds it to
//the context and returns its ID
Guid diaryId = RepositoryHelper.AuditEvent(CaseId, diaryText, commonUpdateContext);
Entities.DocumentMetadata docData = new Entities.DocumentMetadata()
{
Id = Guid.NewGuid();,
ActivityType = activityType,
DiaryEventId = diaryId
};
_commonUpdateContext.DocumentMetadatas.Add(docData);
_commonUpdateContext.SaveChanges();
}
This compiles and runs fine, and when you step through it it appears to function as expected - diaryId is generated and set on the object. But in the DB, it always appears as null.
I've tried calling SaveChanges after adding the diary event (to make sure the key has something to connect to) and I've tried adding the actual DiaryEvent object to the virtual property rather than just the ID - both have the same effect.
When I watch what's going on in SQL Profiler, I can see that the INSERT statement simply ignores my new column completely - it's not listed in the insert columns at all.
Really got no idea what's going on. Any ideas?
Try modifying the object after adding it to the context, just as a test.
_commonUpdateContext.DocumentMetadatas.Add(docData);
Entities.DocumentMetadata docData = new Entities.DocumentMetadata()
{
Id = Guid.NewGuid();,
ActivityType = activityType,
DiaryEventId = diaryId
};
_commonUpdateContext.SaveChanges();
Or is this perhaps a typo?
Entities.DocumentMetadata docData = new Entities.DocumentMetadata()
{
Id = Guid.NewGuid();, <-------------typo?
Beyond that, it will require a bit of info on how you have your entities mapped out. Is there a navigation property between DiaryEvent and DocumentMetadata? Is the key defined as nullable (I'm assuming it is)? Is ActivityType getting persisted correctly?

How can I get access to the current test method in NUnit

TestContext.CurrentContext.Test has several properties like FullName which can be parsed to get the current test method within NUnit. However, these don't help at all when the test's name is overridden using the TestName property on the TestCase attribute.
Is there a simple way to get the MethodInfo for the current test method from within an NUnit test? I can't simply use a stack trace, because I need this information in SetUp and TearDown when the test method is not on the stack.
I'm using NUnit 2.6.2
One thing that comes to my mind is writing a custom NUnit EventListener addin.
Then you could hook into the runcycle of the test runner and at least on the TestStarted overload you will have the TestName object. This won't have the MethodInfo available directly, but you may get it by playing around with the given properties there.
Good luck!
NUnit by default does not provide such information - but it can be queries via private fields and properties. Following code could be used for example (Tested with NUnit 3.13.2):
/// <summary>
/// Accesses private class type via reflection.
/// </summary>
/// <param name="_o">input object</param>
/// <param name="propertyPath">List of properties in one string, comma separated.</param>
/// <returns>output object</returns>
object getPrivate(object _o, string propertyPath)
{
object o = _o;
var flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
foreach (var name in propertyPath.Split('.'))
{
System.Type type = o.GetType();
if (char.IsUpper(name[0]))
o = type.GetProperty(name, flags).GetValue(o);
else
o = type.GetField(name, flags).GetValue(o);
}
return o;
}
[SetUp]
public void EachSpecSetup()
{
var mi = (MemberInfo)getPrivate(TestContext.CurrentContext.Test, "_test.Method.MethodInfo");
// Alternative method - using Exposed nuget package:
//dynamic test = Exposed.From(TestContext.CurrentContext.Test)._test;
//dynamic method = Exposed.From(test)._method;
FactAttribute attr = mi.GetCustomAttribute<FactAttribute>();
string path = attr.FilePath;
string funcName = attr.FunctionName;
}
Like mentioned in code above it's also possible to use Exposed.From - but main example should be theoretically faster.
Code will throw exception if any field / property is not valid - and this is intentional - use Visual studio watch window to identify type / field / properties.

Saving a Hashtable using Mongo & the Play framework?

I've got a model defined like the following...
#MongoEntity
public class Ent extends MongoModel{
public Hashtable<Integer, CustomType> fil;
public int ID;
public Ent(){
fil = new Hashtable<Integer, CustomType>();
}
}
CustomType is a datatype I've created which basically holds a list of items (among other things). At some point in my web application I update the hashtable from a controller and then read back the size of the item I just updated. Like the following...
public static void addToHash(CustomType type, int ID, int key){
//First I add an element to the list I'm storing in custom type.
Ent ent = Ent.find("byID",ID).first();
CustomType element = user.fil.get(key);
if(element == null) element = new CustomType();
element.add(type);
ent.save();
//Next I reset the variables and read back the value I just stored..
ent = null;
ent = User.find("byID",ID).first();
element = ent.fil.get(ID);
System.out.println("SIZE = " + element.size()); //null pointer here
}
As you can see by my above example I add the element, save the model and then attempt to read back what I have just added and it has not been saved. The above model Ent is a minimal version of the entire Model I'm actually using. All other values in the model including List's, String's, Integer's etc. update correctly when they're updated but this Hashtable I'm storing isn't. Why would this be happening and how could I correct it?
You should probably post on the play framework forum for better help..
Alternatives for a mongodb framework are morphia and springdata which have good documentation.
Not sure how Play maps a hash table to a document value, but it seems it cannot update just the hash table using a mongo operator.
You should be able to mark the whole document for update which would work but slower.