Merge pull request #112 from apache/bugfix/110-Usage-of-labels-within-macro-action-definition-is-broken
Issue #110: Usage of labels within macro action definition is broken
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/action/MacroAction.java b/ruta-core/src/main/java/org/apache/uima/ruta/action/MacroAction.java
index 28c654c..f3bb8f4 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/action/MacroAction.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/action/MacroAction.java
@@ -98,14 +98,6 @@
}
}
- @Override
- public void setLabel(String label) {
- super.setLabel(label);
- for (AbstractRutaAction action : actions) {
- action.setLabel(label);
- }
- }
-
public String getName() {
return name;
}
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java b/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java
index 7c6f653..105f419 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java
@@ -21,10 +21,12 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.uima.cas.text.AnnotationFS;
@@ -33,6 +35,7 @@
import org.apache.uima.ruta.RutaStatement;
import org.apache.uima.ruta.RutaStream;
import org.apache.uima.ruta.action.AbstractRutaAction;
+import org.apache.uima.ruta.action.MacroAction;
import org.apache.uima.ruta.block.RutaBlock;
import org.apache.uima.ruta.visitor.InferenceCrowd;
@@ -109,7 +112,7 @@
ownLabels.add(ruleElement.getLabel());
}
}
- fillLabelMapWithActions(ruleElement.getActions(), own);
+ fillLabelMapWithActions(ruleElement.getActions(), own, new HashSet<>());
if (ruleElement instanceof ComposedRuleElement) {
ComposedRuleElement cre = (ComposedRuleElement) ruleElement;
List<RuleElement> ruleElements = cre.getRuleElements();
@@ -121,15 +124,26 @@
fillLabelMapWithInlinedRules(ruleElement.getInlinedActionRuleBlocks());
}
- private void fillLabelMapWithActions(List<AbstractRutaAction> actions, boolean own) {
+ private void fillLabelMapWithActions(List<AbstractRutaAction> actions, boolean own,
+ Set<AbstractRutaAction> processedActions) {
if (actions != null) {
for (AbstractRutaAction action : actions) {
+ // TODO recursive declarations are not supported right now, but we should check it anyways
+ if (processedActions.contains(action)) {
+ continue;
+ }
+ processedActions.add(action);
+
if (action != null && !StringUtils.isBlank(action.getLabel())) {
labels.put(action.getLabel(), null);
if (own) {
ownLabels.add(action.getLabel());
}
}
+ if (action instanceof MacroAction) {
+ MacroAction macroAction = (MacroAction) action;
+ fillLabelMapWithActions(macroAction.getActions(), own, processedActions);
+ }
}
}
}
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/action/MacroActionTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/action/MacroActionTest.java
index 366899c..8641ad5 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/action/MacroActionTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/action/MacroActionTest.java
@@ -34,9 +34,12 @@
import org.apache.uima.cas.Type;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.cas.text.AnnotationIndex;
+import org.apache.uima.fit.util.CasUtil;
import org.apache.uima.ruta.engine.Ruta;
import org.apache.uima.ruta.engine.RutaTestUtils;
import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature;
+import org.apache.uima.ruta.extensions.RutaParseRuntimeException;
+import org.assertj.core.api.Assertions;
import org.junit.Ignore;
import org.junit.Test;
@@ -89,7 +92,7 @@
public void testLabel() throws Exception {
String document = "Test";
String script = "";
- script += "ACTION doit() = MARK(T1);\n";
+ script += "ACTION doit() = t:MARK(T1);\n";
script += "CW{-> t:doit()}-> {t{->T2};};\n";
CAS cas = RutaTestUtils.getCAS(document);
@@ -100,6 +103,62 @@
}
@Test
+ public void testLabelCombination() throws Exception {
+ String document = "Father: DM2";
+ String script = "";
+ script += "ACTION link(ANNOTATION diag, ANNOTATION ref) = s:Subject,s.ref=ref,d.subject=s;\n";
+ script += "\"Father\"->T1;\n";
+ script += "\"DM2\"->Diagnosis;\n";
+ script += "t1:T1{-> link(d,t1)} COLON? d:Diagnosis;\n";
+
+ Map<String, String> typeMap = new TreeMap<String, String>();
+ String typeName1 = "Diagnosis";
+ typeMap.put(typeName1, CAS.TYPE_NAME_ANNOTATION);
+ String typeName2 = "Subject";
+ typeMap.put(typeName2, CAS.TYPE_NAME_ANNOTATION);
+
+ Map<String, List<TestFeature>> featureMap = new TreeMap<String, List<TestFeature>>();
+ List<TestFeature> list1 = new ArrayList<RutaTestUtils.TestFeature>();
+ List<TestFeature> list2 = new ArrayList<RutaTestUtils.TestFeature>();
+ featureMap.put(typeName1, list1);
+ featureMap.put(typeName2, list2);
+ String fn1 = "subject";
+ String fn2 = "ref";
+ list1.add(new TestFeature(fn1, "", typeName2));
+ list2.add(new TestFeature(fn2, "", CAS.TYPE_NAME_ANNOTATION));
+
+ CAS cas = RutaTestUtils.getCAS(document, typeMap, featureMap);
+ Ruta.apply(cas, script);
+
+ AnnotationFS actualDiagnosis = CasUtil.selectSingle(cas, CasUtil.getType(cas, typeName1));
+ AnnotationFS subjectValue = (AnnotationFS) actualDiagnosis
+ .getFeatureValue(actualDiagnosis.getType().getFeatureByBaseName(fn1));
+
+ Assertions.assertThat(actualDiagnosis).extracting(AnnotationFS::getCoveredText)
+ .isEqualTo("DM2");
+ Assertions.assertThat(subjectValue).extracting(AnnotationFS::getCoveredText)
+ .isEqualTo("Father");
+
+ AnnotationFS refValue = (AnnotationFS) subjectValue
+ .getFeatureValue(subjectValue.getType().getFeatureByBaseName(fn2));
+
+ Assertions.assertThat(refValue).extracting(AnnotationFS::getCoveredText).isEqualTo("Father");
+ }
+
+ @Test(expected = RutaParseRuntimeException.class)
+ public void testRecursiveDeclaration() throws Exception {
+ String document = "Test";
+ String script = "";
+ script += "ACTION action1() = action2();\n";
+ script += "ACTION action2() = action3();\n";
+ script += "ACTION action3() = action1();\n";
+ script += "CW{-> action1()};\n";
+
+ CAS cas = RutaTestUtils.getCAS(document);
+ Ruta.apply(cas, script);
+ }
+
+ @Test
@Ignore
public void testShareSameNameArgumentAndLabel() throws Exception {
String document = "Day 5";