Position-less GATHER? - uima

I have a situation where I would like to combine a set of annotations into one new annotation - using the found annotations as features of the new one. One of the annotations would serve as the boundary for the new annotation. All of the other associated annotations would be within a set number of tokens of the main one. The linked article here is similar to my problem, but I can't rely on positions of annotations; they could be before or after the main annotation AND in any order. This article eludes to a way to handle this scenario: "You can also specify rules that do not care [about position], but they will probably return too many matches." Could someone explain how this would work?
UIMA Ruta Creating annotation with features separated by some text

So you have defined your boundaries (as annotations) and want to annotate what lies in between, as features for the new annotation (irrespective of the order). Correct me if I got this wrong.
If that's the case, an illustration/solution example would look like:
(StartBoundary # EndBoundary){-> CREATE(NewAnnotation, "featureA"=A, "featureB"=B};
assuming the annotations A and B already exist in the isolated span.
The problem occurs when you have more than one annotation of type A or/and B. In this case, featureA or/and featureB will be set to the first occurence of A or/and B.

Related

How to get an OrderedSet of OccurrenceSpecifications from a Lifeline in QVTo?

From the diagram on page 570 of the UML spec I concluded that a Lifeline should have the events property, holding an OrderedSet(OcurrenceSpecification). Unfortunately it is not there, at least in the QVTo implementation that I use.
All I have is the coveredBy property, serving me with an (unordered) Set(InteractionFragment). Since my transformation relies on the correct order of MessageOcurrenceSpecification I somehow need to implement myself what I expected to be implemented by the missing events property.
This is what I have so far:
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.coveredBy->selectByKind(OccurrenceSpecification)->sortedBy(true);
}
Obviously sortedBy(true) does not get me far, but I don't know any further. Who can help?
All I could find so far were other people struggling with the same issue years ago, but no solution:
https://www.eclipse.org/forums/index.php/m/1049555/
https://www.eclipse.org/forums/index.php/m/1050025/
https://www.eclipse.org/forums/index.php/m/1095764/
Based on the answer by Vincent combined with input from a colleague of mine I came up with the following solution for QVTo:
-- -----------------------------------------------------------------------------
-- Polyfill for the missing Lifeline::events property
query Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.fragment
->selectByKind(OccurrenceSpecification)
->select(os: OccurrenceSpecification | os.covered->includes(self))
->asOrderedSet();
}
I don't know if it is possible, using directly coveredBy to get an ordered collection. As coveredBy is unordered, if you access it directly by the feature, you will have an unpredictible order and if you try to access it using the eGet(...) stuff, the same result will occur.
However, if I understood correctly, there is a "trick" that could work.
It relies on the assumption that each OccurrenceSpecification instance you need is held by the same Interaction that contains the Lifeline and uses the way EMF stores contained elements. Actually, each contained element is always kind of 'ordered' relatively to its parent (and for each collection so EMF can find elements back when XMI references are expressed using the element position in collections). So, the idea would be to access all the elements contained by the Interaction that owns the lifeline and filter the ones that are contained in coveredBy.
Expression with Acceleo
This is easy to write in MTL/Acceleo. In know you don't use it, but it illustrates what the expression does:
# In Acceleo:
# 'self' is the lifeline instance
self.interaction.eAllContents(OccurrenceSpecification)->select(e | self.coveredBy->includes(e))->asOrderedSet()
with self.interaction we retrieve the Interaction, then we get all the contained elements with eAllContents(...) and we filter the ones that are in the self.coveredBy collection.
But it is way less intuitive in QVT as eAllContents(...) does not exist. Instead you have to gain access to eContents() which is defined on EObject and returns an EList which is transtyped to a Sequence (in QVT,eAllContents() returns a ETreeIterator which is not transtyped by the QVT engine).
So, how to gain access to eContents() in the helper? There is two solutions:
Solution 1: Using the emf.tools library
The emf.tools library give you the ability to use asEObject() which casts your object in a pure EObject and give you more methods to access to (as eClass() for example...etc).
import emf.tools; -- we import the EMF tools library
modeltype UML ...; -- all your metamodel imports and stuffs
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.asEObject().eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Solution 2: Using oclAstype(...)
If for some reason emf.tools cannot be accessed, you can still cast to an EObject using oclAsType(...).
modeltype UML ...; -- all your metamodel imports and stuffs
modeltype ECORE "strict" uses ecore('http://www.eclipse.org/emf/2002/Ecore'); -- you also register the Ecore metamodel
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.oclAsType(EObject).eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Limitation
Ok, let's be honest here, this solution seems to work on the quick tests I performed, but I'm not a 100% sure that you will have all the elements you want as this code relies on the strong assumption that every OccurrenceSpecification you need are in the same Interaction as the Liteline instance. If you are sure that all the coveredBy elements you need are in the Interaction (I think they should be), then, that's not the sexiest solution, but it should do the work.
EDIT>
The solution proposed by hielsnoppe is more eleguant than the one I presented here and should be prefered.
You are correct. The Lifeline::events property is clearly shown on the diagram and appears in derived models such as UML.merged.uml.
Unfortunately Eclipse QVTo uses the Ecore projection of the UML metamodel to UML.ecore where unnavigable opposites are pruned. (A recent UML2Ecore enhancement allows the name to be persisted as an EAnnotation.) However once the true property name "events" has been pruned the implicit property name "OccurrenceSpecification" should work.
All associations are navigable in both directions in OCL, so this loss is a bug. (The new Pivot-based Eclipse OCL goes back to the primary UML model in order to avoid UML2Ecore losses. Once Eclipse QVTo migrates to the Pivot OCL you should see the behavior you expected.)

