Author: pkluegl Date: Wed Aug 28 13:13:45 2013 New Revision: 1518196 URL: http://svn.apache.org/r1518196 Log: UIMA-3224 - extended match on feature values for numeric primitives - added tests for element match and conditions
Added: uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatchTest2.java uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitConditionTest2.java uima/sandbox/ruta/trunk/ruta-ep-ide/src/main/antlr3/org/apache/uima/ruta/ide/core/parser/output/ Modified: uima/sandbox/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g uima/sandbox/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java uima/sandbox/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml uima/sandbox/ruta/trunk/ruta-ep-ide/src/main/antlr3/org/apache/uima/ruta/ide/core/parser/RutaParser.g Modified: uima/sandbox/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g URL: http://svn.apache.org/viewvc/uima/sandbox/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g?rev=1518196&r1=1518195&r2=1518196&view=diff ============================================================================== --- uima/sandbox/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g (original) +++ uima/sandbox/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g Wed Aug 28 13:13:45 2013 @@ -913,8 +913,8 @@ options { matchReference returns [MatchReference mr = null] : - ref = dottedId (op = EQUAL arg = argument)? - {mr = ExpressionFactory.createMatchReference(ref, op, arg);} + ref = dottedId ((comp = LESS | comp = GREATER | comp = GREATEREQUAL | comp = LESSEQUAL |comp = EQUAL | comp = NOTEQUAL) arg = argument)? + {mr = ExpressionFactory.createMatchReference(ref, comp, arg);} ; typeExpression returns [TypeExpression type = null] @@ -966,14 +966,14 @@ TypeExpression te = null; featureMatchExpression returns [FeatureMatchExpression fme = null] : - f = featureExpression (op = EQUAL arg = argument)? - {fme = ExpressionFactory.createFeatureMatchExpression(f, op, arg, $blockDeclaration::env);} + f = featureExpression ((comp = LESS | comp = GREATER | comp = GREATEREQUAL | comp = LESSEQUAL |comp = EQUAL | comp = NOTEQUAL) arg = argument)? + {fme = ExpressionFactory.createFeatureMatchExpression(f, comp, arg, $blockDeclaration::env);} ; featureMatchExpression2 returns [FeatureMatchExpression fme = null] : - f = featureExpression op = EQUAL arg = argument - {fme = ExpressionFactory.createFeatureMatchExpression(f, op, arg, $blockDeclaration::env);} + f = featureExpression (comp = LESS | comp = GREATER | comp = GREATEREQUAL | comp = LESSEQUAL |comp = EQUAL | comp = NOTEQUAL) arg = argument + {fme = ExpressionFactory.createFeatureMatchExpression(f, comp, arg, $blockDeclaration::env);} ; Modified: uima/sandbox/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java URL: http://svn.apache.org/viewvc/uima/sandbox/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java?rev=1518196&r1=1518195&r2=1518196&view=diff ============================================================================== --- uima/sandbox/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java (original) +++ uima/sandbox/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/feature/FeatureMatchExpression.java Wed Aug 28 13:13:45 2013 @@ -19,6 +19,8 @@ package org.apache.uima.ruta.expression.feature; +import java.math.BigDecimal; + import org.apache.uima.cas.Feature; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.ruta.RutaBlock; @@ -70,11 +72,11 @@ public class FeatureMatchExpression exte RutaBlock parent) { String rn = feature.getRange().getName(); if (rn.equals(UIMAConstants.TYPE_BOOLEAN)) { - boolean v1 = afs.getBooleanValue(feature); + Boolean v1 = afs.getBooleanValue(feature); if (arg instanceof BooleanExpression) { BooleanExpression expr = (BooleanExpression) arg; - boolean v2 = expr.getBooleanValue(parent, afs, stream); - return v1 == v2; + Boolean v2 = expr.getBooleanValue(parent, afs, stream); + return compare(v1, v2); } } else if (rn.equals(UIMAConstants.TYPE_INTEGER) || rn.equals(UIMAConstants.TYPE_BYTE) || rn.equals(UIMAConstants.TYPE_SHORT) || rn.equals(UIMAConstants.TYPE_LONG)) { @@ -82,28 +84,56 @@ public class FeatureMatchExpression exte if (arg instanceof NumberExpression) { NumberExpression expr = (NumberExpression) arg; Integer v2 = expr.getIntegerValue(parent, afs, stream); - return v1.equals(v2); + return compare(v1, v2); } } else if (rn.equals(UIMAConstants.TYPE_DOUBLE)) { Double v1 = afs.getDoubleValue(feature); if (arg instanceof NumberExpression) { NumberExpression expr = (NumberExpression) arg; Double v2 = expr.getDoubleValue(parent, afs, stream); - return v1.equals(v2); + return compare(v1, v2); } } else if (rn.equals(UIMAConstants.TYPE_FLOAT)) { Float v1 = afs.getFloatValue(feature); if (arg instanceof NumberExpression) { NumberExpression expr = (NumberExpression) arg; Float v2 = expr.getFloatValue(parent, afs, stream); - return v1.equals(v2); + return compare(v1, v2); } } else if (rn.equals(UIMAConstants.TYPE_STRING)) { String v1 = afs.getStringValue(feature); if (arg instanceof StringExpression) { StringExpression expr = (StringExpression) arg; String v2 = expr.getStringValue(parent, afs, stream); - return v1 != null && v1.equals(v2); + return compare(v1, v2); + } + } + return false; + } + + private boolean compare(Object v1, Object v2) { + 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("==")) { + return compareTo == 0; + } else if(op.equals("!=")) { + return compareTo != 0; + } else if(op.equals(">=")) { + return compareTo >= 0; + } else if(op.equals(">")) { + return compareTo > 0; + } else if(op.equals("<=")) { + return compareTo <= 0; + } else if(op.equals("<")) { + return compareTo < 0; + } + } else if(v1 != null && v2 != null) { + if(op.equals("==")) { + return v1.equals(v2); + } else if(op.equals("!=")) { + return !v1.equals(v2); } } return false; Added: uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatchTest2.java URL: http://svn.apache.org/viewvc/uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatchTest2.java?rev=1518196&view=auto ============================================================================== --- uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatchTest2.java (added) +++ uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatchTest2.java Wed Aug 28 13:13:45 2013 @@ -0,0 +1,107 @@ +/* + * 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 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.junit.Test; + +public class FeatureMatchTest2 { + + @Test + public void test() { + String document = "Peter Kluegl, Joern Kottmann, Marshall Schor."; + String script = ""; + script += "CW.begin<=14{-> T1};\n"; + script += "CW.begin<14{-> T2};\n"; + script += "CW.begin==0{-> T3};\n"; + script += "CW.begin!=0{-> T4};\n"; + script += "CW.begin>=20{-> T5};\n"; + script += "CW.begin>20{-> T6};\n"; + 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(3, ai.size()); + iterator = ai.iterator(); + assertEquals("Peter", iterator.next().getCoveredText()); + assertEquals("Kluegl", iterator.next().getCoveredText()); + assertEquals("Joern", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 2); + ai = cas.getAnnotationIndex(t); + assertEquals(2, ai.size()); + iterator = ai.iterator(); + assertEquals("Peter", iterator.next().getCoveredText()); + assertEquals("Kluegl", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 3); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("Peter", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 4); + ai = cas.getAnnotationIndex(t); + assertEquals(5, ai.size()); + iterator = ai.iterator(); + assertEquals("Kluegl", iterator.next().getCoveredText()); + assertEquals("Joern", iterator.next().getCoveredText()); + assertEquals("Kottmann", iterator.next().getCoveredText()); + assertEquals("Marshall", iterator.next().getCoveredText()); + assertEquals("Schor", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 5); + ai = cas.getAnnotationIndex(t); + assertEquals(3, ai.size()); + iterator = ai.iterator(); + assertEquals("Kottmann", iterator.next().getCoveredText()); + assertEquals("Marshall", iterator.next().getCoveredText()); + assertEquals("Schor", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 6); + ai = cas.getAnnotationIndex(t); + assertEquals(2, ai.size()); + iterator = ai.iterator(); + assertEquals("Marshall", iterator.next().getCoveredText()); + assertEquals("Schor", iterator.next().getCoveredText()); + + if (cas != null) { + cas.release(); + } + + } +} Added: uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitConditionTest2.java URL: http://svn.apache.org/viewvc/uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitConditionTest2.java?rev=1518196&view=auto ============================================================================== --- uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitConditionTest2.java (added) +++ uima/sandbox/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitConditionTest2.java Wed Aug 28 13:13:45 2013 @@ -0,0 +1,108 @@ +/* + * 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.condition; + +import static org.junit.Assert.assertEquals; + +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.RutaTestUtils; +import org.apache.uima.ruta.engine.Ruta; +import org.junit.Test; + +public class ImplicitConditionTest2 { + + @Test + public void test() { + String document = "Peter Kluegl, Joern Kottmann, Marshall Schor."; + String script = ""; + script += "CW{CW.begin<=14 -> T1};\n"; + script += "CW{CW.begin<14-> T2};\n"; + script += "CW{CW.begin==0-> T3};\n"; + script += "CW{CW.begin!=0-> T4};\n"; + script += "CW{CW.begin>=20-> T5};\n"; + script += "CW{CW.begin>20-> T6};\n"; + 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(3, ai.size()); + iterator = ai.iterator(); + assertEquals("Peter", iterator.next().getCoveredText()); + assertEquals("Kluegl", iterator.next().getCoveredText()); + assertEquals("Joern", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 2); + ai = cas.getAnnotationIndex(t); + assertEquals(2, ai.size()); + iterator = ai.iterator(); + assertEquals("Peter", iterator.next().getCoveredText()); + assertEquals("Kluegl", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 3); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("Peter", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 4); + ai = cas.getAnnotationIndex(t); + assertEquals(5, ai.size()); + iterator = ai.iterator(); + assertEquals("Kluegl", iterator.next().getCoveredText()); + assertEquals("Joern", iterator.next().getCoveredText()); + assertEquals("Kottmann", iterator.next().getCoveredText()); + assertEquals("Marshall", iterator.next().getCoveredText()); + assertEquals("Schor", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 5); + ai = cas.getAnnotationIndex(t); + assertEquals(3, ai.size()); + iterator = ai.iterator(); + assertEquals("Kottmann", iterator.next().getCoveredText()); + assertEquals("Marshall", iterator.next().getCoveredText()); + assertEquals("Schor", iterator.next().getCoveredText()); + + t = RutaTestUtils.getTestType(cas, 6); + ai = cas.getAnnotationIndex(t); + assertEquals(2, ai.size()); + iterator = ai.iterator(); + assertEquals("Marshall", iterator.next().getCoveredText()); + assertEquals("Schor", iterator.next().getCoveredText()); + + if (cas != null) { + cas.release(); + } + + } +} Modified: uima/sandbox/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml URL: http://svn.apache.org/viewvc/uima/sandbox/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml?rev=1518196&r1=1518195&r2=1518196&view=diff ============================================================================== --- uima/sandbox/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml (original) +++ uima/sandbox/ruta/trunk/ruta-docbook/src/docbook/tools.ruta.language.expressions.xml Wed Aug 28 13:13:45 2013 @@ -307,7 +307,9 @@ BooleanListExpression -> BooleanListVa Feature expression can be used in different situations, e.g., for restricting the match of a rule element, as an implicit condition or as an implicit action. <programlisting><![CDATA[FeatureExpression -> TypeExpression "." DottedIdentifier -FeatureMatchExpression -> FeatureExpression "==" Expression +FeatureMatchExpression -> FeatureExpression + ("==" | "!=" | "<=" | "<" | ">=" | ">") + Expression FeatureAssignmentExpression -> FeatureExpression "=" Expression ]]></programlisting> </para> Modified: uima/sandbox/ruta/trunk/ruta-ep-ide/src/main/antlr3/org/apache/uima/ruta/ide/core/parser/RutaParser.g URL: http://svn.apache.org/viewvc/uima/sandbox/ruta/trunk/ruta-ep-ide/src/main/antlr3/org/apache/uima/ruta/ide/core/parser/RutaParser.g?rev=1518196&r1=1518195&r2=1518196&view=diff ============================================================================== --- uima/sandbox/ruta/trunk/ruta-ep-ide/src/main/antlr3/org/apache/uima/ruta/ide/core/parser/RutaParser.g (original) +++ uima/sandbox/ruta/trunk/ruta-ep-ide/src/main/antlr3/org/apache/uima/ruta/ide/core/parser/RutaParser.g Wed Aug 28 13:13:45 2013 @@ -936,7 +936,7 @@ featureAssignmentExpression returns [Exp featureTypeExpression returns [Expression expr = null] : - feature = dottedId (comp = EQUAL | comp = NOTEQUAL) value = argument {expr = ExpressionFactory.createFeatureMatch(feature, comp, value);} + feature = dottedId (comp = LESS | comp = GREATER | comp = GREATEREQUAL | comp = LESSEQUAL |comp = EQUAL | comp = NOTEQUAL) value = argument {expr = ExpressionFactory.createFeatureMatch(feature, comp, value);} ; featureExpression returns [Expression expr = null]