how to create an object (call the constructor) from a BOM member in a BAL rule? IBM ODM - ibm-odm

I have requirement in BAL rule to create objects and add them to a list
For instance, Customer is a class with below members
1. Name
2. Location
Based on the 'if' condition of the BAL rule, need to create objects of Type Customer and add them to Customerlist.
I tried to create objects by creating method in the Customer class in BOM editor by following steps provided under this link
how to create an object (call the constructor) from a BOM member on a decision table action column?
But I'm getting below error:
'Incompatible value in the 'return' instruction'
Can anyone please provide detailed steps to create objects and add them to a list in BAL?

Constructors are not directly verbalized in the BOM. You can create a method in XOM which creates the object via constructor and you can map this method onto BOM and verbalize it to be used in rule artifacts.

My suggestion to your scenario would be:
Create a verbalization in the XOM to receive the elements that will be added to the main list (Composite pattern).
Verbalize it
Add it in your Action Column (i.e. within a Decision Table)
I used this approach with great success in several scenarios, with no lack of performance.
Hope this helps.

Create an object and adding it to a list should be two separate methods.
Create: Assuming you followed the recipe for the link you provided, you should have a BOM method called createCustomer() on the Customer BOM class. Since there is no XOM to back that BOM method, you must supply B2X code for that method. Most people refer to such as a method as a virtual BOM method. It would be helpful to see the B2X code for that method. Are your BOM and XOM classes the same type? If not, you would have specified an execution name for the Customer BOM class. In that case, you may need to cast the return value of the createCustomer() BOM method to the Customer BOM class.
// Verbalize as: new customer
Customer Customer.createCustomer()
return (Customer) new OtherCustomerClassFromXOM();
Add: Define another virtual BOM method on some class, and name the method addCustomer(Customer customer). Usually it would be on the class that contained the list variable as a member. But if the list variable is a global variable (i.e., a ruleset variable), then the method could be a static member on any class, even your Customer class.
// Verbalize as: add {0} to {1}
void Customer.addCustomer(Customer customer, java.util.Collection customerList)
if (customerList == null) {
customerList = new java.util.ArrayList();
}
customerList.add(customer);

Related

How to create an object/entity XOM-BOM using lists

I need create object with an attribute that is based on a list of other objects. By default when creating a XOM using XSD, Rule Designer assigns lists as vector of java object. I need some orientation how to verbalize and instantiate the list and add the object members.
You need to create a separate Class of Objects you want to store in the list. After that you have to create a list type variable in your Request Class. "listOfMyObjects" as an example. Then, after updating your BOM instance, you will see a new member in it. You can verbolize it as you need. "{list of my objects} from {this}", where the "my object" itself have to be verbolized as well, as an example.
After that you can work with the list in your rules like that:
definition: make this object equals to any of My Object from list of my objects
if: your condition
then: add new object to list of my objects

How to specify the return type of a method that returns a list of values in StarUML?

I have two classes (say Database and Record). In Database class, I have a method named getRecords() that returns a list of Record objects.
In Java, the above method can be written as:
List<Record> getRecords(){..}
In StarUML, while designing Class diagram, I tried giving
+getRecords() : Record[0..*]
But StarUML refused to create method like above. When I tried with the one below, it works
+getRecords() : ArrayList<Record>
But this is more specific to Java. I want to implement something like Record[0..*] in StarUML. Is it possible to write methods in such format or the Java style of return type is the only solution ?
I don't know why StarUML refuses to parse the text, but you can still create it via model.
Add the operation and call it getRecords()
Right-click on the operation (in diagram or model), and select Add > Parameter
Select parameter in Model Explorer (probably the parameter is already selected when you created it) and set the direction parameter to return. This is how UML represents return types.
(Configure the type, multiplicity, and anything else you need.)
Note that the default collection in UML is Set, so you should check isOrdered, as List is an ordered collection.

How to access certain EStructuralFeatures of an EMF Model?

