in uimaj-core/src/main/java/org/apache/uima/cas/impl/FeaturePathImpl.java [541:644]
private TOP getTargetFs(TOP fs) {
if (null == fs) {
return FEATURE_PATH_FAILED;
}
if (this.featurePathElementNames.size() == 0) {
targetType = fs._getTypeImpl();
return fs;
}
// we have a feature path that must be evaluated
if (boundBaseType == null || !boundBaseType.subsumes(fs._getTypeImpl())) {
boundFeatures.clear(); // reset if supplied FS not the one the features were calculated for.
boundBaseType = fs._getTypeImpl();
}
// set current FS values
TOP currentFs = fs;
TypeImpl rangeType = null;
int rangeTypeClass = -1;
// resolve feature path value
for (int i = 0; i < this.featurePathElementNames.size(); i++) {
if (currentFs == null) {
return FEATURE_PATH_FAILED;
}
if (i < this.boundFeatures.size()) {
targetFeature = this.boundFeatures.get(i);
/*
* It is possible that the previously bound feature isn't valid for this FS. This can happen
* if a type hierarchy defines 2 different features for two different subtypes of type Tt
* with the same feature name.
*
* So we check if this bound feature is appropriate for the current FS
*/
if (!((TypeImpl) targetFeature.getDomain()).subsumes(currentFs._getTypeImpl())) {
setTargetFeature(currentFs, i);
}
} else {
setTargetFeature(currentFs, i);
}
// switch feature type class
// currentRangeTypeCode = llCas.ll_getTypeSystem().ll_getRangeType(targetFeatureCode);
targetType = rangeType = targetFeature.getRangeImpl();
rangeTypeClass = TypeSystemImpl.getTypeClass(rangeType);
switch (rangeTypeClass) {
case LowLevelCAS.TYPE_CLASS_STRING:
case LowLevelCAS.TYPE_CLASS_INT:
case LowLevelCAS.TYPE_CLASS_BOOLEAN:
case LowLevelCAS.TYPE_CLASS_BYTE:
case LowLevelCAS.TYPE_CLASS_DOUBLE:
case LowLevelCAS.TYPE_CLASS_FLOAT:
case LowLevelCAS.TYPE_CLASS_LONG:
case LowLevelCAS.TYPE_CLASS_SHORT:
case LowLevelCAS.TYPE_CLASS_INVALID:
return currentFs; // is the fs which has the feature which is the primitive value
case LowLevelCAS.TYPE_CLASS_BOOLEANARRAY:
case LowLevelCAS.TYPE_CLASS_BYTEARRAY:
case LowLevelCAS.TYPE_CLASS_DOUBLEARRAY:
case LowLevelCAS.TYPE_CLASS_FLOATARRAY:
case LowLevelCAS.TYPE_CLASS_FSARRAY:
case LowLevelCAS.TYPE_CLASS_INTARRAY:
case LowLevelCAS.TYPE_CLASS_LONGARRAY:
case LowLevelCAS.TYPE_CLASS_SHORTARRAY:
case LowLevelCAS.TYPE_CLASS_STRINGARRAY:
return currentFs.getFeatureValue(targetFeature);
case LowLevelCAS.TYPE_CLASS_FS:
currentFs = currentFs.getFeatureValue(targetFeature);
if (currentFs == null) {
if (i == (this.featurePathElementNames.size() - 1)) {
// at the last element, keep targetType == to the range type
} else {
//@formatter:off
/*
* not at the last element, so terminating the feature path prematurely.
* There are 2 cases:
* - the PathValid is POSSIBLE
* - the PathValid is ALWAYS
*/
//@formatter:on
PathValid pathValid = TypeSystemUtils.isPathValid(this.boundBaseType,
this.featurePathElementNames);
if (pathValid == PathValid.POSSIBLE) {
targetType = null; // following v2 design here
}
}
return null;
}
break;
default:
throw new CASRuntimeException(UIMARuntimeException.INTERNAL_ERROR);
} // end of switch
} // end of loop over all items in feature path
return currentFs;
}