blob: 7cfa5e0912204ae99c00fb50bf3a1b3e3c5e39cc [file] [log] [blame]
/*
* 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.rule;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.ruta.RutaEnvironment;
import org.apache.uima.ruta.RutaProcessRuntimeException;
import org.apache.uima.ruta.RutaStream;
import org.apache.uima.ruta.action.AbstractRutaAction;
import org.apache.uima.ruta.block.RutaBlock;
import org.apache.uima.ruta.condition.AbstractRutaCondition;
import org.apache.uima.ruta.rule.quantifier.NormalQuantifier;
import org.apache.uima.ruta.visitor.InferenceCrowd;
public class RutaOptionalRuleElement extends RutaRuleElement {
public RutaOptionalRuleElement(List<AbstractRutaCondition> conditions,
List<AbstractRutaAction> actions, RuleElementContainer container, RutaBlock parent) {
super(null, new NormalQuantifier(), conditions, actions, container, parent);
}
@Override
public Collection<? extends AnnotationFS> getAnchors(RutaStream stream) {
throw new RutaProcessRuntimeException(
"Using an optional rule lement as anchor is not allowed!");
}
@Override
public List<RuleMatch> startMatch(RuleMatch ruleMatch, RuleApply ruleApply,
ComposedRuleElementMatch containerMatch, RuleElement entryPoint, RutaStream stream,
InferenceCrowd crowd) {
throw new RutaProcessRuntimeException(
"Using an optional rule lement as anchor is not allowed!");
}
@Override
public void doMatch(boolean after, AnnotationFS annotation, RuleMatch ruleMatch,
ComposedRuleElementMatch containerMatch, boolean ruleAnchor, RutaStream stream,
InferenceCrowd crowd) {
RuleElementMatch result = new RuleElementMatch(this, containerMatch);
result.setRuleAnchor(ruleAnchor);
List<EvaluatedCondition> evaluatedConditions = new ArrayList<>(
conditions.size());
boolean base = true;
MatchContext context = new MatchContext(annotation, this, ruleMatch, after);
List<AnnotationFS> textsMatched = annotation != null ? asList(annotation) : emptyList();
// already set the matched text and inform others
result.setMatchInfo(base, textsMatched, stream);
RutaEnvironment environment = context.getParent().getEnvironment();
environment.addMatchToVariable(ruleMatch, this, context, stream);
if (base) {
for (AbstractRutaCondition condition : conditions) {
crowd.beginVisit(condition, null);
EvaluatedCondition eval = condition.eval(context, stream, crowd);
crowd.endVisit(condition, null);
evaluatedConditions.add(eval);
if (!eval.isValue()) {
break;
}
}
}
result.setConditionInfo(base, evaluatedConditions);
if (result.matched()) {
boolean inlinedRulesMatched = matchInlinedRules(ruleMatch, result, stream, crowd);
result.setInlinedRulesMatched(inlinedRulesMatched);
} else {
// update label for failed match after evaluating conditions
environment.removeVariableValue(getLabel(), context);
}
ruleMatch.setMatched(ruleMatch.matched() && result.matched());
}
@Override
protected boolean isNotConsumable(Collection<? extends AnnotationFS> nextAnnotations) {
return false;
}
@Override
public String toString() {
return "_";
}
@Override
public long estimateAnchors(RutaStream stream) {
return Integer.MAX_VALUE;
}
@Override
public Collection<? extends AnnotationFS> getNextAnnotations(boolean after,
AnnotationFS annotation, RutaStream stream) {
return Arrays.asList(stream.getBasicNextTo(!after, annotation));
}
}