UIMA-6414: Ruta: missing match for optional after sidestep out of composed
- only follow side step before composed fallback, if the origin is within the current container
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java b/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java
index a438cca..d90a999 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java
@@ -201,7 +201,9 @@
if (nextRuleElement != null) {
result = nextRuleElement.continueMatch(after, eachAnchor, extendedMatch, ruleApply,
extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
- } else if (sideStepOrigin != null && !failed) {
+ } else if (sideStepOrigin != null && !failed && containedIn(sideStepOrigin, getContainer())) {
+ // continue directly with the sidestep if it is contained in this container
+ // if not, we might miss matches in the same direction
result = sideStepOrigin.continueSideStep(after, extendedMatch, ruleApply,
extendedContainerMatch, entryPoint, stream, crowd);
} else if (getContainer() instanceof ComposedRuleElement) {
@@ -212,6 +214,26 @@
return result;
}
+ private boolean containedIn(RuleElement sideStepOrigin, RuleElementContainer container) {
+ // TODO: should we support this in interface?
+ if (container == null || sideStepOrigin == null) {
+ return false;
+ }
+ List<RuleElement> ruleElements = container.getRuleElements();
+ if (ruleElements.contains(sideStepOrigin)) {
+ return true;
+ } else {
+ for (RuleElement ruleElement : ruleElements) {
+ if (ruleElement instanceof RuleElementContainer) {
+ if (containedIn(sideStepOrigin, (RuleElementContainer) ruleElement)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public List<RuleMatch> continueMatch(boolean after, AnnotationFS annotation, RuleMatch ruleMatch,
RuleApply ruleApply, ComposedRuleElementMatch containerMatch, RuleElement sideStepOrigin,
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/rule/ManualAnchoringTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/rule/ManualAnchoringTest.java
index 64b7561..385478e 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/rule/ManualAnchoringTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/rule/ManualAnchoringTest.java
@@ -38,6 +38,19 @@
RutaTestUtils.assertAnnotationsEquals(cas, 3, 1, "A, B and C");
- cas.release();
+ }
+
+ @Test
+ public void testComposedInSequence() throws Exception {
+ String text = "bla CAP 1-2 bla";
+
+ String script = "FOREACH(cap) CAP{}{";
+ script += "ANY{-PARTOF(SPECIAL)} @cap (NUM SPECIAL NUM){-> T1} ANY{-PARTOF(SPECIAL)};";
+ script += "}";
+
+ CAS cas = RutaTestUtils.getCAS(text);
+ Ruta.apply(cas, script);
+
+ RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "1-2");
}
}