I currently have project where i had to make my own DSL. I have my DSL and also the most of my Validation. I got stucked by the fact that i wanted to check if a specific word contains a number.
I wrote a grammar, which allows you to create the following code:
Category Doors belongs to Group Car_Equiptment;
Category Engine belongs to Group Car_Equiptment;
Doors properties:
-5_Doors
-4_Doors
Engine properties:
-V8 180 "PS"
-V10 200 "PS"
Here the grammer definition:
Category:
'Category' name=ID 'belongs' 'to' (group+=Group) ';'
;
PropHeader:
name=[Category] 'properties' ':'
(properties+=Properties)+
;
Properties:
'-' name=ID number=INT? description=STRING?
;
I should controll that the user doesn't choose a door property, which is over 5 Doors. I can get the properties name with out a problem but i'm missing a funtion which si helping me to check if the string contains a number. Since i have a lot of different properties i can't just make a ID only for the Doors. I have to check via Validaiotn if a property named doors is exsisting (i have this part already) and if yes is any of the string contains a number higher then 5.
Related
I am simulating an assembly process in Arena. To keep things simple, suppose a model that assigns bags to passengers.
Each entity has a different ID (Entity.SerialNumber): I would like to check which bag has been assigned to which passenger.
How could I write a log file saving the ID of passenger and ID of the assigned bag?
First you must declare an attribute for the original entity that I understand that in this case would be the passenger, for example: ID = ID + 1, then with the separate module you duplicate the original entity, now both entities can have their independent flow and when you want to put them together again you can do it with a batch module using the rule: by attribute or with a match module using the type: based on attribute.
My bot asks: 'how do you (i.e. customer) want to pay for this product?'
Customer says: 'part in cash and the difference in 48x'
What the customer is saying above is that he wants to pay in cash and use financing. And that financing should consider 48 installments.
Entities:
paymentType: {cash, financed} ; Financed includes 48x as a synonym
numInstallments: {12x, 24x, 36x, 48x} ; 48x is the number of installments desired
Using the GUI only, how to do this:
IF user says '48x' THEN simultaneously add 'financed' to the paymentType list AND set numInstallments equal to '48x' ?
Apparently the GUI doesn't allow me to do that unless I'm doing something wrong (see below the screen which allows a parameter to be mapped to an entity and notice that this dropdown apparently allows selection of a single entity and not two, which is what I need).
How to solve this problem in an easy way through the GUI?
I don't know if what you have in mind is actually feasible in this case.
What you could do is keep the intent and entities as-is and then create several conditions in the page where you fill this parameters or another page (i think this is preferred).
In that page you can put different routes where your conditions are true that modify your parameters as you wish.
For example, after asking the user how they'd like to pay, you can have a route going to a "Set parameters" page which has several routes:
First route has a condition $session.params.numeroDeParcelas != null (you know the user has asked a specific number of installments, so handle the case by setting the parameters you need in this route (under parameters in the route write paymentType : "financed")
Second route has another condition, for example $session.params.numeroDeParcelas = null (you know the user hasn't asked for financing, so set the same parameter as before to "cash")
and so on, until you've exhausted your user cases (all payment methods, possibly all types of financing).
Pay attention: the routes are always evaluated in order so make sure to keep this in mind while writing/ordering them: be specific to avoid fulfilling the wrong one by mistake (e.g. by creating compound conditions, chaining parameter checks as in $session.params.numeroDeParcelas = null AND $session.params. numInstallments = "36x"
The following is a basic drools syntax:
$customer : Customer( )
Account( ) from $customer.accounts
As far as I know the first line create a new variable and assign it to the fact.
However I can't quite understand the second line especially what the "Account()" part means...
You have written class Customer, or must know it to understand what's going on here. Presumably it contains a Collection<Account> accounts (see note), which is (by the engine) retrieved one by one so that the rule fires for each Account object contained in Customer's object.
The rule will fire once for each Account object stored in any of the collections contained in all the Customer facts in working memory, with $customer being bound to the containing Customer.
You can bind another variable to Account.
Note: It could also contain a field Account accounts, but I hope the name was chosen carefully.
I would like to know if it is possible to disable the validation for a subset of modelelements which are specified in the metamodel.
The problem is that I'm getting some validation-errors from the Xtexteditor while writting my dsl-file. So my idea is to disable the validation for exactly this modelelement.
I try to build a real simple textual notation and want to serialize the (valid) model while saving the file. The saved model is modified during the saving process, so it is
valid at the end.
Regards,
Alex
Lets beginn with the grammer:
I'am working on an imported metamodel (UML2):
import "http://www.eclipse.org/uml2/4.0.0/UML"
Then I create all the necessary parserules to define a classdiagram. In my case the problem appears
in the parserrule for associations between classes:
AssociationClass_Impl returns AssociationClass:
{AssociationClass} 'assoc' name=ID'{'
(ownedAttribute+=Property_Impl)*
'}';
And of course the parserrule for properties:
Property_Impl returns Property:
name=ID ':' type=[Type|QualifiedName]
(association=[AssociationClass|QualifiedName])?
;
Now some words to the problem itself. While editing the xtext-file in the xtexteditor of the runtime eclipse, the build model is validated. The problem is here that the metamodel itself has several constraints for an AssociationClass (screenshot not possible yet ):
Multiple markers at this line
- The feature 'memberEnd' of 'org.eclipse.uml2.uml.internal.impl.AssociationClassImpl#142edebe{platform:/resource/aaa/test.mydsl#//Has}'
with 0 values must have at least 2 values
- The feature 'relatedElement' of 'org.eclipse.uml2.uml.internal.impl.AssociationClassImpl#142edebe{platform:/resource/aaa/test.mydsl#//Has}'
with 0 values must have at least 1 values
- The feature 'endType' of 'org.eclipse.uml2.uml.internal.impl.AssociationClassImpl#142edebe{platform:/resource/aaa/test.mydsl#//Has}'
with 0 values must have at least 1 values
- An association has to have min. two ownedends.
And now I wanted to know if it is possible to disable the validation for exactly this modelelement. So I can hide the errorinformation from the user. Because I want to serialize the created xtextmodel in the next step and will do some modeltransformations.
Seems like UML registers this validator in the global singleton registry. So you basically need to avoid using the registry. You can do that by binding a different element in your runtime modul:
public EValidator.Registry bindEValidatorRegistry() {
// return an empty one as opposed to EValidator.Registry.INSTANCE
return new org.eclipse.emf.ecore.impl.ValidationDelegateRegistryImpl();
}
How might it be possible to get Commerce-Product-Display information in a Commerce-Order object?
The issue is I need to publish a Commerce-Product-Display node when a user has made a payment to publish the node. I am using Rules to detect the payment and attempt to publish the node.
My problem is, because the Completing the checkout process Rules event only has data for a Commerce-Order, and the Commerce-Order does not have information for the Product nor the Product display, I am unable to publish the node.
OK, so here's my new answer based on the new info you provided in your question
=================================
So this is probably a little more complicated than you expected, but not impossible! Two things are important:
the line-items that are attached to your order will contain your products and
you will need to use a rule component, in order to be able to have an additional 'condition-action' combo inside your rule action
Here is how to do it:
In your rule that is triggered upon 'Completing the checkout process', add a loop in your 'Actions' section. You should see 'Add loop' right next to 'Add action'. We'll use this loop to iterate through all the commerce-line-items in your order: that's where the products are hiding
When configuring the loop, tell it to iterate through 'commerce-order:commerce-line-items' and either rename, or remember what it's going to call each line item as it goes through it.
Now - as it's going through each of your order's line items, we'll want to call an entire new rule with its own set of 'condition' and 'action'. The condition we need is to check that the line item contains the product you expect, and the action can be whatever you want - publish a node based on a certain field or whatever. In my case, the action will just be sending an email to prove I found a product. When we need condition-action sets within a rule, we need to create a rule component!!
Go to /admin/config/workflow/rules/components to create a new rule component to run for each of the above items. Click the 'Add new component' link at the top of the page
Select 'Rule' from the drop-down options, since this will be a component that contains both a condition and an action
Name the rule, and in the 'Variables' section, we have to let it know we're going to pass it a parameter to work with. In our case, it will be the commerce line item that is currently being iterated through.
Add two conditions to your component (or whatever checks you think are necessary). I added 'Entity is of type' => Commerce Line item and 'Entity has field' => commerce_product. So this runs for all my products at the moment.
The condition I set on my component is to send an email, and I filled in the following for the body of the email: [line-item:commerce_product], and it prints out the product's name beautifully in the email each time I've tested checking out!
But first - how do I call this component for each of my line item types after I save it?? Read on:
After the component is saved, Add an action to your loop:
From now on, at the very bottom of your actions, you'll see a brand new 'Components' section, and in your case, you should only have one now. Select it to call it for each item:
Last step will be to fill in the parameter to pass to this component, which is obviously the list_item you're currently on, or whatever the computer name of the current item was if you changed it.
Save and test!
Whew! It's a little complicated, but I hope it puts you in the right direction!
The way rules work in Drupal is that not all fields are shown for your entity by default in the actions. What you need to do is prompt Rules to recognize your object as a certain type of node in order for the Rule to add all of its appropriate fields.
You can do this either by
using the 'Content is of type' under the Node section check (and select your Commerce Display node type or
directly using the 'Entity has field' check under the Entities section to check for a specific field you want to use.
Either of those should prompt Rules to recognize the type of entity you're working with and populate the Actions with the necessary fields.
Let us know if this works!