I know that there are ways to access an EAttribute of an Eclipse EMF model by its featureID or by its name via different indirect approaches. For that I found the following: Eclipse EMF: How to get access EAttribute by name?
But what if I don't know the name of the attribute I want to get? Let's say, based on the design, the model has some fixed attributes by the developer, along with the features that can be set dynamically by the user.
So, for the time being I use the getEAllStructuralFeatures() and use indexes via get() to reach to the by-the-user-created attributes, since I know that the list I get will have the fixed attributes of the model as its first elements beginning with the index 0. But I find this solution unclear and inefficient. Also in some cases, that I want to work, not suitable.
E.g: IEMFEditProperty prop = EMFEditProperties.list(editingDomain, EMFMODELPackage.Literals.EMFMODEL.getEAllStructuralFeatures().get(X));
Do you know a solution or a workaround for this problem? As far as I can see, there are no direct methods to get such dynamically created features of the model.
Every help will be appreciated.
I have been working on a similar case recently where I first tried to define an EStructuralFeature to access exactly the setting/attribute of the object that I needed.
But if you look at how things work internally in ECore, you will find out, that there is no way this will ever work, since the indices are bound to the object identity of the EStructuralFeature objects created at runtime for the specific context (i.e. EClass instance).
My approach was then to either inspect the features proposed by EClass.getEAllStructuralFeatures or to iterate over the features and inspect the object returned by EObject.eGet for this very feature (where EClass eClass = eObject.eClass()).
Example: In a UML profile I have defined a UML Stereotype called "Bean" with a property called FactoryEntity. The property shall reference a UML Class with the Stereotype "Entity" that is closest to this very bean and for which a static factory method will be generated.
In the model I would then have one UML Class typed as Bean and one as Entity.
And for the Class typed as "Bean" I would then set a value for the attribute/property factoryEntity defined in the profile.
The question was then how the property value would be accessible in ECore. I ended up iterating the List of available EStructuralFeature of the EClass of the EObject and checking the type of the object returned by eGet.
final EObject eObject = (EObject) holdingClass.getValue(stereotype, stereoTypePropertyName);
final EList<EStructuralFeature> allEStructFeats = eObject.eClass().getEAllStructuralFeatures();
for(EStructuralFeature esf : allEStructFeats)
{
final Object o = eobject.eGet(esf);
if(o instanceof org.eclipse.uml2.uml.Class)
{
return (org.eclipse.uml2.uml.Class) o;
}
}
Maybe that is not the most elegant way to access structural features but it is the only one I thought was robust enough to last.
Please let me know if you have any suggestions on how to improve this.

System.ComponentModel.BindingList: Add(object) vs. AddNew()

What is the difference between the System.ComponentModel.BindingList methods Add(object) and AddNew()? The MSDN documentation says this:
Add: Adds an object to the end of the Collection<T>.
AddNew: Adds a new item to the collection.
It seems like both methods add an item to the collection, but Add(object) does it in one shot whereas AddNew() is slightly more complicated. My tests with Add(object) seem to be working, but I want to know if I am using the correct method.
So what is the difference between these methods?
AddNew() creates the object for you (that's why it doesn't have a parameter).
It's designed to be used by grids, which don't know how to create a new object to pass to Add().
AddNew() is very handy (it’s the well-known Factory design pattern) when you implement a class derived of BindingList().
It allows your code to initialize new items with values that depend on the list itself - e.g. a foreign key to the parent object if the binding list contains a list of children.

Can we get declared properties of a Groovy class by its order?

I created a plain Groovy class (i.e Person class)with some properties. Now I want to get those declared attributes (which I've defined in my class) with their order, but I don't know how to do it.
I've tried to use Person.metaClass.getProperties() but it retrieves not only declared properties but also built-in Groovy ones.
Could you please help me on this: just get declared properties by its order when declaring.
Thank you so much!
I can't see a use case, but the compiler could reorder all fields declaration while creating bytecode. I'm pretty sure ordering is not a constraint on fields though it should mostly be the case for not modified/enhanced class
As per the JVM spec, generated fields should be marked SYNTHETIC (like generated methods) in the bytecode, so you can test with :
Person.getDeclaredFields().grep { !it.synthetic }
and filter the base Groovy fields like ClassInfo,metaClass and others beginning by __timestamp
But I'm not a specialist, there could be another way I don't think of
There was a question about this on the mailing list back in February of this year
The answer is, no. There is no way to get properties in the order they are declared in the class without doing some extra work.
You could parse the source file for the class, and generate an ordered list of property names from that
You could write a custom annotation, and annotate the fields with this annotation ie: #Order(1) String prop
You could make all of the classes where this matters implement an interface which forces them to have a method that returns the names of the properties in order.
Other than that, you probably want to have a re-think :-(

Resources