How can I add a custom condition to an existing RUTA project? Started, but am stuck - uima

I want to add a custom UIMA RUTA rule condition. I have an existing UIMA Ruta project in Eclipse. So far I created a source file in the same project with a basic annotator stub:
package mynamespace.extensions;
[imports]
public class MyNewCondition extends AbstractRutaCondition {
private final String para1;
public MyNewCondition(String para1) {
super();
this.para1 = para1;
}
#Override
public EvaluatedCondition eval(AnnotationFS annotation,
RuleElement element, RutaStream stream, InferenceCrowd crowd) {
// TODO Auto-generated method stub
if (para1 == "hfoo")
return new EvaluatedCondition(this, true);
else
return new EvaluatedCondition(this, false);
}
public String getPara() {
return para1;
}
}
The file compiles to the target/classes/... folder, but when I create a RUTA script:
DECLARE Test;
SW{MyNewCondition("foo") -> MARK(Test)};
... Eclipse tells me that "MyNewCondition" is not defined and when I run it I get: "Error in line 40, "(": found no viable alternative" on the console. I presume I need to do some further import, but do not know how. I tried to work from the Extension example project in the Github repository, but I do not know where to start there as the script file does not contain any further imports, but the associated xml descriptor files do. But as these get automatically generated I do not know whether this is what I should change or it is something else.
I also tried importing the same new condition type from a second project via Eclipse's build path options, but no luck there either.
Can someone help? Thanks.

You need at least three classes for adding a new condition that also is resolved in the UIMA Ruta Workbench:
An implementation of the condition as you did in your question
An implementation of IRutaConditionExtension, which provides the condition implementation to the engine
An implementation of IIDEConditionExtension, which provides the condition for the UIMA Ruta Workench
The condition itself contains only the functionality that should be added to the language. The analysis engine knows of course nothing about any external implementations resulting in a strange parse exception like "(" not found. That should be improved sometimes. The analysis engine provides a configuration parameter additionalExtensions that lists all known extensions to the language. If you are not using the UIMA Ruta Workbench, you need to add your implementation of IRutaConditionExtension to this parameter. The implemenation of IIDEConditionExtension provides the necessary functionality for the UIMA Ruta Workbench that is the syntax check, syntax highlighting and so on. Additionally, it enables the Workbench to generate correct descriptors. It adds your implementation of IRutaConditionExtension to the respective parameter. This extension of the Workbench needs of course to be implemented in an Eclipse plugin that is installed in your UIMA Ruta Workbench Eclipse instance, in order to be available in the Workbench. There is an extension point, which you need to extend that knows both your implementation of IRutaConditionExtension and IIDEConditionExtension.
There is an exemplary project that provides implementation of all possible language elements. This project contains the implementations for the analysis engine and also the implementation for the UIMA Ruta Workbench, and is therefore an Eclipse plugin (mind the pom file).
Concerning the ExampleCondition condition extension, there are three important spots/classes:
ExampleCondition.java provides the implementation of the new condition, which evaluates dates
ExampleConditionExtension.java provides the extension for the analysis engine. It knows the name of the condition, its implementation, can create new instances of that condition, and is able to verbalize the condition for the explanation components.
ExampleConditionIDEExtension provides the syntax check for the editor and the keyword for syntax coloring.
plugin.xml defines the extension for the Workbench:
<extension point="org.apache.uima.ruta.ide.conditionExtension">
<condition
class="org.apache.uima.ruta.example.extensions.ExampleConditionIDEExtension"
engine="org.apache.uima.ruta.example.extensions.ExampleConditionExtension">
</condition>
</extension>
If you do not use the UIMA Ruta Workbench or only want to apply the rules in UIMA pipelines, you only need ExampleCondition and ExampleConditionExtension, and you need to add org.apache.uima.ruta.example.extensions.ExampleConditionExtension to the additionalExtensions parameter of your UIMA Ruta analysis engine (descriptor).
Adding new conditions using Java projects in the same workspace has not been tested yet, but at least the Workbench support will be missing due to the inclusion of extensions using the extension point mechanism of Eclipse.

Related

XText - Multiple grammars and example web editor

I have an XText project setup with multiple grammars and am able to edit each grammar with cross-linking within the IDE generated by the mwe2 workflow. When I run the example web editor, the first grammar defined in the mwe2 workflow functions correctly.
If I change the the generated index.html to use one of the alternate grammar extensions the editor no longer functions, and I get an error message that looks like:
Xtext service 'occurrences' failed: Unable to identify the Xtext
language for resource 3c05cdd1.ed
I'd like to understand what is wrong in order to better understand how I can begin minimal integration of editors for the grammars into our existing console.
Thanks!
Pierre Padovani
P.S. I've posted this same question on the Eclipse Community Forums, but my post seems to be stuck in a moderator queue.
Having found the thread which #ppadovani mentions, it seems that the only necessary change is to ignore all the generated Servlet.xtend files except the one whose grammar is working.
In that one which works, it is necessary to initialise run the WebSetup for the other languages.
override init() {
super.init()
// call createInjectorAndDoEMFRegistration for each WebSetup
new DerivedDslWebSetup().createInjectorAndDoEMFRegistration
// keep the rest as-is
val injector = new CoreDslWebSetup().createInjectorAndDoEMFRegistration()
disposableRegistry = injector.getInstance(DisposableRegistry)
}
Reference: https://www.eclipse.org/forums/index.php?t=msg&th=1096166&goto=1798287&#msg_1798287

How to access Array in UIMA-RUTA

I have an Annotation class with String Array as one of the field.
I want to add and remove string elements to that String Array from ruta script.
I searched for FSArray but didn't got anything.
Please help me with solving above problem.
As of UIMA Ruta 2.5.0, operations on FSArrays and StringArrays are not yet supported and still an open issue: UIMA-4399
You either need to wrap the logic in an additional analysis engine or you need to write an language extension for ruta.
DISCLAIMER: I am a developer of UIMA Ruta

Using Apache UIMA Ruta from my own annotator

I have a series of UIMA Ruta rules that I wish to run from within my own UIMA annotator. This is described here, but I can't get it to work: http://uima.apache.org/d/ruta-current/tools.ruta.book.html#ugr.tools.ruta.integration
When I try to run the annotator (from within a JUnit test, which I have used with other UIMA annotators successfully in the past), I get an error telling me that one of the Ruta basic annotation types (org.apache.uima.ruta.type.TokenSeed) is used in the Java code but isn't defined in the XML.
I've added the absolute path to the Ruta type system (BasicTypeSystem.xml and InternalTypeSystem.xml) to the descriptorPaths parameter (as detailed here: http://uima.apache.org/d/ruta-current/tools.ruta.book.html#ugr.tools.ruta.ae.basic.parameter.descriptorPaths), but that doesn't seem to make a difference.
I've had a look through the Ruta source code and couldn't figure out where I was going wrong.
Has anyone successfully got a Ruta script to run from within a UIMA annotator? How did you manage to get it working?
The problem is caused by the fact that the type system used by your analysis engine does not contain the types UIMA Ruta needs. The error mentions the seeding types because the initial annotations are added at the beginning. Even without seeding, more errors will occur because of the missing types like RutaBasic.
Adding the BasicTypeSystem to the type system used in your analysis engine should solve the problem.

How to compare files programmatically in eclipse?

I am developing an eclipse plugin that runs code violation checker on the difference of two versions of a file. Right now I am using diff.exe to get the difference between the two files. But as diff.exe is an extrenal app, I realized that its better to use eclipse built-in compare tool to get the file difference.
So I used org.eclipse.compare and reached up to this point:
public static List<Patch> compare(String old, String recent) {
try{
IRangeComparator left = new TokenComparator(old); //what exactly to be passed in this constructor, a file path, a literal value or something else?
IRangeComparator right = new TokenComparator(recent);
RangeDifference[] diffs = RangeDifferencer.findDifferences(left, right); // This line is throwing NPE
//..
// Process RangeDifferences into Collection of Patch collection
//..
}catch(Exception e){}
//Returns a collection of file differences.
return null;
}
Now the problem is I am not sure what exactly to be passed in the constructor TokenComparator(String). The document says this constructor Creates a TokenComparator for the given string. But it is not written what exactly to be passed in this constructor, a file path, a literal value or something else? When I'm passing a file path or a string literal I am getting NullPointerException on the next line of finding differences.
java.lang.NullPointerException
at org.eclipse.compare.internal.core.LCS.isCappingDisabled(LCS.java:98)
at org.eclipse.compare.internal.core.LCS.longestCommonSubsequence(LCS.java:55)
at org.eclipse.compare.rangedifferencer.RangeComparatorLCS.longestCommonSubsequence(RangeComparatorLCS.java:186)
at org.eclipse.compare.rangedifferencer.RangeComparatorLCS.findDifferences(RangeComparatorLCS.java:31)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:98)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:82)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:67)
at com.dassault_systemes.eclipseplugin.codemonview.util.CodeMonDiff.compare(CodeMonDiff.java:48)
at com.dassault_systemes.eclipseplugin.codemonview.util.CodeMonDiff.main(CodeMonDiff.java:56)
Someone please tell what is right way to proceed.
If the question is What value the token comparators constructor takes then the answer is it takes the input string to compare. Specified in javadoc here http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcompare%2Fcontentmergeviewer%2FTokenComparator.html
TokenComparator(String text)
Creates a TokenComparator for the given string.
And the null pointer yo are getting is because in function isCappingDisabled it tries to open the compare plugin which seems to be null. You seem to be missing a direct dependency to the plugin "org.eclipse.compare.core"
The org.eclipse.compare plugin was never meant to be used in standalone : many of its functionalities require a running instance of Eclipse. Furthermore, it mixes core and UI code within the same plugin, which will lead to unexpected behavior if you are not very careful about what you use and what dependencies are actually available in your environment.
You mentionned that you were developping an Eclipse plugin. However, the NPE you get indicates that you are not running your code as an Eclipse plugin, but rather as a standard Java program. In an Eclipse environment, ComparePlugin.getDefault() cannot return null : the plugin needs to be started for that call to return anything but null.... and the mere loading of the ComparePlugin class within Eclipse is enough to start it.
The answer will be a choice :
You need your code to run as a standalone Java program out of Eclipse. In such an event, you cannot use org.eclipse.compare and diff.exe is probably your best choice (or you could switch to an implementation of diff that was implemented in Java in order to be independent of the platform).
You do not need your program to work in a standalone environment, only as an Eclipse plugin. In this case, you can keep the code you're using. However, when you run your code, you have to launch it as a new "Eclipse application" instead of "Java Application". You might want to look at a tutorial on how to develop Eclipse plugins for this, This simple tutorial from Lars Vogel shows how to run a new Eclipse Application to test an Hello World plugin. You will need a similar code, with a menu entry to launch your plugin somewhere (right-click on a file then select "check violations" in your case?).

