blob: b71cf29bd94954e8324cf2790b0f8dfb1edf9036 [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.visitor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.fit.util.FSCollectionFactory;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.cas.FSArray;
import org.apache.uima.ruta.RutaElement;
import org.apache.uima.ruta.RutaStatement;
import org.apache.uima.ruta.RutaStream;
import org.apache.uima.ruta.ScriptApply;
import org.apache.uima.ruta.block.BlockApply;
import org.apache.uima.ruta.rule.AbstractRule;
import org.apache.uima.ruta.rule.AbstractRuleMatch;
import org.apache.uima.ruta.rule.ComposedRuleElement;
import org.apache.uima.ruta.rule.ComposedRuleElementMatch;
import org.apache.uima.ruta.rule.EvaluatedCondition;
import org.apache.uima.ruta.rule.RegExpRule;
import org.apache.uima.ruta.rule.RegExpRuleMatch;
import org.apache.uima.ruta.rule.RuleApply;
import org.apache.uima.ruta.rule.RuleElement;
import org.apache.uima.ruta.rule.RuleElementMatch;
import org.apache.uima.ruta.rule.RuleMatch;
import org.apache.uima.ruta.rule.RutaRuleElement;
import org.apache.uima.ruta.type.DebugBlockApply;
import org.apache.uima.ruta.type.DebugEvaluatedCondition;
import org.apache.uima.ruta.type.DebugFailedRuleMatch;
import org.apache.uima.ruta.type.DebugInlinedBlock;
import org.apache.uima.ruta.type.DebugMatchedRuleMatch;
import org.apache.uima.ruta.type.DebugRuleApply;
import org.apache.uima.ruta.type.DebugRuleElementMatch;
import org.apache.uima.ruta.type.DebugRuleElementMatches;
import org.apache.uima.ruta.type.DebugRuleMatch;
import org.apache.uima.ruta.type.DebugScriptApply;
import org.apache.uima.ruta.verbalize.RutaVerbalizer;
public class DebugInfoFactory {
private RutaVerbalizer verbalizer;
public DebugInfoFactory(RutaVerbalizer verbalizer) {
super();
this.verbalizer = verbalizer;
}
public DebugBlockApply createDummyBlockApply(RuleMatch ruleMatch, RutaStream stream,
boolean addToIndex, boolean withMatches, Map<RutaElement, Long> timeInfo) {
JCas cas = stream.getJCas();
DebugBlockApply dba = new DebugBlockApply(cas);
AnnotationFS matchedAnnotation = ruleMatch
.getMatchedAnnotationsOfElement(ruleMatch.getRule().getRoot()).get(0);
dba.setElement(matchedAnnotation.getCoveredText());
dba.setBegin(matchedAnnotation.getBegin());
dba.setEnd(matchedAnnotation.getEnd());
return dba;
}
public DebugBlockApply createDebugBlockApply(BlockApply blockApply, RutaStream stream,
boolean addToIndex, boolean withMatches, Map<RutaElement, Long> timeInfo) {
JCas cas = stream.getJCas();
DebugBlockApply dba = new DebugBlockApply(cas);
List<DebugScriptApply> innerApply = new ArrayList<DebugScriptApply>();
// TODO refactor and remove counting hotfix
int applied = blockApply.getRuleApply().getApplied();
RutaElement element = blockApply.getElement();
String verbalize = "";
verbalize = verbalizer.verbalize(element);
if (applied > 1) {
List<ScriptApply> innerApplies = blockApply.getInnerApplies();
List<List<ScriptApply>> loops = new ArrayList<List<ScriptApply>>();
for (int i = 0; i < applied; i++) {
loops.add(new ArrayList<ScriptApply>());
}
int counter = 0;
int size = innerApplies.size();
int parts = size / applied;
for (ScriptApply each : innerApplies) {
int listIndex = Math.max(0, counter / parts);
List<ScriptApply> list = loops.get(listIndex);
list.add(each);
counter++;
}
counter = 0;
for (List<ScriptApply> list : loops) {
AbstractRuleMatch<? extends AbstractRule> ruleMatch = blockApply.getRuleApply().getList()
.get(counter);
DebugBlockApply dummyBlockApply = createDummyBlockApply((RuleMatch) ruleMatch, stream,
addToIndex, withMatches, timeInfo);
List<DebugRuleMatch> ruleMatches = new ArrayList<DebugRuleMatch>();
ruleMatches.add(createDebugRuleMatch(ruleMatch, stream, addToIndex, withMatches, timeInfo));
dummyBlockApply.setApplied(1);
dummyBlockApply.setTried(1);
dummyBlockApply.setRules(FSCollectionFactory.createFSArray(cas, ruleMatches));
List<DebugScriptApply> innerInnerApply = new ArrayList<DebugScriptApply>();
for (ScriptApply each : list) {
DebugScriptApply eachInnerInner = createDebugScriptApply(each, stream, addToIndex,
withMatches, timeInfo);
innerInnerApply.add(eachInnerInner);
}
dummyBlockApply.setInnerApply(FSCollectionFactory.createFSArray(cas, innerInnerApply));
innerApply.add(dummyBlockApply);
counter++;
}
dba.setInnerApply(FSCollectionFactory.createFSArray(cas, innerApply));
dba.setElement(verbalize);
DebugRuleApply ruleApply = createDebugRuleApply(blockApply.getRuleApply(), stream, addToIndex,
withMatches, timeInfo);
dba.setApplied(ruleApply.getApplied());
dba.setTried(ruleApply.getTried());
dba.setRules(ruleApply.getRules());
dba.setBegin(ruleApply.getBegin());
dba.setEnd(ruleApply.getEnd());
if (timeInfo != null) {
long time = timeInfo.get(element);
dba.setTime(time);
}
if (addToIndex)
dba.addToIndexes();
return dba;
} else {
for (ScriptApply each : blockApply.getInnerApplies()) {
innerApply.add(createDebugScriptApply(each, stream, addToIndex, withMatches, timeInfo));
}
dba.setInnerApply(FSCollectionFactory.createFSArray(cas, innerApply));
dba.setElement(verbalize);
DebugRuleApply ruleApply = createDebugRuleApply(blockApply.getRuleApply(), stream, addToIndex,
withMatches, timeInfo);
dba.setApplied(ruleApply.getApplied());
dba.setTried(ruleApply.getTried());
dba.setRules(ruleApply.getRules());
dba.setBegin(ruleApply.getBegin());
dba.setEnd(ruleApply.getEnd());
if (timeInfo != null) {
Long time = timeInfo.get(element);
if (time != null) {
dba.setTime(time);
}
}
if (addToIndex)
dba.addToIndexes();
return dba;
}
}
public DebugRuleApply createDebugRuleApply(RuleApply ruleApply, RutaStream stream,
boolean addToIndex, boolean withMatches, Map<RutaElement, Long> timeInfo) {
JCas cas = stream.getJCas();
DebugRuleApply dra = new DebugRuleApply(cas);
List<DebugRuleMatch> ruleMatches = new ArrayList<DebugRuleMatch>();
int begin = Integer.MAX_VALUE;
int end = 0;
if (withMatches) {
for (AbstractRuleMatch<? extends AbstractRule> match : ruleApply.getList()) {
DebugRuleMatch debugRuleMatch = createDebugRuleMatch(match, stream, addToIndex, withMatches,
timeInfo);
begin = Math.min(begin, debugRuleMatch.getBegin());
end = Math.max(end, debugRuleMatch.getEnd());
ruleMatches.add(debugRuleMatch);
}
}
if (begin >= end) {
begin = end;
}
dra.setRules(FSCollectionFactory.createFSArray(cas, ruleMatches));
RutaElement element = ruleApply.getElement();
String namespace = "";
if (element instanceof RutaStatement) {
RutaStatement rs = (RutaStatement) element;
namespace = rs.getParent().getScript().getRootBlock().getNamespace();
}
dra.setElement(verbalizer.verbalize(element));
dra.setApplied(ruleApply.getApplied());
dra.setTried(ruleApply.getTried());
dra.setId(((AbstractRule) element).getId());
dra.setScript(namespace);
dra.setBegin(begin);
dra.setEnd(end);
if (timeInfo != null) {
Long time = timeInfo.get(element);
if (time != null) {
dra.setTime(time);
}
}
if (addToIndex)
dra.addToIndexes();
return dra;
}
public DebugRuleMatch createDebugRuleMatch(AbstractRuleMatch<? extends AbstractRule> match,
RutaStream stream, boolean addToIndex, boolean withMatches,
Map<RutaElement, Long> timeInfo) {
JCas cas = stream.getJCas();
DebugRuleMatch drm = null;
if (match.matchedCompletely()) {
drm = new DebugMatchedRuleMatch(cas);
} else {
drm = new DebugFailedRuleMatch(cas);
}
drm.setMatched(match.matchedCompletely());
if (match instanceof RuleMatch) {
ComposedRuleElementMatch rootMatch = ((RuleMatch) match).getRootMatch();
setInnerMatches(stream, addToIndex, withMatches, timeInfo, drm, rootMatch);
// if (match.matched()) {
List<DebugScriptApply> delegates = new ArrayList<DebugScriptApply>();
for (ScriptApply rem : ((RuleMatch) match).getDelegateApply().values()) {
delegates.add(createDebugScriptApply(rem, stream, addToIndex, withMatches, timeInfo));
}
drm.setDelegates(FSCollectionFactory.createFSArray(cas, delegates));
// }
} else if (match instanceof RegExpRuleMatch) {
RegExpRuleMatch rerm = (RegExpRuleMatch) match;
Map<Integer, List<AnnotationFS>> map = rerm.getMap();
Set<Entry<Integer, List<AnnotationFS>>> entrySet = map.entrySet();
List<DebugRuleElementMatches> ruleElementMatches = new ArrayList<DebugRuleElementMatches>();
for (Entry<Integer, List<AnnotationFS>> entry : entrySet) {
DebugRuleElementMatches drems = new DebugRuleElementMatches(cas);
RegExpRule rule = rerm.getRule();
Integer key = entry.getKey();
List<AnnotationFS> value = entry.getValue();
drems.setElement(verbalizer.verbalize(rule));
List<DebugRuleElementMatch> remList = new ArrayList<DebugRuleElementMatch>();
if (value != null) {
for (AnnotationFS each : value) {
DebugRuleElementMatch drem = new DebugRuleElementMatch(cas);
DebugEvaluatedCondition base = new DebugEvaluatedCondition(cas);
base.setValue(true);
String baseString = "Group " + key;
base.setElement(baseString);
drem.setBaseCondition(base);
if (each.getBegin() <= each.getEnd()) {
drem.setBegin(each.getBegin());
drem.setEnd(each.getEnd());
}
if (addToIndex) {
drem.addToIndexes();
}
remList.add(drem);
}
}
drems.setMatches(FSCollectionFactory.createFSArray(cas, remList));
if (addToIndex) {
drems.addToIndexes();
}
ruleElementMatches.add(drems);
}
drm.setElements(FSCollectionFactory.createFSArray(cas, ruleElementMatches));
}
if (timeInfo != null) {
long time = timeInfo.get(match.getRule());
drm.setTime(time);
}
List<AnnotationFS> matchedAnnotationsOfRoot = match.getMatchedAnnotationsOfRoot();
if (!matchedAnnotationsOfRoot.isEmpty()) {
AnnotationFS matchedAnnotation = matchedAnnotationsOfRoot.get(0);
if (matchedAnnotation != null) {
drm.setBegin(matchedAnnotation.getBegin());
drm.setEnd(matchedAnnotation.getEnd());
if (addToIndex || withMatches)
drm.addToIndexes();
}
}
return drm;
}
private void setInnerMatches(RutaStream stream, boolean addToIndex, boolean withMatches,
Map<RutaElement, Long> timeInfo, DebugRuleMatch drm, ComposedRuleElementMatch rootMatch) {
Set<Entry<RuleElement, List<RuleElementMatch>>> entrySet = rootMatch.getInnerMatches()
.entrySet();
List<DebugRuleElementMatches> ruleElementMatches = new ArrayList<DebugRuleElementMatches>();
for (Entry<RuleElement, List<RuleElementMatch>> entry : entrySet) {
RuleElement re = entry.getKey();
List<RuleElementMatch> rems = entry.getValue();
ruleElementMatches.add(
createDebugRuleElementMatches(re, rems, stream, addToIndex, withMatches, timeInfo));
}
drm.setElements(FSCollectionFactory.createFSArray(stream.getJCas(), ruleElementMatches));
}
private void setInnerMatches(RutaStream stream, boolean addToIndex, boolean withMatches,
Map<RutaElement, Long> timeInfo, DebugRuleElementMatch drm,
ComposedRuleElementMatch rootMatch) {
Set<Entry<RuleElement, List<RuleElementMatch>>> entrySet = rootMatch.getInnerMatches()
.entrySet();
List<DebugRuleElementMatches> ruleElementMatches = new ArrayList<DebugRuleElementMatches>();
for (Entry<RuleElement, List<RuleElementMatch>> entry : entrySet) {
RuleElement re = entry.getKey();
List<RuleElementMatch> rems = entry.getValue();
ruleElementMatches.add(
createDebugRuleElementMatches(re, rems, stream, addToIndex, withMatches, timeInfo));
}
drm.setElements(FSCollectionFactory.createFSArray(stream.getJCas(), ruleElementMatches));
}
public DebugRuleElementMatches createDebugRuleElementMatches(RuleElement re,
List<RuleElementMatch> rems, RutaStream stream, boolean addToIndex, boolean withMatches,
Map<RutaElement, Long> timeInfo) {
JCas cas = stream.getJCas();
DebugRuleElementMatches drems = new DebugRuleElementMatches(cas);
drems.setElement(verbalizer.verbalize(re));
List<DebugRuleElementMatch> remList = new ArrayList<DebugRuleElementMatch>();
if (rems != null) {
for (RuleElementMatch each : rems) {
DebugRuleElementMatch rem = null;
if (each instanceof ComposedRuleElementMatch) {
rem = createDebugComposedRuleElementMatch((ComposedRuleElementMatch) each, stream,
addToIndex, withMatches, timeInfo);
} else {
rem = createDebugRuleElementMatch(each, stream, addToIndex);
}
FSArray<DebugInlinedBlock> inlinedConditionBlocks = createInlinedBlocks(
each.getInlinedConditionRules(), stream, true, addToIndex, withMatches, timeInfo);
rem.setInlinedConditionBlocks(inlinedConditionBlocks);
if (rem != null) {
remList.add(rem);
}
}
}
if (rems != null && !rems.isEmpty()) {
drems.setRuleAnchor(rems.get(0).isRuleAnchor());
}
drems.setMatches(FSCollectionFactory.createFSArray(cas, remList));
FSArray<DebugInlinedBlock> inlinedActionBlocks = createInlinedActionBlocks(rems, stream,
addToIndex, withMatches, timeInfo);
drems.setInlinedActionBlocks(inlinedActionBlocks);
if (addToIndex)
drems.addToIndexes();
return drems;
}
private FSArray<DebugInlinedBlock> createInlinedBlocks(List<List<ScriptApply>> blocks,
RutaStream stream, boolean asCondition, boolean addToIndex, boolean withMatches,
Map<RutaElement, Long> timeInfo) {
JCas jcas = stream.getJCas();
if (blocks == null || blocks.isEmpty()) {
return null;
}
List<DebugInlinedBlock> blockList = new ArrayList<>();
for (List<ScriptApply> block : blocks) {
List<DebugScriptApply> list = new ArrayList<>();
boolean oneRuleApplied = false;
for (ScriptApply ruleApply : block) {
if (ruleApply instanceof RuleApply) {
if (((RuleApply) ruleApply).getApplied() > 0) {
oneRuleApplied = true;
}
}
DebugScriptApply debugScriptApply = createDebugScriptApply(ruleApply, stream, addToIndex,
withMatches, timeInfo);
list.add(debugScriptApply);
}
DebugInlinedBlock debugInlinedBlock = new DebugInlinedBlock(jcas);
debugInlinedBlock.setInlinedRules(FSCollectionFactory.createFSArray(jcas, list));
debugInlinedBlock.setAsCondition(asCondition);
if (asCondition) {
debugInlinedBlock.setElement(verbalizer.verbalizeInlinedConditionRuleBlock(block));
debugInlinedBlock.setMatched(oneRuleApplied);
} else {
debugInlinedBlock.setElement(verbalizer.verbalizeInlinedActionRuleBlock(block));
}
blockList.add(debugInlinedBlock);
}
return FSCollectionFactory.createFSArray(jcas, blockList);
}
private FSArray<DebugInlinedBlock> createInlinedActionBlocks(List<RuleElementMatch> rems,
RutaStream stream, boolean addToIndex, boolean withMatches,
Map<RutaElement, Long> timeInfo) {
if (rems == null || rems.isEmpty()) {
return null;
}
return createInlinedBlocks(rems.get(0).getInlinedActionRules(), stream, false, addToIndex,
withMatches, timeInfo);
}
public DebugRuleElementMatch createDebugComposedRuleElementMatch(ComposedRuleElementMatch rem,
RutaStream stream, boolean addToIndex, boolean withMatches,
Map<RutaElement, Long> timeInfo) {
JCas cas = stream.getJCas();
DebugRuleElementMatch drem = new DebugRuleElementMatch(cas);
DebugEvaluatedCondition base = new DebugEvaluatedCondition(cas);
base.setValue(rem.isBaseConditionMatched());
setInnerMatches(stream, addToIndex, withMatches, timeInfo, drem, rem);
String baseString = verbalizer.verbalize(rem.getRuleElement());
base.setElement(baseString);
drem.setBaseCondition(base);
drem.setConditions(createEvaluatedConditions(rem, stream, addToIndex));
List<AnnotationFS> annotations = rem.getTextsMatched();
if (!annotations.isEmpty()) {
int begin = annotations.get(0).getBegin();
int end = annotations.get(annotations.size() - 1).getEnd();
if (begin <= end) {
drem.setBegin(begin);
drem.setEnd(end);
}
}
if (addToIndex)
drem.addToIndexes();
return drem;
}
public DebugRuleElementMatch createDebugRuleElementMatch(RuleElementMatch rem, RutaStream stream,
boolean addToIndex) {
JCas cas = stream.getJCas();
DebugRuleElementMatch drem = new DebugRuleElementMatch(cas);
DebugEvaluatedCondition base = new DebugEvaluatedCondition(cas);
base.setValue(rem.isBaseConditionMatched());
RuleElement ruleElement = rem.getRuleElement();
String baseString = "";
if (ruleElement instanceof RutaRuleElement) {
baseString = verbalizer.verbalizeMatcher((RutaRuleElement) ruleElement);
} else if (ruleElement instanceof ComposedRuleElement) {
baseString = verbalizer.verbalizeComposed((ComposedRuleElement) ruleElement);
}
base.setElement(baseString);
drem.setBaseCondition(base);
drem.setConditions(createEvaluatedConditions(rem, stream, addToIndex));
List<AnnotationFS> annotations = rem.getTextsMatched();
if (!annotations.isEmpty()) {
int begin = annotations.get(0).getBegin();
int end = annotations.get(annotations.size() - 1).getEnd();
if (begin <= end) {
drem.setBegin(begin);
drem.setEnd(end);
}
}
if (addToIndex) {
drem.addToIndexes();
}
return drem;
}
private FSArray<DebugEvaluatedCondition> createEvaluatedConditions(RuleElementMatch rem,
RutaStream stream, boolean addToIndex) {
JCas cas = stream.getJCas();
List<DebugEvaluatedCondition> ecs = new ArrayList<DebugEvaluatedCondition>();
if (rem.getConditions() != null) {
for (EvaluatedCondition each : rem.getConditions()) {
DebugEvaluatedCondition ec = new DebugEvaluatedCondition(cas);
ec.setValue(each.isValue());
ec.setElement(verbalizer.verbalize(each.getCondition()));
ec.setConditions(createEvaluatedConditions(each, stream, addToIndex));
ecs.add(ec);
}
}
FSArray<DebugEvaluatedCondition> result = FSCollectionFactory.createFSArray(cas, ecs);
return result;
}
private FSArray<DebugEvaluatedCondition> createEvaluatedConditions(EvaluatedCondition eval,
RutaStream stream, boolean addToIndex) {
JCas cas = stream.getJCas();
List<DebugEvaluatedCondition> ecs = new ArrayList<DebugEvaluatedCondition>();
for (EvaluatedCondition each : eval.getConditions()) {
DebugEvaluatedCondition ec = new DebugEvaluatedCondition(cas);
ec.setValue(each.isValue());
ec.setElement(verbalizer.verbalize(each.getCondition()));
ec.setConditions(createEvaluatedConditions(each, stream, addToIndex));
ecs.add(ec);
}
FSArray<DebugEvaluatedCondition> result = FSCollectionFactory.createFSArray(cas, ecs);
return result;
}
public DebugScriptApply createDebugScriptApply(ScriptApply apply, RutaStream stream,
boolean addToIndex, boolean withMatches, Map<RutaElement, Long> timeInfo) {
DebugScriptApply debug = null;
if (apply instanceof BlockApply) {
debug = createDebugBlockApply((BlockApply) apply, stream, addToIndex, withMatches, timeInfo);
} else if (apply instanceof RuleApply) {
debug = createDebugRuleApply((RuleApply) apply, stream, addToIndex, withMatches, timeInfo);
}
if (addToIndex)
debug.addToIndexes();
return debug;
}
}