in RegularExpressionAnnotator/src/main/java/org/apache/uima/annotator/regex/impl/RegExAnnotator.java [646:888]
private void processConceptInstructions(Matcher matcher, AnnotationFS annot, String matchingText,
CAS aCAS, Concept concept, int ruleIndex, ArrayList<FeatureStructure> annotsToAdd)
throws RegexAnnotatorProcessException {
// create local annotation map for reference features
HashMap<String, FeatureStructure> annotMap = new HashMap<String, FeatureStructure>();
// has the rule some reference features to set
boolean hasReferenceFeatures = false;
// get annotations that should be created
Annotation[] annotations = concept.getAnnotations();
for (int a = 0; a < annotations.length; a++) {
// get annotation type
Type annotType = annotations[a].getAnnotationType();
// get local start and end position of the match in the matchingText
int localStart = annotations[a].getBegin().getMatchPosition(matcher);
int localEnd = annotations[a].getEnd().getMatchPosition(matcher);
// check if match group positions are valid. If they are invalid,
// the match group is available but has no matching content
if (localStart == -1 || localEnd == -1) {
// match group positions are invalid, so we cannot create the
// annotation
continue;
}
// set default validation value to true, by default all annotations
// are created
boolean validation = true;
// check if an validator for the current annotation is available
if (annotations[a].hasValidator()) {
// get the substring of the match from the matching text
String matchText = matchingText.substring(localStart, localEnd);
// validate annotation
try {
validation = annotations[a].validate(matchText, concept.getRules()[ruleIndex].getId());
} catch (Exception ex) {
throw new RegexAnnotatorProcessException("regex_annotator_error_validating_annotation",
new Object[] { annotations[a].getId(), matchText, Integer.valueOf(localStart),
Integer.valueOf(localEnd) }, ex);
}
}
// only create annotation if the validation was true
if (validation == true) {
// create annotation start and begin positions dependent of the rule
// matching
if (concept.getRules()[ruleIndex].isFeaturePathMatch()) {
// we match a feature path, use a source annotation boundaries
// for the annotation that is created
localStart = annot.getBegin();
localEnd = annot.getEnd();
} else {
// we match no feature path, make positions absolute to the
// document text -> add match type annotation offset.
localStart = annot.getBegin() + localStart;
localEnd = annot.getBegin() + localEnd;
}
// create annotation for this match
FeatureStructure fs = aCAS.createAnnotation(annotType, localStart, localEnd);
// get features for the current annotation
Feature[] features = annotations[a].getFeatures();
for (int f = 0; f < features.length; f++) {
// get feature type
int type = features[f].getType();
// check if we have a reference feature or not
if (type == Feature.FLOAT_FEATURE || type == Feature.INTEGER_FEATURE
|| type == Feature.STRING_FEATURE) {
// we have no reference feature
// replace match groups in the feature value
String featureValue = replaceMatchGroupValues(features[f].getValue(), matcher, concept
.getRules()[ruleIndex]);
// do featureValue normalization
try {
// try to set the normalized feature value, if no
// normalization was specified for the feature, the
// original feature value is set
if (featureValue != null) {
featureValue = features[f].normalize(featureValue, concept.getRules()[ruleIndex]
.getId());
}
} catch (Exception ex) {
throw new RegexAnnotatorProcessException(
"regex_annotator_error_normalizing_feature_value", new Object[] { featureValue,
features[f].getName() }, ex);
}
// set feature value at the annotation in dependence of the
// feature type
if (type == Feature.FLOAT_FEATURE) {
try {
if (featureValue != null) {
Number number = this.floatNumberFormat.parse(featureValue);
fs.setFloatValue(features[f].getFeature(), number.floatValue());
}
} catch (ParseException ex) {
this.logger.logrb(Level.WARNING, "RegExAnnotator", "processConceptInstructions",
MESSAGE_DIGEST, "regex_annotator_warning_number_format_conversion",
new Object[] { featureValue, features[f].getFeature().getName(), "float" });
}
} else if (type == Feature.INTEGER_FEATURE) {
try {
if (featureValue != null) {
Number number = this.integerNumberFormat.parse(featureValue);
fs.setIntValue(features[f].getFeature(), number.intValue());
}
} catch (ParseException ex) {
this.logger.logrb(Level.WARNING, "RegExAnnotator", "processConceptInstructions",
MESSAGE_DIGEST, "regex_annotator_warning_number_format_conversion",
new Object[] { featureValue, features[f].getFeature().getName(), "integer" });
}
} else if (type == Feature.STRING_FEATURE) {
fs.setStringValue(features[f].getFeature(), featureValue);
}
} else if (type == Feature.REFERENCE_FEATURE) {
// we have a reference feature, we have to set this later
// since we cannot be sure that the referenced annotation is
// already created
hasReferenceFeatures = true;
} else if (type == Feature.RULEID_FEATURE) {
// get rule id and set it as feature value
String ruleId = concept.getRules()[ruleIndex].getId();
fs.setStringValue(features[f].getFeature(), ruleId);
} else if (type == Feature.CONFIDENCE_FEATURE) {
// get rule confidence value and set it as feature value
float confidence = concept.getRules()[ruleIndex].getConfidence();
fs.setFloatValue(features[f].getFeature(), confidence);
}
}
// add annotation to the local HashMap that is used to set
// annotation
// reference features, the annotation must only be added in case
// that
// an annotation id was specified.
if (annotations[a].getId() != null) {
annotMap.put(annotations[a].getId(), fs);
}
// add annotation to the list of feature structures that must be
// added
// to the index
annotsToAdd.add(fs);
}
} // end of annotation processing
// if we detected previously some reference feature types we have to set
// them now
if (hasReferenceFeatures) {
// iterate again over the annotation array
for (int a = 0; a < annotations.length; a++) {
// get all features for the current annotation
Feature[] features = annotations[a].getFeatures();
for (int f = 0; f < features.length; f++) {
// get feature type
int type = features[f].getType();
// check if we have a reference feature, we are only
// interested in reference features now
if (type == Feature.REFERENCE_FEATURE) {
// search for the annotation the feature belongs to, the
// annotation was created earlier
// to search for the correct annotation we use the current
// annotation ID
FeatureStructure fs = annotMap.get(annotations[a].getId());
// search for the referenced annotation ID
// the annotation ID we search for is specified in the feature
// value
FeatureStructure refFs = annotMap.get(features[f].getValue());
// set reference feature value
fs.setFeatureValue(features[f].getFeature(), refFs);
}
}
}
} // end - set reference feature value
// process update features of the current match type annotation
// get all match type update features of the current rule
Feature[] updateFeatures = concept.getRules()[ruleIndex].getMatchTypeUpdateFeatures();
for (int f = 0; f < updateFeatures.length; f++) {
int type = updateFeatures[f].getType();
// check if we have a reference feature or not
if (type == Feature.FLOAT_FEATURE || type == Feature.INTEGER_FEATURE
|| type == Feature.STRING_FEATURE) {
// we have no reference feature
// replace match groups in the feature value
String featureValue = replaceMatchGroupValues(updateFeatures[f].getValue(), matcher,
concept.getRules()[ruleIndex]);
// do featureValue normalization
try {
// try to set the normalized feature value, if no
// normalization was specified for the feature, the
// original feature value is set
featureValue = updateFeatures[f].normalize(featureValue, concept.getRules()[ruleIndex]
.getId());
} catch (Exception ex) {
throw new RegexAnnotatorProcessException(
"regex_annotator_error_normalizing_feature_value", new Object[] { featureValue,
updateFeatures[f].getName() }, ex);
}
// set feature value at the annotation in dependence of the feature
// type
if (type == Feature.FLOAT_FEATURE) {
annot.setFloatValue(updateFeatures[f].getFeature(), Float.parseFloat(featureValue));
} else if (type == Feature.INTEGER_FEATURE) {
annot.setIntValue(updateFeatures[f].getFeature(), Integer.parseInt(featureValue));
} else if (type == Feature.STRING_FEATURE) {
annot.setStringValue(updateFeatures[f].getFeature(), featureValue);
}
} else if (type == Feature.REFERENCE_FEATURE) {
// search for the referenced annotation ID
// the annotation ID we search for is specified in the feature value
FeatureStructure refFs = annotMap.get(updateFeatures[f].getValue());
// set reference feature value
annot.setFeatureValue(updateFeatures[f].getFeature(), refFs);
} else if (type == Feature.RULEID_FEATURE) {
// get rule id and set it as feature value
String ruleId = concept.getRules()[ruleIndex].getId();
annot.setStringValue(updateFeatures[f].getFeature(), ruleId);
} else if (type == Feature.CONFIDENCE_FEATURE) {
// get rule confidence value and set it as feature value
float confidence = concept.getRules()[ruleIndex].getConfidence();
annot.setFloatValue(updateFeatures[f].getFeature(), confidence);
}
}
}