Eclipse CDT: how to add support for new filetype

In Eclipse CDT, I would like to create syntax highlighting and a error parser for a custom filetype, lets say *.xy.
Those files do not contain C-Code, so i cannot use any existing parsers.
What kind of plugins would I have to create?
For the error parser, I think I have to use Codan? (have not tried it yet)
https://www.ibm.com/developerworks/java/library/j-codan/
The CDT is the wrong start for your journey, if your language is not related to the CDT supported languages and workflows. Implement an xtext based language editor instead.
Maybe this is a simple solution for you:
colorEditor plugin
You can simply add a new language by unpacking the jar archive, then adding a xyz.xml file for your .xyz files.
Pakc together again, and copy into your Eclipse "plugins" dir.
You need to introduce a new "language" - this is the extension point: http://help.eclipse.org/helios/topic/org.eclipse.cdt.doc.isv/reference/extension-points/org_eclipse_cdt_core_language.html
Codan is not an "error parser" it is a static analysis framework. Error parser processes output of the command-line tools you use to build the application (e.g. compiler, linker) to identify errors that happened during the build and filling their attributes, e.g. source file name and line number.
Codan analyzes the source code in the editor to identify errors. E.g. it checks if the variable used in the expression was declared beforehand. Note that same check can be performed by a compile at a build time and then captured by error parser and shown in the editor/problems view - the goal of Codan is to detect problems sooner, before the build is even ran. Codan can also perform some checks that compiler doesn't.