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 2016/01/04 18:01:29 UTC

svn commit: r1722919 - in /uima/ruta/trunk/ruta-core/src: main/antlr3/org/apache/uima/ruta/parser/ main/java/org/apache/uima/ruta/ main/java/org/apache/uima/ruta/action/ main/java/org/apache/uima/ruta/expression/ main/java/org/apache/uima/ruta/rule/ te...

Author: pkluegl
Date: Mon Jan  4 17:01:29 2016
New Revision: 1722919

URL: http://svn.apache.org/viewvc?rev=1722919&view=rev
Log:
UIMA-4657
- usage of annotation list

Modified:
    uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
    uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaScriptFactory.java
    uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java
    uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/AssignAction.java
    uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java
    uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java
    uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java
    uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaAnnotationMatcher.java
    uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationVariableExpressionTest.java

Modified: uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g (original)
+++ uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g Mon Jan  4 17:01:29 2016
@@ -1930,7 +1930,9 @@ actionAssign returns [AbstractRutaAction
     :
     name = ASSIGN LPAREN
     (
-    {isVariableOfType($blockDeclaration::env, input.LT(1).getText(), "ANNOTATION")||isVariableOfType($blockDeclaration::env, input.LT(1).getText(), "TYPE")}? 
+    {isVariableOfType($blockDeclaration::env, input.LT(1).getText(), "ANNOTATION")||
+    isVariableOfType($blockDeclaration::env, input.LT(1).getText(), "ANNOTATIONLIST")||
+    isVariableOfType($blockDeclaration::env, input.LT(1).getText(), "TYPE")}? 
         nv = Identifier COMMA ea = annotationOrTypeExpression 
         {action = ActionFactory.createAssignAction(nv, ea,$blockDeclaration::env);}
     |
@@ -2219,10 +2221,10 @@ annotationExpression returns [IRutaExpre
 
 annotationExpression2 returns [IRutaExpression expr = null]
 	:
-	{isVariableOfType($blockDeclaration::env,input.LT(1).getText(), "ANNOTATION")	}? 
+	{isVariableOfType($blockDeclaration::env,input.LT(1).getText(), "ANNOTATION")}? 
 	id = Identifier {expr = ExpressionFactory.createAnnotationVariableExpression(id);} 
 	|
-	{isVariableOfType($blockDeclaration::env,input.LT(1).getText(), "ANNOTATIONLIST")	}? 
+	{isVariableOfType($blockDeclaration::env,input.LT(1).getText(), "ANNOTATIONLIST")}? 
 	id = Identifier {expr = ExpressionFactory.createAnnotationListVariableExpression(id);} 
 	|
 	aae = annotationAddressExpression {expr = aae;}

Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaScriptFactory.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaScriptFactory.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaScriptFactory.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaScriptFactory.java Mon Jan  4 17:01:29 2016
@@ -30,6 +30,7 @@ import org.apache.uima.ruta.action.Abstr
 import org.apache.uima.ruta.condition.AbstractRutaCondition;
 import org.apache.uima.ruta.expression.IRutaExpression;
 import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
+import org.apache.uima.ruta.expression.annotation.IAnnotationListExpression;
 import org.apache.uima.ruta.expression.feature.FeatureExpression;
 import org.apache.uima.ruta.expression.number.INumberExpression;
 import org.apache.uima.ruta.expression.string.IStringExpression;
@@ -145,6 +146,8 @@ public class RutaScriptFactory {
       matcher = new RutaTypeMatcher((FeatureExpression) expression);
     } else if (expression instanceof IAnnotationExpression) {
       matcher = new RutaAnnotationMatcher((IAnnotationExpression) expression);
+    } else if (expression instanceof IAnnotationListExpression) {
+      matcher = new RutaAnnotationMatcher((IAnnotationListExpression) expression);
     } else if (expression instanceof IStringExpression) {
       matcher = new RutaLiteralMatcher((IStringExpression) expression);
     } else {

Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java Mon Jan  4 17:01:29 2016
@@ -957,21 +957,12 @@ public class RutaStream extends FSIterat
       annotation.setBooleanValue(feature, v);
     } else if (value instanceof AnnotationTypeExpression && !feature.getRange().isPrimitive()) {
       AnnotationTypeExpression ate = (AnnotationTypeExpression) value;
-      AnnotationFS a = ate.getAnnotation(context, this);
-      if (a != null) {
-        // TODO support annotation list expressions
-        if (feature.getRange().isArray()) {
-          List<AnnotationFS> c = new ArrayList<AnnotationFS>();
-          c.add(a);
-          annotation.setFeatureValue(feature, UIMAUtils.toFSArray(this.getJCas(), c));
-        } else {
-          annotation.setFeatureValue(feature, a);
-        }
+      if (feature.getRange().isArray()) {
+        List<AnnotationFS> annotations = ate.getAnnotations(context, this);
+        annotation.setFeatureValue(feature, UIMAUtils.toFSArray(this.getJCas(), annotations));
       } else {
-        Type t = ate.getType(context, this);
-        if(t != null) {
-          assignAnnotationByTypeInWindow(annotation, feature, context, t);
-        }
+        AnnotationFS a = ate.getAnnotation(context, this);
+        annotation.setFeatureValue(feature, a);
       }
     } else if (value instanceof IAnnotationExpression && !feature.getRange().isPrimitive()) {
       IAnnotationExpression ae = (IAnnotationExpression) value;

Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/AssignAction.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/AssignAction.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/AssignAction.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/AssignAction.java Mon Jan  4 17:01:29 2016
@@ -19,6 +19,8 @@
 
 package org.apache.uima.ruta.action;
 
+import java.util.List;
+
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.ruta.RutaBlock;
@@ -26,6 +28,7 @@ import org.apache.uima.ruta.RutaEnvironm
 import org.apache.uima.ruta.RutaStream;
 import org.apache.uima.ruta.expression.IRutaExpression;
 import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
+import org.apache.uima.ruta.expression.annotation.IAnnotationListExpression;
 import org.apache.uima.ruta.expression.bool.IBooleanExpression;
 import org.apache.uima.ruta.expression.number.INumberExpression;
 import org.apache.uima.ruta.expression.string.IStringExpression;
@@ -70,6 +73,12 @@ public class AssignAction extends Abstra
     } else if (clazz.equals(AnnotationFS.class) && expression instanceof IAnnotationExpression) {
       AnnotationFS v = ((IAnnotationExpression) expression).getAnnotation(context, stream);
       environment.setVariableValue(var, v);
+    } else if(clazz.equals(List.class)) {
+      Class<?> variableGenericType = environment.getVariableGenericType(var);
+      if(variableGenericType.equals(AnnotationFS.class) && expression instanceof IAnnotationListExpression) {
+         List<AnnotationFS> v = ((IAnnotationListExpression) expression).getAnnotations(context, stream);
+         environment.setVariableValue(var, v);
+      }
     }
   }
 

Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java Mon Jan  4 17:01:29 2016
@@ -19,24 +19,30 @@
 
 package org.apache.uima.ruta.expression;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.ruta.RutaStream;
 import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
+import org.apache.uima.ruta.expression.annotation.IAnnotationListExpression;
 import org.apache.uima.ruta.expression.type.ITypeExpression;
 import org.apache.uima.ruta.rule.MatchContext;
 
-public class AnnotationTypeExpression extends RutaExpression implements ITypeExpression, IAnnotationExpression {
- 
-  
+public class AnnotationTypeExpression extends RutaExpression implements ITypeExpression,
+        IAnnotationExpression, IAnnotationListExpression {
+
   private MatchReference reference;
-  
+
   private ITypeExpression typeExpression;
-  
+
   private IAnnotationExpression annotationExpression;
 
+  private IAnnotationListExpression annotationListExpression;
+
   private boolean initialized = false;
-  
+
   public AnnotationTypeExpression(MatchReference reference) {
     super();
     this.reference = reference;
@@ -44,21 +50,25 @@ public class AnnotationTypeExpression ex
 
   private void initialize(MatchContext context, RutaStream stream) {
     annotationExpression = reference.getAnnotationExpression(context, stream);
+    annotationListExpression = reference.getAnnotationListExpression(context, stream);
     typeExpression = reference.getTypeExpression(context, stream);
     initialized = true;
   }
-  
-  
+
   @Override
   public AnnotationFS getAnnotation(MatchContext context, RutaStream stream) {
     if (!initialized) {
       initialize(context, stream);
     }
-    if(annotationExpression != null) {
+    if (annotationExpression != null) {
       return annotationExpression.getAnnotation(context, stream);
+    } else if (annotationListExpression != null) {
+      List<AnnotationFS> annotations = annotationListExpression.getAnnotations(context, stream);
+      if (annotations != null && !annotations.isEmpty())
+        return annotations.get(0);
     } else {
       Type type = getType(context, stream);
-      if(type != null) {
+      if (type != null) {
         return stream.getSingleAnnotationByTypeInContext(type, context);
       }
     }
@@ -70,11 +80,11 @@ public class AnnotationTypeExpression ex
     if (!initialized) {
       initialize(context, stream);
     }
-    if(typeExpression != null) {
+    if (typeExpression != null) {
       return typeExpression.getType(context, stream);
     } else {
       AnnotationFS annotation = getAnnotation(context, stream);
-      if(annotation!= null) {
+      if (annotation != null) {
         return annotation.getType();
       }
     }
@@ -86,14 +96,31 @@ public class AnnotationTypeExpression ex
     if (!initialized) {
       initialize(context, stream);
     }
-    if(annotationExpression != null) {
+    if (annotationExpression != null) {
       return annotationExpression.getStringValue(context, stream);
     } else {
       return typeExpression.getStringValue(context, stream);
     }
   }
 
-  
-  
-  
+  @Override
+  public List<AnnotationFS> getAnnotations(MatchContext context, RutaStream stream) {
+    if (!initialized) {
+      initialize(context, stream);
+    }
+    if (annotationListExpression != null) {
+      return annotationListExpression.getAnnotations(context, stream);
+    } else if (annotationExpression != null) {
+      List<AnnotationFS> result = new ArrayList<AnnotationFS>(1);
+      result.add(annotationExpression.getAnnotation(context, stream));
+      return result;
+    } else {
+      Type type = getType(context, stream);
+      if (type != null) {
+        return stream.getAnnotationsByTypeInContext(type, context);
+      }
+    }
+    return null;
+  }
+
 }

Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java Mon Jan  4 17:01:29 2016
@@ -27,6 +27,7 @@ import org.apache.uima.ruta.RutaBlock;
 import org.apache.uima.ruta.expression.annotation.AnnotationAddressExpression;
 import org.apache.uima.ruta.expression.annotation.AnnotationFeatureExpression;
 import org.apache.uima.ruta.expression.annotation.AnnotationLabelExpression;
+import org.apache.uima.ruta.expression.annotation.AnnotationListVariableExpression;
 import org.apache.uima.ruta.expression.annotation.AnnotationVariableExpression;
 import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
 import org.apache.uima.ruta.expression.bool.BooleanFeatureExpression;
@@ -312,7 +313,7 @@ public class ExpressionFactory {
   }
 
   public static IRutaExpression createAnnotationListVariableExpression(Token var) {
-    return null;
+    return new AnnotationListVariableExpression(var.getText());
   }
 
   public static IAnnotationExpression createAnnotationFeatureExpression(

Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java Mon Jan  4 17:01:29 2016
@@ -26,8 +26,10 @@ import org.apache.uima.ruta.RutaBlock;
 import org.apache.uima.ruta.RutaEnvironment;
 import org.apache.uima.ruta.RutaStream;
 import org.apache.uima.ruta.expression.annotation.AnnotationLabelExpression;
+import org.apache.uima.ruta.expression.annotation.AnnotationListVariableExpression;
 import org.apache.uima.ruta.expression.annotation.AnnotationVariableExpression;
 import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
+import org.apache.uima.ruta.expression.annotation.IAnnotationListExpression;
 import org.apache.uima.ruta.expression.feature.FeatureExpression;
 import org.apache.uima.ruta.expression.feature.SimpleFeatureExpression;
 import org.apache.uima.ruta.expression.type.ITypeExpression;
@@ -44,6 +46,8 @@ public class MatchReference extends Ruta
   private ITypeExpression typeExpression;
   
   private IAnnotationExpression annotationExpression;
+  
+  private IAnnotationListExpression annotationListExpression;
 
   private FeatureExpression featureExpression;
 
@@ -85,7 +89,7 @@ public class MatchReference extends Ruta
       }
     }
     initialized = true;
-    if (typeExpression == null && annotationExpression == null) {
+    if (typeExpression == null && annotationExpression == null && annotationListExpression == null) {
       throw new IllegalArgumentException("Not able to resolve annotation/type expression: " + reference);
     }
   }
@@ -97,6 +101,9 @@ public class MatchReference extends Ruta
     } else if (e.isVariableOfType(candidate, "ANNOTATION")) {
       annotationExpression = new AnnotationVariableExpression(candidate);
       return true;
+    } else if (e.isVariableOfType(candidate, "ANNOTATIONLIST")) {
+      annotationListExpression = new AnnotationListVariableExpression(candidate);
+      return true;
     } else if (e.getType(candidate) != null) {
       typeExpression = new SimpleTypeExpression(candidate);
       return true;
@@ -120,6 +127,11 @@ public class MatchReference extends Ruta
     resolve(context, stream);
     return annotationExpression;
   }
+  
+  public IAnnotationListExpression getAnnotationListExpression(MatchContext context, RutaStream stream) {
+    resolve(context, stream);
+    return annotationListExpression;
+  }
 
   public FeatureExpression getFeatureExpression(MatchContext context, RutaStream stream) {
     resolve(context, stream);

Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaAnnotationMatcher.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaAnnotationMatcher.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaAnnotationMatcher.java (original)
+++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaAnnotationMatcher.java Mon Jan  4 17:01:29 2016
@@ -31,6 +31,7 @@ import org.apache.uima.ruta.RutaBlock;
 import org.apache.uima.ruta.RutaStream;
 import org.apache.uima.ruta.expression.IRutaExpression;
 import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
+import org.apache.uima.ruta.expression.annotation.IAnnotationListExpression;
 import org.apache.uima.ruta.type.RutaBasic;
 
 public class RutaAnnotationMatcher implements RutaMatcher {
@@ -39,20 +40,34 @@ public class RutaAnnotationMatcher imple
 
   private IAnnotationExpression annotationExpression;
 
-  public RutaAnnotationMatcher(IAnnotationExpression annotationExpression) {
+  private IAnnotationListExpression annotationListExpression;
+
+  public RutaAnnotationMatcher(IAnnotationExpression expression) {
+    super();
+    this.annotationExpression = expression;
+    this.comparator = new AnnotationComparator();
+  }
+
+  public RutaAnnotationMatcher(IAnnotationListExpression expression) {
     super();
-    this.annotationExpression = annotationExpression;
+    this.annotationListExpression = expression;
     this.comparator = new AnnotationComparator();
   }
+
   public Collection<AnnotationFS> getMatchingAnnotations(RutaStream stream, RutaBlock parent) {
     // TODO what about the matching direction?
-    Collection<AnnotationFS> annotations = new TreeSet<AnnotationFS>(comparator);
     MatchContext context = new MatchContext(parent);
-    AnnotationFS annotation = annotationExpression.getAnnotation(context, stream);
-    if(annotation != null) {
-      annotations.add(annotation);
+    if (annotationExpression != null) {
+      Collection<AnnotationFS> annotations = new TreeSet<AnnotationFS>(comparator);
+      AnnotationFS annotation = annotationExpression.getAnnotation(context, stream);
+      if (annotation != null) {
+        annotations.add(annotation);
+      }
+      return annotations;
+    } else if (annotationListExpression != null) {
+      return annotationListExpression.getAnnotations(context, stream);
     }
-    return annotations;
+    return Collections.emptyList();
   }
 
   public Collection<AnnotationFS> getAnnotationsAfter(RutaRuleElement ruleElement,
@@ -90,14 +105,27 @@ public class RutaAnnotationMatcher imple
         }
       }
       MatchContext context = new MatchContext(parent);
-      AnnotationFS ref = annotationExpression.getAnnotation(context, stream);
-      boolean beginsWith = nextBasic.beginsWith(ref.getType());
-      if(beginsWith) {
-        Collection<AnnotationFS> result = new ArrayList<>(1);
-        result.add(ref);
+      if (annotationExpression != null) {
+
+        AnnotationFS ref = annotationExpression.getAnnotation(context, stream);
+        boolean beginsWith = nextBasic.beginsWith(ref.getType());
+        if (beginsWith) {
+          Collection<AnnotationFS> result = new ArrayList<>(1);
+          result.add(ref);
+          return result;
+        }
+      } else if (annotationListExpression != null) {
+        List<AnnotationFS> annotations = annotationListExpression.getAnnotations(context, stream);
+        Collection<AnnotationFS> result = new ArrayList<>();
+        for (AnnotationFS each : annotations) {
+          boolean beginsWith = nextBasic.beginsWith(each.getType());
+          if (beginsWith) {
+            result.add(each);
+          }
+        }
         return result;
       }
-      
+
     }
     return Collections.emptyList();
   }
@@ -126,12 +154,24 @@ public class RutaAnnotationMatcher imple
         }
       }
       MatchContext context = new MatchContext(parent);
-      AnnotationFS ref = annotationExpression.getAnnotation(context, stream);
-      boolean endsWith = nextBasic.beginsWith(ref.getType());
-      if(endsWith) {
-        Collection<AnnotationFS> result = new ArrayList<>(1);
-        result.add(ref);
-        return result;
+      if (annotationExpression != null) {
+        AnnotationFS ref = annotationExpression.getAnnotation(context, stream);
+        boolean endsWith = nextBasic.beginsWith(ref.getType());
+        if (endsWith) {
+          Collection<AnnotationFS> result = new ArrayList<>(1);
+          result.add(ref);
+          return result;
+        }
+      } else if (annotationListExpression != null) {
+        List<AnnotationFS> annotations = annotationListExpression.getAnnotations(context, stream);
+        for (AnnotationFS each : annotations) {
+          boolean endsWith = nextBasic.beginsWith(each.getType());
+          if (endsWith) {
+            Collection<AnnotationFS> result = new ArrayList<>();
+            result.add(each);
+            return result;
+          }
+        }
       }
     }
     return Collections.emptyList();
@@ -142,26 +182,54 @@ public class RutaAnnotationMatcher imple
       return false;
     }
     MatchContext context = new MatchContext(parent);
-    AnnotationFS ref = annotationExpression.getAnnotation(context, stream);
-
-    return annotation.equals(ref);
+    if (annotationExpression != null) {
+      AnnotationFS ref = annotationExpression.getAnnotation(context, stream);
 
+      return annotation.equals(ref);
+    } else if (annotationListExpression != null) {
+      List<AnnotationFS> annotations = annotationListExpression.getAnnotations(context, stream);
+      for (AnnotationFS each : annotations) {
+        if (each.equals(annotation)) {
+          return true;
+        }
+      }
+    }
+    return false;
   }
+
   @Override
   public List<Type> getTypes(RutaBlock parent, RutaStream stream) {
     MatchContext context = new MatchContext(parent);
+    if(annotationExpression != null) {
+      
     AnnotationFS ref = annotationExpression.getAnnotation(context, stream);
-    if(ref == null) {
+    if (ref == null) {
       return Collections.emptyList();
     }
     List<Type> result = new ArrayList<Type>(1);
     result.add(ref.getType());
     return result;
+    } else if(annotationListExpression != null) {
+      List<AnnotationFS> annotations = annotationListExpression.getAnnotations(context, stream);
+      List<Type> result = new ArrayList<Type>();
+      for (AnnotationFS each : annotations) {
+        result.add(each.getType());
+      }
+      return result;
+    }
+    return Collections.emptyList();
   }
+
   @Override
   public IRutaExpression getExpression() {
-    return annotationExpression;
+    if (annotationExpression != null) {
+      return annotationExpression;
+    } else if (annotationListExpression != null) {
+      return annotationListExpression;
+    }
+    return null;
   }
+
   @Override
   public long estimateAnchors(RutaBlock parent, RutaStream stream) {
     return 1;

Modified: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationVariableExpressionTest.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationVariableExpressionTest.java?rev=1722919&r1=1722918&r2=1722919&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationVariableExpressionTest.java (original)
+++ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationVariableExpressionTest.java Mon Jan  4 17:01:29 2016
@@ -33,6 +33,7 @@ import org.apache.uima.cas.Feature;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.cas.text.AnnotationIndex;
+import org.apache.uima.jcas.cas.FSArray;
 import org.apache.uima.ruta.engine.Ruta;
 import org.apache.uima.ruta.engine.RutaTestUtils;
 import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature;
@@ -40,13 +41,64 @@ import org.junit.Test;
 
 public class AnnotationVariableExpressionTest {
 
+//  @Test
+//  public void test() {
+//    String document = "Some text.";
+//    String script = "ANNOTATION a;";
+//    script += "CW{-> ASSIGN(a, CW)};";
+//    script += "a{-> T1};";
+//    script += "W W{-> CREATE(Struct, \"a\"=a)};";
+//
+//    Map<String, String> typeMap = new TreeMap<String, String>();
+//    String typeName = "Struct";
+//    typeMap.put(typeName, "uima.tcas.Annotation");
+//
+//    Map<String, List<TestFeature>> featureMap = new TreeMap<String, List<TestFeature>>();
+//    List<TestFeature> list = new ArrayList<RutaTestUtils.TestFeature>();
+//    featureMap.put(typeName, list);
+//    String fn = "a";
+//    list.add(new TestFeature(fn, "", "uima.tcas.Annotation"));
+//
+//    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;
+//    AnnotationFS next = null;
+//
+//    Type t1 = RutaTestUtils.getTestType(cas, 1);
+//    ai = cas.getAnnotationIndex(t1);
+//    assertEquals(1, ai.size());
+//    iterator = ai.iterator();
+//    next = iterator.next();
+//    assertEquals("Some", next.getCoveredText());
+//
+//    t = cas.getTypeSystem().getType(typeName);
+//    Feature f1 = t.getFeatureByBaseName(fn);
+//    ai = cas.getAnnotationIndex(t);
+//
+//    assertEquals(1, ai.size());
+//    iterator = ai.iterator();
+//    next = iterator.next();
+//    assertEquals("text", next.getCoveredText());
+//    AnnotationFS a = (AnnotationFS) next.getFeatureValue(f1);
+//    assertNotNull("Feature value is null!", a);
+//    assertEquals("Some", a.getCoveredText());
+//  }
+
   @Test
-  public void test() {
+  public void testList() {
     String document = "Some text.";
-    String script = "ANNOTATION a;";
-    script += "CW{-> ASSIGN(a, CW)};";
-    script += "a{-> T1};";
-    script += "W W{-> CREATE(Struct, \"a\"=a)};";
+    String script = "ANNOTATIONLIST as;";
+    script += "Document{-> ASSIGN(as, W)};";
+    script += "as{-> T1};";
+    script += "W W{-> CREATE(Struct, \"as\"=as)};";
 
     Map<String, String> typeMap = new TreeMap<String, String>();
     String typeName = "Struct";
@@ -55,8 +107,8 @@ public class AnnotationVariableExpressio
     Map<String, List<TestFeature>> featureMap = new TreeMap<String, List<TestFeature>>();
     List<TestFeature> list = new ArrayList<RutaTestUtils.TestFeature>();
     featureMap.put(typeName, list);
-    String fn = "a";
-    list.add(new TestFeature(fn, "", "uima.tcas.Annotation"));
+    String fn = "as";
+    list.add(new TestFeature(fn, "", "uima.cas.FSArray"));
 
     CAS cas = null;
     try {
@@ -71,12 +123,7 @@ public class AnnotationVariableExpressio
     FSIterator<AnnotationFS> iterator = null;
     AnnotationFS next = null;
 
-    Type t1 = RutaTestUtils.getTestType(cas, 1);
-    ai = cas.getAnnotationIndex(t1);
-    assertEquals(1, ai.size());
-    iterator = ai.iterator();
-    next = iterator.next();
-    assertEquals("Some", next.getCoveredText());
+    RutaTestUtils.assertAnnotationsEquals(cas, 1, 2, "Some", "text");
 
     t = cas.getTypeSystem().getType(typeName);
     Feature f1 = t.getFeatureByBaseName(fn);
@@ -86,9 +133,9 @@ public class AnnotationVariableExpressio
     iterator = ai.iterator();
     next = iterator.next();
     assertEquals("text", next.getCoveredText());
-    AnnotationFS a = (AnnotationFS) next.getFeatureValue(f1);
-    assertNotNull("Feature value is null!", a);
-    assertEquals("Some", a.getCoveredText());
+    FSArray array = (FSArray) next.getFeatureValue(f1);
+    assertNotNull("Feature value is null!", array);
+    assertEquals(2, array.size());
   }
-
+  
 }