UIMA Ruta negating conditions

This might be a trivial question, but I'm new to Ruta so bear with me please.
My testdata consists of numbers in the following format:
0.1mm 0,11mm 1.1mm 1,1mm 1mm
I use the following rule to annotate the first four examples:
((NUM(COMMA|PERIOD)NUM) W{REGEXP("mm")}) {-> nummm};
Document{->MARK(nummm)};
Now I want to annotate "1mm", for example, too, but I'm kind of stuck right now, because I have no idea how to do this. I tried negating Conditions, like AFTER (as in "if NUM mm not after comma or period"), but it either didn't work or the syntax was wrong. Any help would be appreciated!
EDIT: I should add that I want to annotate "1mm", but not the 1mm part after a comma or period, as of right now i basically annotate everything twice.
There are really a lot of ways to specify this in UIMA Ruta.
Here's the first thing that came to my mind:
(NUM{-PARTOF(nummm)} (PM{PARTOF({COMMA,PERIOD})} NUM)? W{REGEXP("mm")}){-> nummm};
This is probably not the "best" rule but should do what you want. There are three main changes:
I made the middle part of the rule optional so that it also matches on a single NUM.
I added the negated PARTOF of at the first rule element thus the matching will fail if the starting point is already covered by a nummm annotation. The - is a shortcut for the NOT condition.
I replaced the expensive disjunctive composed rule element with a simple one just because it is not really necessary here.
This rule works because the actions of a rule match are already executed before the next rule match is considered.
DISCLAIMER: I am a developer of UIMA Ruta.

Mirror formatting spring-data-rest/spring-hateoas in custom controllers

I used the suggested approach in this question to return HATEOAS formatted outputs that match those returned by spring-data-rest. It works good, but is there a way to avoid boiler plate code to create entity resource assemblers like the QuestionResourceAssembler in the referenced question, if I only want to add 'self' links using the id to all entities? Perhaps using ResourceAssemblerSupport?
The easiest way is to simply use the Resource wrapper type:
Resource<Person> personResource = new Resource<>(person);
personResource.addLink(…);
personResource.addLink(…);
Links can be created either by simply instantiating them (i.e. new Link("http://localhost/foo", "relation") or by using the ControllerLinkBuilder which allows you to point to Controller methods for obtain a reverse mapping. See this section of the Readme for details.

How can I have two editors for the same property on a switch?

I am trying to create an editor where the user can either select an existing item or create a new one inline. For example, imagine the typical person-address relationship. I want a form where the user, when editing a person, can either select an address from a set of existing addresses or create a new address without moving to a separate form.
Naively, this seems to require two different editors for the same property. Say I have a Person which has Address getAddress() and setAddress(Address). My PersonEditor class would need to have two sub-editors named address of differing types; one to select an existing person and the another a composite of editors to descend into the Address type and allow editing of its properties.
From reading the documentation on CompositeEditor, it seems like I have to make use of it to dynamically select the sub-editor. However, the documentation isn't detailed enough for me to really understand how I should implement the interface. I've tried looking at how ListEditor and OptionalFieldEditor are implemented for clues, but to avail. ListEditor doesn't seem like a straight fit as my sub-editors edit different paths.
For instance, trying to use CompositeEditor, I'm unclear on what createEditorForTraversal and getPathElement should return in my case.
How do I dynamically attach one of two different types of editors to one property?
I managed to do this in the end. I simply added two editors with the same #Path annotation. I was not expecting the editor framework to allow this, but it seems to work!

xtext check annotation issue

I'm using the #Check annotation in order to validate my dsl. my dsl is for json.
at first the method was invoked for a specific object and once per change
but it suddenly doesn't work in the same way anymore (and i'm not sure what i've done that effected it)
the method signature is:
#Check
public void validateJson(ObjectValue object) {...}
now its entering this method for each node in the gui although i'm editing only one node
The validator works normally in this case. When Xtext re-parses your model, it cannot always avoid re-creating the EMF model that is validated in the Check expression - in other words, the model is practically re-created every time, thus warranting a full validation.
However, in some cases, it is possible that only a partial re-creation of the model is necessary - in these cases it is possible that not all elements are re-validated (however, I am not sure whether this optimization was included).