You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by pk...@apache.org on 2014/07/28 12:48:23 UTC
svn commit: r1613955 - in /uima/ruta/trunk:
ruta-core/src/main/java/org/apache/uima/ruta/
ruta-core/src/main/java/org/apache/uima/ruta/action/
ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/
ruta-core/src/main/java/org/apache/uima/ruta...
Author: pkluegl
Date: Mon Jul 28 10:48:22 2014
New Revision: 1613955
URL: http://svn.apache.org/r1613955
Log:
UIMA-3931
- added functionality
- added test
- extended documentation
Added:
uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/CoveredTextTest.java (with props)
Modified:
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/UIMAConstants.java
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/ImplicitFeatureAction.java
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/SetFeatureAction.java
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/SimpleFeatureExpression.java
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java
uima/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml
Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/UIMAConstants.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/UIMAConstants.java?rev=1613955&r1=1613954&r2=1613955&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/UIMAConstants.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/UIMAConstants.java Mon Jul 28 10:48:22 2014
@@ -39,4 +39,8 @@ public class UIMAConstants {
public static final String TYPE_DOCUMENT = "uima.tcas.DocumentAnnotation";
+ public static final String FEATURE_COVERED_TEXT = "coveredText";
+
+ public static final String FEATURE_COVERED_TEXT_SHORT = "ct";
+
}
Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/ImplicitFeatureAction.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/ImplicitFeatureAction.java?rev=1613955&r1=1613954&r2=1613955&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/ImplicitFeatureAction.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/ImplicitFeatureAction.java Mon Jul 28 10:48:22 2014
@@ -81,6 +81,9 @@ public class ImplicitFeatureAction exten
private void setFeatureValue(AnnotationFS a, Feature feature, IRutaExpression argExpr,
RuleElement element, RutaStream stream) {
+ if(feature == null) {
+ throw new IllegalArgumentException("Not able to assign feature value (e.g., coveredText).");
+ }
String range = feature.getRange().getName();
if (range.equals(UIMAConstants.TYPE_STRING)) {
if (argExpr instanceof IStringExpression) {
Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/SetFeatureAction.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/SetFeatureAction.java?rev=1613955&r1=1613954&r2=1613955&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/SetFeatureAction.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/SetFeatureAction.java Mon Jul 28 10:48:22 2014
@@ -60,6 +60,7 @@ public class SetFeatureAction extends Ab
List<AnnotationFS> matchedAnnotations = match.getMatchedAnnotationsOf(element);
for (AnnotationFS annotationFS : matchedAnnotations) {
Feature feature = annotationFS.getType().getFeatureByBaseName(featureString);
+
if (feature != null) {
Type range = feature.getRange();
String rangeName = range.getName();
@@ -110,6 +111,8 @@ public class SetFeatureAction extends Ab
}
}
stream.getCas().addFsToIndexes(annotationFS);
+ } else {
+ throw new IllegalArgumentException("Not able to assign feature value (e.g., coveredText).");
}
}
}
Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java?rev=1613955&r1=1613954&r2=1613955&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java Mon Jul 28 10:48:22 2014
@@ -31,6 +31,7 @@ import org.apache.uima.ruta.expression.R
import org.apache.uima.ruta.expression.bool.IBooleanExpression;
import org.apache.uima.ruta.expression.number.INumberExpression;
import org.apache.uima.ruta.expression.string.AbstractStringExpression;
+import org.apache.uima.ruta.expression.string.IStringExpression;
public class FeatureMatchExpression extends SimpleFeatureExpression {
@@ -71,7 +72,8 @@ public class FeatureMatchExpression exte
public boolean checkFeatureValue(AnnotationFS afs, Feature feature, RutaStream stream,
RutaBlock parent) {
- String rn = feature.getRange().getName();
+ // null is possibly coveredText
+ String rn = feature == null ? UIMAConstants.TYPE_STRING : feature.getRange().getName();
if (rn.equals(UIMAConstants.TYPE_BOOLEAN)) {
Boolean v1 = afs.getBooleanValue(feature);
if (arg instanceof IBooleanExpression) {
@@ -102,9 +104,13 @@ public class FeatureMatchExpression exte
return compare(v1, v2);
}
} else if (rn.equals(UIMAConstants.TYPE_STRING)) {
- String v1 = afs.getStringValue(feature);
- if (arg instanceof AbstractStringExpression) {
- AbstractStringExpression expr = (AbstractStringExpression) arg;
+ String v1 = afs.getCoveredText();
+ // null is possibly coveredText
+ if (feature != null) {
+ v1 = afs.getStringValue(feature);
+ }
+ if (arg instanceof IStringExpression) {
+ IStringExpression expr = (IStringExpression) arg;
String v2 = expr.getStringValue(parent, afs, stream);
return compare(v1, v2);
}
@@ -113,27 +119,27 @@ public class FeatureMatchExpression exte
}
private boolean compare(Object v1, Object v2) {
- if(v1 instanceof Number && v2 instanceof Number) {
+ if (v1 instanceof Number && v2 instanceof Number) {
Number n1 = (Number) v1;
Number n2 = (Number) v2;
int compareTo = new BigDecimal(n1.toString()).compareTo(new BigDecimal(n2.toString()));
- if(op.equals("==")) {
+ if (op.equals("==")) {
return compareTo == 0;
- } else if(op.equals("!=")) {
+ } else if (op.equals("!=")) {
return compareTo != 0;
- } else if(op.equals(">=")) {
+ } else if (op.equals(">=")) {
return compareTo >= 0;
- } else if(op.equals(">")) {
+ } else if (op.equals(">")) {
return compareTo > 0;
- } else if(op.equals("<=")) {
+ } else if (op.equals("<=")) {
return compareTo <= 0;
- } else if(op.equals("<")) {
+ } else if (op.equals("<")) {
return compareTo < 0;
}
- } else if(v1 != null && v2 != null) {
- if(op.equals("==")) {
+ } else if (v1 != null && v2 != null) {
+ if (op.equals("==")) {
return v1.equals(v2);
- } else if(op.equals("!=")) {
+ } else if (op.equals("!=")) {
return !v1.equals(v2);
}
}
Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/SimpleFeatureExpression.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/SimpleFeatureExpression.java?rev=1613955&r1=1613954&r2=1613955&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/SimpleFeatureExpression.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/SimpleFeatureExpression.java Mon Jul 28 10:48:22 2014
@@ -25,13 +25,16 @@ import java.util.Collection;
import java.util.List;
import java.util.TreeSet;
+import org.apache.commons.lang3.StringUtils;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.ruta.RutaBlock;
import org.apache.uima.ruta.RutaStream;
+import org.apache.uima.ruta.UIMAConstants;
import org.apache.uima.ruta.expression.type.TypeExpression;
+import org.apache.uima.ruta.extensions.RutaParseException;
import org.apache.uima.ruta.rule.AnnotationComparator;
public class SimpleFeatureExpression extends FeatureExpression {
@@ -69,9 +72,21 @@ public class SimpleFeatureExpression ext
Type type = typeExpr.getType(parent);
Feature feature = null;
for (String each : features) {
- feature = type.getFeatureByBaseName(each);
+ if (StringUtils.equals(each, UIMAConstants.FEATURE_COVERED_TEXT)) {
+ // there is no explicit feature for coveredText
+ feature = null;
+ } else {
+ feature = type.getFeatureByBaseName(each);
+ if (feature == null) {
+ if(!StringUtils.equals(each, UIMAConstants.FEATURE_COVERED_TEXT_SHORT))
+ throw new IllegalArgumentException("Not able to access feature " + each + " of type "
+ + type.getName());
+ }
+ }
result.add(feature);
- type = feature.getRange();
+ if(feature != null) {
+ type = feature.getRange();
+ }
}
return result;
}
@@ -99,7 +114,8 @@ public class SimpleFeatureExpression ext
for (AnnotationFS eachBase : annotations) {
AnnotationFS afs = eachBase;
for (Feature feature : features) {
- if (feature.getRange().isPrimitive()) {
+ if(feature == null || feature.getRange().isPrimitive()) {
+ // feature == null -> this is the coveredText "feature"
if (this instanceof FeatureMatchExpression) {
FeatureMatchExpression fme = (FeatureMatchExpression) this;
if (checkOnFeatureValue) {
@@ -119,7 +135,7 @@ public class SimpleFeatureExpression ext
}
}
if (!(this instanceof FeatureMatchExpression)) {
- if(stream.isVisible(afs)) {
+ if (stream.isVisible(afs)) {
result.add(afs);
}
}
Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java?rev=1613955&r1=1613954&r2=1613955&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java Mon Jul 28 10:48:22 2014
@@ -47,7 +47,12 @@ public class StringFeatureExpression ext
false);
if (!featureAnnotations.isEmpty()) {
AnnotationFS next = featureAnnotations.iterator().next();
- return next.getStringValue(feature);
+ if(feature == null) {
+ // feature == coveredText
+ return next.getCoveredText();
+ } else {
+ return next.getStringValue(feature);
+ }
}
return null;
}
Added: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/CoveredTextTest.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/CoveredTextTest.java?rev=1613955&view=auto
==============================================================================
--- uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/CoveredTextTest.java (added)
+++ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/CoveredTextTest.java Mon Jul 28 10:48:22 2014
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.ruta;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.cas.text.AnnotationIndex;
+import org.apache.uima.ruta.engine.Ruta;
+import org.apache.uima.ruta.engine.RutaTestUtils;
+import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature;
+import org.junit.Test;
+
+public class CoveredTextTest {
+
+ @Test
+ public void testWithCTFeature() {
+ String document = "This is the document.";
+ String script = "";
+ script += "DECLARE Annotation Type(STRING ct);\n";
+ script += "CW{-> CREATE(Type, \"ct\" = \"cw\")};";
+ script += "SW{-> CREATE(Type, \"ct\" = \"sw\")};";
+ script += "Type.ct == \"cw\" {-> T1};";
+ script += "Type.ct == \"sw\" {-> T2};";
+ script += "Type.ct == \"This\" {-> T3};";
+ script += "Type.ct == \"is\" {-> T4};";
+ script += "Type.ct == Type.coveredText {-> T5};";
+
+ Map<String, String> typeMap = new TreeMap<String, String>();
+ String typeName1 = "Type";
+ typeMap.put(typeName1, "uima.tcas.Annotation");
+
+ Map<String, List<TestFeature>> featureMap = new TreeMap<String, List<TestFeature>>();
+ List<TestFeature> list = new ArrayList<RutaTestUtils.TestFeature>();
+ featureMap.put(typeName1, list);
+ String fn1 = "ct";
+ list.add(new TestFeature(fn1, "", "uima.cas.String"));
+
+ CAS cas = null;
+ try {
+ cas = RutaTestUtils.getCAS(document, typeMap, featureMap);
+ Ruta.apply(cas, script);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Type t = null;
+ AnnotationIndex<AnnotationFS> ai = null;
+ FSIterator<AnnotationFS> iterator = null;
+
+ t = RutaTestUtils.getTestType(cas, 1);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(1, ai.size());
+ iterator = ai.iterator();
+ assertEquals("This", iterator.next().getCoveredText());
+
+ t = RutaTestUtils.getTestType(cas, 2);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(3, ai.size());
+ iterator = ai.iterator();
+ assertEquals("is", iterator.next().getCoveredText());
+ assertEquals("the", iterator.next().getCoveredText());
+ assertEquals("document", iterator.next().getCoveredText());
+
+ t = RutaTestUtils.getTestType(cas, 3);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(0, ai.size());
+
+ t = RutaTestUtils.getTestType(cas, 4);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(0, ai.size());
+
+ t = RutaTestUtils.getTestType(cas, 5);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(0, ai.size());
+
+ if (cas != null) {
+ cas.release();
+ }
+
+ }
+
+ @Test
+ public void testCoveredText() {
+ String document = "This is the document.";
+ String script = "STRING var = \"This\";";
+ script += "W.ct == \"This\"{-> T1};";
+ script += "W.ct == \"is\"{-> T2};";
+ script += "W.coveredText == \"This\"{-> T3};";
+ script += "W.coveredText == \"is\"{-> T4};";
+ script += "W{W.ct == var -> T5};";
+ script += "W{W.coveredText == var -> T6};";
+ // script += "W{-> W.coveredText = \"NEW\"};";
+ // script += "W{-> SETFEATURE(\"coveredText\", \"NEW\")};";
+
+ CAS cas = null;
+ try {
+ cas = RutaTestUtils.getCAS(document);
+ Ruta.apply(cas, script);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Type t = null;
+ AnnotationIndex<AnnotationFS> ai = null;
+ FSIterator<AnnotationFS> iterator = null;
+
+ t = RutaTestUtils.getTestType(cas, 1);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(1, ai.size());
+ iterator = ai.iterator();
+ assertEquals("This", iterator.next().getCoveredText());
+
+ t = RutaTestUtils.getTestType(cas, 2);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(1, ai.size());
+ iterator = ai.iterator();
+ assertEquals("is", iterator.next().getCoveredText());
+
+ t = RutaTestUtils.getTestType(cas, 3);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(1, ai.size());
+ iterator = ai.iterator();
+ assertEquals("This", iterator.next().getCoveredText());
+
+ t = RutaTestUtils.getTestType(cas, 4);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(1, ai.size());
+ iterator = ai.iterator();
+ assertEquals("is", iterator.next().getCoveredText());
+
+ t = RutaTestUtils.getTestType(cas, 5);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(1, ai.size());
+ iterator = ai.iterator();
+ assertEquals("This", iterator.next().getCoveredText());
+
+ t = RutaTestUtils.getTestType(cas, 6);
+ ai = cas.getAnnotationIndex(t);
+ assertEquals(1, ai.size());
+ iterator = ai.iterator();
+ assertEquals("This", iterator.next().getCoveredText());
+
+ if (cas != null) {
+ cas.release();
+ }
+
+ }
+
+}
Propchange: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/CoveredTextTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: uima/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml?rev=1613955&r1=1613954&r2=1613955&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml (original)
+++ uima/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml Mon Jul 28 10:48:22 2014
@@ -313,6 +313,13 @@ FeatureMatchExpression -> FeatureEx
FeatureAssignmentExpression -> FeatureExpression "=" Expression
]]></programlisting>
</para>
-
+ <para>
+ The covered text of an annoation can be referred to with "coveredText" or "ct".
+ The latter one is an abbreviation and returns the covered text of an annotation
+ only if the type of the annotation does not define a feature with the name "ct".
+ The following example creates an annotation of the type TypeA for each word with the
+ covered text "A".
+ <programlisting><![CDATA[W.ct == "A" {-> TypeA};]]></programlisting>
+ </para>
</section>
</section>
\ No newline at end of file