Author: pkluegl Date: Fri Dec 14 15:06:46 2018 New Revision: 1848947 URL: http://svn.apache.org/viewvc?rev=1848947&view=rev Log: UIMA-5910: support string types with allowed values, added test
Added: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/string/ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/string/StringSubtypeAllowedValuesTest.java Modified: 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/GetFeatureAction.java uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/MarkTableAction.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/resource/MultiTreeWordList.java uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RegExpRule.java uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatch1Test.java uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/action/ImplicitActionTest.java uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/FeatureTest.java uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition1Test.java 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=1848947&r1=1848946&r2=1848947&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 Fri Dec 14 15:06:46 2018 @@ -598,7 +598,7 @@ public class RutaStream extends FSIterat } public List<AnnotationFS> getAnnotationsInWindow(AnnotationFS windowAnnotation, Type type) { - + if (windowAnnotation == null || type == null) { return Collections.emptyList(); } @@ -967,8 +967,8 @@ public class RutaStream extends FSIterat Feature feature = type.getFeatureByBaseName(featureName); if (feature == null) { throw new IllegalArgumentException("Not able to assign feature value for feature '" - + featureName + "'. Feature is not defined for type '" + type.getName() + "'" - + " in script " +context.getParent().getName()); + + featureName + "'. Feature is not defined for type '" + type.getName() + "'" + + " in script " + context.getParent().getName()); } assignFeatureValue(annotation, feature, value, context); } @@ -977,12 +977,16 @@ public class RutaStream extends FSIterat public void assignFeatureValue(FeatureStructure annotation, Feature feature, IRutaExpression value, MatchContext context) { if (feature == null) { - throw new IllegalArgumentException("Not able to assign feature value (e.g., coveredText) in script " +context.getParent().getName()); + throw new IllegalArgumentException( + "Not able to assign feature value (e.g., coveredText) in script " + + context.getParent().getName()); } CAS cas = annotation.getCAS(); + TypeSystem typeSystem = cas.getTypeSystem(); Type range = feature.getRange(); String rangeName = range.getName(); - if (rangeName.equals(CAS.TYPE_NAME_STRING)) { + + if (typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range)) { if (value instanceof IStringExpression) { IStringExpression stringExpr = (IStringExpression) value; String string = stringExpr.getStringValue(context, this); @@ -1331,7 +1335,7 @@ public class RutaStream extends FSIterat return cas.getAnnotationType(); } - + public RutaAnnotation getRutaAnnotationFor(AnnotationFS annotation, boolean create, RutaStream stream) { Type heuristicType = this.cas.getTypeSystem().getType(RutaAnnotation.class.getName()); Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/GetFeatureAction.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/GetFeatureAction.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/GetFeatureAction.java (original) +++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/GetFeatureAction.java Fri Dec 14 15:06:46 2018 @@ -24,6 +24,7 @@ import java.util.List; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; +import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.ruta.RutaEnvironment; import org.apache.uima.ruta.RutaStream; @@ -64,14 +65,17 @@ public class GetFeatureAction extends Ab List<AnnotationFS> matchedAnnotations = match.getMatchedAnnotationsOfElement(element); for (AnnotationFS annotationFS : matchedAnnotations) { if (annotationFS.getType().getFeatureByBaseName(stringValue) == null) { + // TODO replace syso by logger System.out.println("Can't access feature " + stringValue + ", because it's not defined in the matched type: " + annotationFS.getType()); return; } - String featName = featureByBaseName.getRange().getName(); + TypeSystem typeSystem = stream.getCas().getTypeSystem(); + Type range = featureByBaseName.getRange(); + String featName = range.getName(); if (environment.getVariableType(variable).equals(String.class) - && featName.equals(CAS.TYPE_NAME_STRING)) { + && typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range)) { Object value = annotationFS.getStringValue(featureByBaseName); environment.setVariableValue(variable, value); } else if (Number.class.isAssignableFrom(environment.getVariableType(variable))) { @@ -95,7 +99,7 @@ public class GetFeatureAction extends Ab Object value = annotationFS.getBooleanValue(featureByBaseName); environment.setVariableValue(variable, value); } else if (environment.getVariableType(variable).equals(Type.class) - && featName.equals(CAS.TYPE_NAME_STRING)) { + && typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range)) { Object value = annotationFS.getStringValue(featureByBaseName); Type t = stream.getCas().getTypeSystem().getType((String) value); if (t != null) { Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/MarkTableAction.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/MarkTableAction.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/MarkTableAction.java (original) +++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/action/MarkTableAction.java Fri Dec 14 15:06:46 2018 @@ -29,13 +29,13 @@ import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; +import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.tcas.Annotation; import org.apache.uima.ruta.RutaStream; import org.apache.uima.ruta.engine.RutaEngine; import org.apache.uima.ruta.expression.bool.IBooleanExpression; -import org.apache.uima.ruta.expression.bool.SimpleBooleanExpression; import org.apache.uima.ruta.expression.number.INumberExpression; import org.apache.uima.ruta.expression.resource.WordTableExpression; import org.apache.uima.ruta.expression.string.IStringExpression; @@ -92,7 +92,7 @@ public class MarkTableAction extends Abs RuleElement element = context.getElement(); element.getParent(); RutaTable table = tableExpr.getTable(context, stream); - if(table == null) { + if (table == null) { return; } int index = indexExpr.getIntegerValue(context, stream); @@ -110,7 +110,8 @@ public class MarkTableAction extends Abs String ignoreCharValue = ignoreChar != null ? ignoreChar.getStringValue(context, stream) : ""; int maxIgnoreCharValue = maxIgnoreChar != null ? maxIgnoreChar.getIntegerValue(context, stream) : 0; - boolean ignoreWSValue = ignoreWS != null ? ignoreWS.getBooleanValue(context, stream) : getDictWSParamValue(context); + boolean ignoreWSValue = ignoreWS != null ? ignoreWS.getBooleanValue(context, stream) + : getDictWSParamValue(context); RutaWordList wordList = table.getWordList(index, element.getParent()); Collection<AnnotationFS> found = wordList.find(stream, ignoreCaseValue, ignoreLengthValue, @@ -145,12 +146,15 @@ public class MarkTableAction extends Abs } private boolean getDictWSParamValue(MatchContext context) { - return (Boolean) context.getParent().getContext().getConfigParameterValue(RutaEngine.PARAM_DICT_REMOVE_WS); + return (Boolean) context.getParent().getContext() + .getConfigParameterValue(RutaEngine.PARAM_DICT_REMOVE_WS); } private void fillFeatures(TOP structure, Map<String, Integer> map, AnnotationFS annotationFS, RuleElement element, List<String> row, RutaStream stream) { List<?> featuresList = structure.getType().getFeatures(); + TypeSystem typeSystem = stream.getCas().getTypeSystem(); + for (int i = 0; i < featuresList.size(); i++) { Feature targetFeature = (Feature) featuresList.get(i); String name = targetFeature.getName(); @@ -159,7 +163,7 @@ public class MarkTableAction extends Abs Type range = targetFeature.getRange(); if (entryIndex != null && row.size() >= entryIndex) { String value = row.get(entryIndex - 1); - if (range.getName().equals(CAS.TYPE_NAME_STRING)) { + if (typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range)) { structure.setStringValue(targetFeature, value); } else if (range.getName().equals(CAS.TYPE_NAME_INTEGER)) { Integer integer = Integer.parseInt(value); 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=1848947&r1=1848946&r2=1848947&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 Fri Dec 14 15:06:46 2018 @@ -27,6 +27,8 @@ import java.util.List; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; +import org.apache.uima.cas.Type; +import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.ruta.RutaStream; import org.apache.uima.ruta.expression.IRutaExpression; @@ -76,46 +78,47 @@ public class FeatureMatchExpression exte public boolean checkFeatureValue(FeatureStructure fs, Feature feature, MatchContext context, RutaStream stream) { - String rn = null; - if(feature instanceof CoveredTextFeature) { - rn = CAS.TYPE_NAME_STRING; - } else if (feature != null){ - rn = feature.getRange().getName(); + Type featureRangeType = null; + TypeSystem typeSystem = stream.getCas().getTypeSystem(); + if (feature instanceof CoveredTextFeature) { + featureRangeType = typeSystem.getType(CAS.TYPE_NAME_STRING); + } else if (feature != null) { + featureRangeType = feature.getRange(); } - - if (rn.equals(CAS.TYPE_NAME_BOOLEAN)) { + String rangeName = featureRangeType.getName(); + if (rangeName.equals(CAS.TYPE_NAME_BOOLEAN)) { Boolean v1 = fs.getBooleanValue(feature); if (getArg() instanceof IBooleanExpression) { IBooleanExpression expr = (IBooleanExpression) getArg(); Boolean v2 = expr.getBooleanValue(context, stream); return compare(v1, v2); } - } else if (rn.equals(CAS.TYPE_NAME_INTEGER) || rn.equals(CAS.TYPE_NAME_BYTE) - || rn.equals(CAS.TYPE_NAME_SHORT) || rn.equals(CAS.TYPE_NAME_LONG)) { + } else if (rangeName.equals(CAS.TYPE_NAME_INTEGER) || rangeName.equals(CAS.TYPE_NAME_BYTE) + || rangeName.equals(CAS.TYPE_NAME_SHORT) || rangeName.equals(CAS.TYPE_NAME_LONG)) { Integer v1 = fs.getIntValue(feature); if (getArg() instanceof INumberExpression) { INumberExpression expr = (INumberExpression) getArg(); Integer v2 = expr.getIntegerValue(context, stream); return compare(v1, v2); } - } else if (rn.equals(CAS.TYPE_NAME_DOUBLE)) { + } else if (rangeName.equals(CAS.TYPE_NAME_DOUBLE)) { Double v1 = fs.getDoubleValue(feature); if (getArg() instanceof INumberExpression) { INumberExpression expr = (INumberExpression) getArg(); Double v2 = expr.getDoubleValue(context, stream); return compare(v1, v2); } - } else if (rn.equals(CAS.TYPE_NAME_FLOAT)) { + } else if (rangeName.equals(CAS.TYPE_NAME_FLOAT)) { Float v1 = fs.getFloatValue(feature); if (getArg() instanceof INumberExpression) { INumberExpression expr = (INumberExpression) getArg(); Float v2 = expr.getFloatValue(context, stream); return compare(v1, v2); } - } else if (rn.equals(CAS.TYPE_NAME_STRING)) { + } else if (typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), featureRangeType)) { String v1 = null; // null is possibly coveredText - if(feature instanceof CoveredTextFeature && fs instanceof AnnotationFS) { + if (feature instanceof CoveredTextFeature && fs instanceof AnnotationFS) { v1 = ((AnnotationFS) fs).getCoveredText(); } else if (feature != null) { v1 = fs.getStringValue(feature); @@ -129,8 +132,8 @@ public class FeatureMatchExpression exte FeatureExpression fe = (FeatureExpression) getArg(); List<FeatureStructure> list = new ArrayList<>(1); list.add(fs); - Collection<? extends FeatureStructure> featureAnnotations = fe.getFeatureStructures(list, false, context, - stream); + Collection<? extends FeatureStructure> featureAnnotations = fe.getFeatureStructures(list, + false, context, stream); return compare(fs.getFeatureValue(feature), featureAnnotations); } return false; @@ -188,13 +191,13 @@ public class FeatureMatchExpression exte @Override public String toString() { String result = super.toString(); - if(op != null) { + if (op != null) { result += op; } - if(arg != null) { + if (arg != null) { result += arg.toString(); } return result; } - + } Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/resource/MultiTreeWordList.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/resource/MultiTreeWordList.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/resource/MultiTreeWordList.java (original) +++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/resource/MultiTreeWordList.java Fri Dec 14 15:06:46 2018 @@ -41,6 +41,7 @@ import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; +import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.ruta.RutaStream; import org.apache.uima.ruta.type.RutaBasic; @@ -66,7 +67,9 @@ public class MultiTreeWordList implement /** * Default constructor. - * @throws IOException - should not happen but required by called constructor + * + * @throws IOException + * - should not happen but required by called constructor */ public MultiTreeWordList() throws IOException { this(new String[] {}, null); @@ -80,7 +83,7 @@ public class MultiTreeWordList implement * @param base * the relative base * @throws IOException - * When there is a problem reading pathname. + * When there is a problem reading pathname. */ public MultiTreeWordList(String pathname, File base) throws IOException { this(new FileSystemResource(pathname)); @@ -143,7 +146,8 @@ public class MultiTreeWordList implement * * @param pathnames * path of the file to create a TextWordList from - * @param base - the relative base + * @param base + * - the relative base * @throws IOException * When there is a problem reading a path. */ @@ -157,9 +161,12 @@ public class MultiTreeWordList implement } /** - * @param files - the input files - * @param base - the relative base - * @throws IOException - When there is a problem reading the files. + * @param files + * - the input files + * @param base + * - the relative base + * @throws IOException + * - When there is a problem reading the files. */ public MultiTreeWordList(List<File> files, File base) throws IOException { this.root = new MultiTextNode(); @@ -215,7 +222,8 @@ public class MultiTreeWordList implement } else if (name.endsWith(".mtwl")) { persistence.readMTWL(root, stream, "UTF-8"); } else { - throw new IllegalArgumentException("File name should end with .mtwl or .txt, found " + name); + throw new IllegalArgumentException( + "File name should end with .mtwl or .txt, found " + name); } } finally { IOUtils.closeQuietly(stream); @@ -225,8 +233,10 @@ public class MultiTreeWordList implement /** * Creates a new Tree in the existing treeWordList from a file with path pathname * - * @param stream - Input stream for the file containing the words for the treeWordList - * @param name - Associated name for the file + * @param stream + * - Input stream for the file containing the words for the treeWordList + * @param name + * - Associated name for the file * @throws IOException * When there is a problem reading the inputstream. */ @@ -573,8 +583,8 @@ public class MultiTreeWordList implement Map<String, Set<String>> resultMap = null; if (!edit) { - return recursiveContains2(root, string, 0, ignoreCase && string.length() > ignoreLength, - true, ignoreToken.toCharArray(), ignoreLength); + return recursiveContains2(root, string, 0, ignoreCase && string.length() > ignoreLength, true, + ignoreToken.toCharArray(), ignoreLength); } else { if (string.length() >= ignoreLength && ignoreCase) { resultMap = editDistance(string, (int) distance, true, ignoreToken, true); @@ -823,8 +833,8 @@ public class MultiTreeWordList implement } List<String> types = null; if (!skip) { - types = containsFragment(candidate.toString(), ignoreCase, ignoreLength, edit, - distance, ignoreToken); + types = containsFragment(candidate.toString(), ignoreCase, ignoreLength, edit, distance, + ignoreToken); } if (skip || types != null) { streamPointer.moveToNext(); @@ -909,7 +919,7 @@ public class MultiTreeWordList implement int end = basicsToAdd.get(basicsToAdd.size() - 1).getEnd(); AnnotationFS newFS = stream.getCas().createAnnotation(type, begin, end); Feature feature = type.getFeatureByBaseName(featureString); - setFeatureValue(newFS, feature, value); + setFeatureValue(newFS, feature, value, stream); results.add(newFS); } } @@ -920,11 +930,14 @@ public class MultiTreeWordList implement } } - private void setFeatureValue(AnnotationFS annotationFS, Feature feature, Object o) { + private void setFeatureValue(AnnotationFS annotationFS, Feature feature, Object o, + RutaStream stream) { + TypeSystem typeSystem = stream.getCas().getTypeSystem(); if (feature != null && o != null) { Type range = feature.getRange(); String rangeName = range.getName(); - if (rangeName.equals(CAS.TYPE_NAME_STRING) && o instanceof String) { + if (typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range) + && o instanceof String) { annotationFS.setStringValue(feature, (String) o); } else if (rangeName.equals(CAS.TYPE_NAME_INTEGER) && o instanceof Number) { annotationFS.setIntValue(feature, ((Number) o).intValue()); @@ -940,12 +953,13 @@ public class MultiTreeWordList implement annotationFS.setLongValue(feature, ((Number) o).longValue()); } else if (rangeName.equals(CAS.TYPE_NAME_BOOLEAN) && o instanceof Boolean) { annotationFS.setBooleanValue(feature, (Boolean) o); - } else if (rangeName.equals(CAS.TYPE_NAME_STRING) & o instanceof Type) { + } else if (typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range) + & o instanceof Type) { annotationFS.setStringValue(feature, ((Type) o).getName()); } } else { - throw new IllegalArgumentException("Not able to assign feature value: " + o + " -> " - + feature); + throw new IllegalArgumentException( + "Not able to assign feature value: " + o + " -> " + feature); } } @@ -953,8 +967,10 @@ public class MultiTreeWordList implement * Returns a map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. * - * @param query - The query string. - * @param distance - The specified edit distance. + * @param query + * - The query string. + * @param distance + * - The specified edit distance. * @return A map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. */ @@ -966,10 +982,14 @@ public class MultiTreeWordList implement * Returns a map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. * - * @param query - The query string. - * @param distance - The specified edit distance. - * @param ignoreCase - Indicates whether we search case sensitive or not. - * @param ignoreToken - Indicates the characters to ignore + * @param query + * - The query string. + * @param distance + * - The specified edit distance. + * @param ignoreCase + * - Indicates whether we search case sensitive or not. + * @param ignoreToken + * - Indicates the characters to ignore * @return A map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. */ @@ -982,11 +1002,16 @@ public class MultiTreeWordList implement * Returns a map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. * - * @param query - The query string. - * @param distance - The specified edit distance. - * @param ignoreCase - Indicates whether we search case sensitive or not. - * @param ignoreToken - the characters to ignore - * @param fragment - Indicates whether we search for fragments of the query string or not. + * @param query + * - The query string. + * @param distance + * - The specified edit distance. + * @param ignoreCase + * - Indicates whether we search case sensitive or not. + * @param ignoreToken + * - the characters to ignore + * @param fragment + * - Indicates whether we search for fragments of the query string or not. * @return A map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. */ @@ -1013,7 +1038,8 @@ public class MultiTreeWordList implement result = editDistanceClever(root, query.toLowerCase(), "", distance, 0, true, fragment, edcm, false, false); } else { - result = editDistanceClever(root, query, "", distance, 0, false, fragment, edcm, false, false); + result = editDistanceClever(root, query, "", distance, 0, false, fragment, edcm, false, + false); } // Restoring of the old insert costs. @@ -1028,16 +1054,26 @@ public class MultiTreeWordList implement * Returns a map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. * - * @param node - The MultiTextNode which is under consideration at the moment. - * @param query - The query string. - * @param result - The result which matched until now. - * @param distance - The remaining edit distance. - * @param index - The index of the query string at the moment. - * @param ignoreCase - Indicates whether we search case sensitive or not. - * @param fragment - Indicates whether we search for fragments of the query string or not. - * @param edm - The edit distance cost map we are using. - * @param lastActionInsert - Indicates whether the last action was an insert action. - * @param lastActionDelete - Indicates whether the last action was a delete action. + * @param node + * - The MultiTextNode which is under consideration at the moment. + * @param query + * - The query string. + * @param result + * - The result which matched until now. + * @param distance + * - The remaining edit distance. + * @param index + * - The index of the query string at the moment. + * @param ignoreCase + * - Indicates whether we search case sensitive or not. + * @param fragment + * - Indicates whether we search for fragments of the query string or not. + * @param edm + * - The edit distance cost map we are using. + * @param lastActionInsert + * - Indicates whether the last action was an insert action. + * @param lastActionDelete + * - Indicates whether the last action was a delete action. * @return A map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. */ @@ -1094,8 +1130,8 @@ public class MultiTreeWordList implement if (index < query.length()) { if (ignoreCase) { - if (Character.toLowerCase(tempNode.getValue()) == Character.toLowerCase(query - .charAt(index))) { + if (Character.toLowerCase(tempNode.getValue()) == Character + .toLowerCase(query.charAt(index))) { resultMap.putAll(editDistanceClever(tempNode, query, result + tempNode.getValue(), distance, index + 1, ignoreCase, fragment, edm, false, false)); } @@ -1110,9 +1146,9 @@ public class MultiTreeWordList implement if (distance - edm.getReplaceCosts(node.getValue(), tempNode.getValue()) >= 0) { // Substitute. - resultMap.putAll(editDistanceClever(tempNode, query, result + tempNode.getValue(), distance - - edm.getReplaceCosts(node.getValue(), tempNode.getValue()), index + 1, ignoreCase, - fragment, edm, false, false)); + resultMap.putAll(editDistanceClever(tempNode, query, result + tempNode.getValue(), + distance - edm.getReplaceCosts(node.getValue(), tempNode.getValue()), index + 1, + ignoreCase, fragment, edm, false, false)); } if (!lastActionDelete) { @@ -1131,19 +1167,27 @@ public class MultiTreeWordList implement /** * Checks if a string is contained by the MultiTreeWordList. * - * @param node - The MultiTextNode which is under consideration at the moment. - * @param query - The query string. - * @param result - The result which matched until now. - * @param distance - The remaining edit distance. - * @param index - The index of the query string at the moment. - * @param ignoreCase - Indicates whether we search case sensitive or not. - * @param fragment - Indicates whether we search for fragments of the query string or not. - * @param edm - The edit distance cost map we are using. + * @param node + * - The MultiTextNode which is under consideration at the moment. + * @param query + * - The query string. + * @param result + * - The result which matched until now. + * @param distance + * - The remaining edit distance. + * @param index + * - The index of the query string at the moment. + * @param ignoreCase + * - Indicates whether we search case sensitive or not. + * @param fragment + * - Indicates whether we search for fragments of the query string or not. + * @param edm + * - The edit distance cost map we are using. * @return A map with all strings with a specified edit distance to the string query as keys and * the files they belong to as values. */ - private boolean editDistanceBool(MultiTextNode node, String query, String result, - double distance, int index, boolean ignoreCase, boolean fragment, EditDistanceCostMap edm) { + private boolean editDistanceBool(MultiTextNode node, String query, String result, double distance, + int index, boolean ignoreCase, boolean fragment, EditDistanceCostMap edm) { boolean deletion = false; boolean insertion = false; @@ -1188,8 +1232,8 @@ public class MultiTreeWordList implement if (index < query.length()) { if (ignoreCase) { - if (Character.toLowerCase(tempNode.getValue()) == Character.toLowerCase(query - .charAt(index))) { + if (Character.toLowerCase(tempNode.getValue()) == Character + .toLowerCase(query.charAt(index))) { noop = editDistanceBool(tempNode, query, result + tempNode.getValue(), distance, index + 1, ignoreCase, fragment, edm); } @@ -1208,9 +1252,9 @@ public class MultiTreeWordList implement if (distance - edm.getReplaceCosts(node.getValue(), tempNode.getValue()) >= 0) { // Substitute. - substitution = editDistanceBool(tempNode, query, result + tempNode.getValue(), distance - - edm.getReplaceCosts(node.getValue(), tempNode.getValue()), index + 1, ignoreCase, - fragment, edm); + substitution = editDistanceBool(tempNode, query, result + tempNode.getValue(), + distance - edm.getReplaceCosts(node.getValue(), tempNode.getValue()), index + 1, + ignoreCase, fragment, edm); if (substitution) { return true; @@ -1233,7 +1277,6 @@ public class MultiTreeWordList implement return false; } - @Override public int hashCode() { final int prime = 31; Modified: uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RegExpRule.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RegExpRule.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RegExpRule.java (original) +++ uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RegExpRule.java Fri Dec 14 15:06:46 2018 @@ -93,8 +93,8 @@ public class RegExpRule extends Abstract createAnnotations(i, delta, begin, end, types, fa, matchResult, ruleMatch, stream); } else if (i == 0) { CAS cas = stream.getCas(); - AnnotationFS afs = cas.createAnnotation(cas.getAnnotationType(), delta + begin, delta - + end); + AnnotationFS afs = cas.createAnnotation(cas.getAnnotationType(), delta + begin, + delta + end); ruleMatch.addMatched(0, afs); } } @@ -196,7 +196,7 @@ public class RegExpRule extends Abstract if (argExpr instanceof INumberExpression) { INumberExpression ne = (INumberExpression) argExpr; int cg = ne.getIntegerValue(context, stream); - if (range.getName().equals(CAS.TYPE_NAME_STRING)) { + if (typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range)) { String s = matchResult.group(cg); afs.setStringValue(feature, s); } else if (range.getName().equals(CAS.TYPE_NAME_BOOLEAN)) { @@ -224,7 +224,7 @@ public class RegExpRule extends Abstract } } else { if (argExpr instanceof ITypeExpression - && range.getName().equals(CAS.TYPE_NAME_STRING)) { + && typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range)) { ITypeExpression typeExpr = (ITypeExpression) argExpr; List<AnnotationFS> annotationsInWindow = stream.getAnnotationsInWindow(afs, typeExpr.getType(context, stream)); @@ -233,7 +233,7 @@ public class RegExpRule extends Abstract afs.setStringValue(feature, annotation.getCoveredText()); } } else if (argExpr instanceof AbstractStringExpression - && range.getName().equals(CAS.TYPE_NAME_STRING)) { + && typeSystem.subsumes(typeSystem.getType(CAS.TYPE_NAME_STRING), range)) { afs.setStringValue(feature, ((AbstractStringExpression) argExpr).getStringValue(context, stream)); // numbers are reserved for capturing groups @@ -302,7 +302,8 @@ public class RegExpRule extends Abstract this.regexpExpr = regexp; } - public void setFeatureAssignments(Map<ITypeExpression, Map<IStringExpression, IRutaExpression>> fa) { + public void setFeatureAssignments( + Map<ITypeExpression, Map<IStringExpression, IRutaExpression>> fa) { this.featureAssignments = fa; } Modified: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatch1Test.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatch1Test.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatch1Test.java (original) +++ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/FeatureMatch1Test.java Fri Dec 14 15:06:46 2018 @@ -19,25 +19,33 @@ package org.apache.uima.ruta; +import java.io.IOException; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.CAS; +import org.apache.uima.resource.ResourceConfigurationException; +import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.ruta.engine.RutaEngine; import org.apache.uima.ruta.engine.RutaTestUtils; import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature; +import org.apache.uima.util.InvalidXMLException; import org.junit.Test; public class FeatureMatch1Test { @Test - public void test() { + public void test() throws AnalysisEngineProcessException, InvalidXMLException, + ResourceInitializationException, ResourceConfigurationException, URISyntaxException, + IOException { String name = this.getClass().getSimpleName(); String namespace = this.getClass().getPackage().getName().replaceAll("\\.", "/"); - CAS cas = null; + Map<String, String> complexTypes = new HashMap<String, String>(); Map<String, List<TestFeature>> features = new TreeMap<String, List<TestFeature>>(); String typeNameA = "org.apache.uima.ruta.FeatureMatchTest.A"; @@ -69,13 +77,8 @@ public class FeatureMatch1Test { String fnds = "ds"; listD.add(new TestFeature(fnds, "", "uima.cas.String")); - try { - cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, - namespace + "/" + name + ".txt", 50, false, false, complexTypes, features, null); - } catch (Exception e) { - e.printStackTrace(); - assert (false); - } + CAS cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, + namespace + "/" + name + ".txt", 50, false, false, complexTypes, features, null); RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "Marshall"); RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "Marshall"); @@ -93,8 +96,10 @@ public class FeatureMatch1Test { RutaTestUtils.assertAnnotationsEquals(cas, 14, 3, "Kluegl", "Kottmann", "Schor"); RutaTestUtils.assertAnnotationsEquals(cas, 15, 3, "Peter", "Joern", "Marshall"); RutaTestUtils.assertAnnotationsEquals(cas, 16, 1, "Peter Kluegl, Joern Kottmann, Marshall"); - RutaTestUtils.assertAnnotationsEquals(cas, 17, 1, "Peter Kluegl, Joern Kottmann, Marshall Schor"); - RutaTestUtils.assertAnnotationsEquals(cas, 18, 1, "Peter Kluegl, Joern Kottmann, Marshall Schor"); + RutaTestUtils.assertAnnotationsEquals(cas, 17, 1, + "Peter Kluegl, Joern Kottmann, Marshall Schor"); + RutaTestUtils.assertAnnotationsEquals(cas, 18, 1, + "Peter Kluegl, Joern Kottmann, Marshall Schor"); cas.release(); } Modified: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/action/ImplicitActionTest.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/action/ImplicitActionTest.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/action/ImplicitActionTest.java (original) +++ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/action/ImplicitActionTest.java Fri Dec 14 15:06:46 2018 @@ -42,10 +42,12 @@ import org.junit.Test; public class ImplicitActionTest { @Test - public void test() { + public void test() throws AnalysisEngineProcessException, InvalidXMLException, + ResourceInitializationException, ResourceConfigurationException, URISyntaxException, + IOException { String name = this.getClass().getSimpleName(); String namespace = this.getClass().getPackage().getName().replaceAll("\\.", "/"); - CAS cas = null; + Map<String, String> complexTypes = new HashMap<String, String>(); Map<String, List<TestFeature>> features = new TreeMap<String, List<TestFeature>>(); String typeNameA = "org.apache.uima.ruta.FeatureMatchTest.A"; @@ -77,25 +79,23 @@ public class ImplicitActionTest { String fnds = "ds"; listD.add(new TestFeature(fnds, "", "uima.cas.String")); - try { - cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, - FeatureMatch1Test.class.getName().replaceAll("\\.", "/") +".txt", 50, false, false, complexTypes, features, null); - } catch (Exception e) { - e.printStackTrace(); - assert (false); - } - - RutaTestUtils.assertAnnotationsEquals(cas, 1, 3, "Peter Kluegl", "Joern Kottmann", "Marshall Schor"); + CAS cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, + FeatureMatch1Test.class.getName().replaceAll("\\.", "/") + ".txt", 50, false, false, + complexTypes, features, null); + + RutaTestUtils.assertAnnotationsEquals(cas, 1, 3, "Peter Kluegl", "Joern Kottmann", + "Marshall Schor"); RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "Peter", "Joern", "Marshall"); RutaTestUtils.assertAnnotationsEquals(cas, 3, 3, "Peter", "Joern", "Marshall"); RutaTestUtils.assertAnnotationsEquals(cas, 4, 3, "Peter", "Joern", "Marshall"); - + cas.release(); } - - + @Test - public void testChangeOffsets() throws ResourceInitializationException, InvalidXMLException, IOException, AnalysisEngineProcessException, ResourceConfigurationException, URISyntaxException { + public void testChangeOffsets() + throws ResourceInitializationException, InvalidXMLException, IOException, + AnalysisEngineProcessException, ResourceConfigurationException, URISyntaxException { String text = "text 2 3 x 4 1"; String script = ""; script += "NUM{->T1};"; @@ -106,7 +106,5 @@ public class ImplicitActionTest { RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "4 1"); cas.release(); } - - - + } Modified: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/FeatureTest.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/FeatureTest.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/FeatureTest.java (original) +++ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/FeatureTest.java Fri Dec 14 15:06:46 2018 @@ -19,28 +19,36 @@ package org.apache.uima.ruta.condition; +import java.io.IOException; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.CAS; +import org.apache.uima.resource.ResourceConfigurationException; +import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.ruta.engine.RutaEngine; import org.apache.uima.ruta.engine.RutaTestUtils; import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature; +import org.apache.uima.util.InvalidXMLException; import org.junit.Test; public class FeatureTest { @Test - public void test() { + public void test() throws AnalysisEngineProcessException, InvalidXMLException, + ResourceInitializationException, ResourceConfigurationException, URISyntaxException, + IOException { String name = this.getClass().getSimpleName(); String namespace = this.getClass().getPackage().getName().replaceAll("\\.", "/"); - + Map<String, String> complexTypes = new TreeMap<String, String>(); String typeName = "org.apache.uima.FS"; complexTypes.put(typeName, "uima.tcas.Annotation"); - + Map<String, List<TestFeature>> features = new TreeMap<String, List<TestFeature>>(); List<TestFeature> list = new ArrayList<RutaTestUtils.TestFeature>(); features.put(typeName, list); @@ -52,15 +60,10 @@ public class FeatureTest { list.add(new TestFeature(fn3, "", "uima.cas.Integer")); String fn4 = "boolean"; list.add(new TestFeature(fn4, "", "uima.cas.Boolean")); - - CAS cas = null; - try { - cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, namespace + "/" + name - + ".txt", 50, false, false, complexTypes, features, namespace + "/"); - } catch (Exception e) { - e.printStackTrace(); - assert (false); - } + + CAS cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, + namespace + "/" + name + ".txt", 50, false, false, complexTypes, features, + namespace + "/"); RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "Testing FEATURE condition."); RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "Testing FEATURE condition."); Modified: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition1Test.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition1Test.java?rev=1848947&r1=1848946&r2=1848947&view=diff ============================================================================== --- uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition1Test.java (original) +++ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition1Test.java Fri Dec 14 15:06:46 2018 @@ -19,26 +19,34 @@ package org.apache.uima.ruta.condition; +import java.io.IOException; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.CAS; +import org.apache.uima.resource.ResourceConfigurationException; +import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.ruta.FeatureMatch1Test; import org.apache.uima.ruta.engine.RutaEngine; import org.apache.uima.ruta.engine.RutaTestUtils; import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature; +import org.apache.uima.util.InvalidXMLException; import org.junit.Test; public class ImplicitCondition1Test { @Test - public void test() { + public void test() throws AnalysisEngineProcessException, InvalidXMLException, + ResourceInitializationException, ResourceConfigurationException, URISyntaxException, + IOException { String name = this.getClass().getSimpleName(); String namespace = this.getClass().getPackage().getName().replaceAll("\\.", "/"); - CAS cas = null; + Map<String, String> complexTypes = new HashMap<String, String>(); Map<String, List<TestFeature>> features = new TreeMap<String, List<TestFeature>>(); String typeNameA = "org.apache.uima.ruta.FeatureMatchTest.A"; @@ -70,19 +78,18 @@ public class ImplicitCondition1Test { String fnds = "ds"; listD.add(new TestFeature(fnds, "", "uima.cas.String")); - try { - cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, - FeatureMatch1Test.class.getName().replaceAll("\\.", "/") +".txt", 50, false, false, complexTypes, features, null); - } catch (Exception e) { - e.printStackTrace(); - assert (false); - } + CAS cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, + FeatureMatch1Test.class.getName().replaceAll("\\.", "/") + ".txt", 50, false, false, + complexTypes, features, null); RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "Marshall Schor"); - RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "Peter Kluegl", "Joern Kottmann", "Marshall Schor"); - RutaTestUtils.assertAnnotationsEquals(cas, 3, 3, "Peter Kluegl", "Joern Kottmann", "Marshall Schor"); + RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "Peter Kluegl", "Joern Kottmann", + "Marshall Schor"); + RutaTestUtils.assertAnnotationsEquals(cas, 3, 3, "Peter Kluegl", "Joern Kottmann", + "Marshall Schor"); RutaTestUtils.assertAnnotationsEquals(cas, 4, 1, "Joern Kottmann"); - RutaTestUtils.assertAnnotationsEquals(cas, 5, 3, "Peter Kluegl", "Joern Kottmann", "Marshall Schor"); + RutaTestUtils.assertAnnotationsEquals(cas, 5, 3, "Peter Kluegl", "Joern Kottmann", + "Marshall Schor"); cas.release(); } Added: uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/string/StringSubtypeAllowedValuesTest.java URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/string/StringSubtypeAllowedValuesTest.java?rev=1848947&view=auto ============================================================================== --- uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/string/StringSubtypeAllowedValuesTest.java (added) +++ uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/expression/string/StringSubtypeAllowedValuesTest.java Fri Dec 14 15:06:46 2018 @@ -0,0 +1,111 @@ +/* + * 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.expression.string; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.uima.analysis_engine.AnalysisEngineProcessException; +import org.apache.uima.cas.CAS; +import org.apache.uima.cas.CASException; +import org.apache.uima.fit.factory.TypeSystemDescriptionFactory; +import org.apache.uima.fit.util.JCasUtil; +import org.apache.uima.jcas.JCas; +import org.apache.uima.resource.ResourceConfigurationException; +import org.apache.uima.resource.ResourceInitializationException; +import org.apache.uima.resource.metadata.AllowedValue; +import org.apache.uima.resource.metadata.FsIndexDescription; +import org.apache.uima.resource.metadata.TypeDescription; +import org.apache.uima.resource.metadata.TypeSystemDescription; +import org.apache.uima.resource.metadata.impl.AllowedValue_impl; +import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; +import org.apache.uima.ruta.engine.Ruta; +import org.apache.uima.ruta.type.FalseNegative; +import org.apache.uima.ruta.type.FalsePositive; +import org.apache.uima.ruta.type.TruePositive; +import org.apache.uima.util.CasCreationUtils; +import org.apache.uima.util.InvalidXMLException; +import org.junit.Assert; +import org.junit.Test; + +public class StringSubtypeAllowedValuesTest { + + @Test + public void testValidValue() throws ResourceInitializationException, + AnalysisEngineProcessException, InvalidXMLException, ResourceConfigurationException, + IOException, URISyntaxException, CASException { + CAS cas = createCAS(); + + String script = "Document{-> CREATE(Test, \"allowed\" = \"A\")};"; + script += "Document{-> CREATE(Test, \"allowed\" = \"B\")};"; + // using eval types just as helper types + script += "Test.allowed == \"A\"{-> TruePositive};"; + script += "Test.allowed == \"B\"{-> TruePositive};"; + script += "t:Test{t.allowed == \"A\" -> TruePositive};"; + script += "t:Test{t.allowed == \"B\" -> TruePositive};"; + script += "Test.allowed == \"\"{-> FalseNegative};"; + script += "Test.allowed == \"C\"{-> FalsePositive};"; + + Ruta.apply(cas, script); + + JCas jcas = cas.getJCas(); + Assert.assertEquals(4, JCasUtil.select(jcas, TruePositive.class).size()); + Assert.assertEquals(0, JCasUtil.select(jcas, FalseNegative.class).size()); + Assert.assertEquals(0, JCasUtil.select(jcas, FalsePositive.class).size()); + + } + + @Test(expected = AnalysisEngineProcessException.class) + public void testInvalidValue() throws ResourceInitializationException, + AnalysisEngineProcessException, InvalidXMLException, ResourceConfigurationException, + IOException, URISyntaxException, CASException { + + CAS cas = createCAS(); + + String script = "Document{-> CREATE(Test, \"allowed\" = \"D\")};"; + + Ruta.apply(cas, script); + } + + private CAS createCAS() throws ResourceInitializationException { + TypeSystemDescription typeSystemDescription = new TypeSystemDescription_impl(); + String subStringTypeName = "ruta.SubString"; + TypeDescription stringTypeDescription = typeSystemDescription.addType(subStringTypeName, + "for testing", CAS.TYPE_NAME_STRING); + stringTypeDescription.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("A", "A"), + new AllowedValue_impl("B", "B"), new AllowedValue_impl("C", "C") }); + TypeDescription testTypeDescription = typeSystemDescription.addType("ruta.Test", "for testing", + CAS.TYPE_NAME_ANNOTATION); + testTypeDescription.addFeature("allowed", "for testing", subStringTypeName); + + TypeSystemDescription typeSystemDescription2 = TypeSystemDescriptionFactory + .createTypeSystemDescription(); + + Collection<TypeSystemDescription> typeSystems = new ArrayList<>(); + typeSystems.add(typeSystemDescription); + typeSystems.add(typeSystemDescription2); + TypeSystemDescription mergedTypeSystem = CasCreationUtils.mergeTypeSystems(typeSystems); + CAS cas = CasCreationUtils.createCas(mergedTypeSystem, null, new FsIndexDescription[0]); + cas.setDocumentText("Some text."); + return cas; + } + +}