in uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureValuePathImpl.java [826:977]
public void typeSystemInit(int fsType, LowLevelTypeSystem ts) throws CASRuntimeException {
if (typeNameInSnippet != null) { // if the feature path snippet
// defines
// its own
// type,
// we use that one instead of the one that's passed in
fsType = ts.ll_getCodeForTypeName(typeNameInSnippet);
}
if (fsType == LowLevelTypeSystem.UNKNOWN_TYPE_CODE) {
throw new CASRuntimeException(CASRuntimeException.INVALID_FEATURE_PATH, typeNameInSnippet);
}
// the range type denotes what type of FSes (or
// built-in type) is contained in this feature
int rangeTypeCode = LowLevelTypeSystem.UNKNOWN_TYPE_CODE;
if (!(isBuiltInFeature() || isBracketsOnly)) {
// find the feature in fsType that corresponds to this path snippet
int[] features = ts.ll_getAppropriateFeatures(fsType);
boolean found = false;
int i = 0;
for (; i < features.length && (!found); i++) {
Feature feature = ts.ll_getFeatureForCode(features[i]);
found = feature.getShortName().equals(featureName);
}
if (found) {
// store the feature code that corresponds to this path snippet
featureCode = features[i - 1];
rangeTypeCode = ts.ll_getRangeType(featureCode);
} else {
Type type = ts.ll_getTypeForCode(fsType);
throw new CASRuntimeException(CASRuntimeException.INAPPROP_FEAT, featureName,
type.getName());
}
}
if (isBracketsOnly) {
rangeTypeCode = fsType;
}
typeCode = fsType;
// TODO: check mismatch between isArray and the actual rangeTypeCode
// find out whether the type is a "simple" type that may only be used in
// the last snippet of a path
Type type = ts.ll_getTypeForCode(rangeTypeCode);
featureRangeType = rangeTypeCode;
if (isBuiltInFeature()) {
isSimpleRangeType = true;
} else {
isSimpleRangeType = Arrays.binarySearch(SIMPLE_VAL_TYPES, type.getName()) >= 0;
}
if (isArrayOrList) {
int arrayType = ts.ll_getCodeForTypeName(CAS.TYPE_NAME_ARRAY_BASE);
isArrayType = ((TypeSystemImpl) ts).subsumes(arrayType, rangeTypeCode);
if (!isArrayType) {
// check whether the feature points to a list
for (int i = 0; i < LIST_TYPE_NAMES.length && !isListType; i++) {
int candidateType = ts.ll_getCodeForTypeName(LIST_TYPE_NAMES[i]);
isListType = ((TypeSystemImpl) ts).subsumes(candidateType, rangeTypeCode);
if (isListType) {
// determine the type class of the list
listType = i;
}
}
// determine the right head and tail feature, depending on the
// list type
switch (listType) {
case TYPE_CLASS_FSLIST:
headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FS_LIST_HEAD);
tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FS_LIST_TAIL);
break;
case TYPE_CLASS_STRINGLIST:
headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_STRING_LIST_HEAD);
tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_STRING_LIST_TAIL);
break;
case TYPE_CLASS_INTEGERLIST:
headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_INTEGER_LIST_HEAD);
tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_INTEGER_LIST_TAIL);
break;
case TYPE_CLASS_FLOATLIST:
headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FLOAT_LIST_HEAD);
tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FLOAT_LIST_TAIL);
break;
default:
break;
}
emptyListTypes = new Type[EMPTY_LIST_TYPE_NAMES.length];
for (int i = 0; i < EMPTY_LIST_TYPE_NAMES.length; i++) {
emptyListTypes[i] = ts
.ll_getTypeForCode(ts.ll_getCodeForTypeName(EMPTY_LIST_TYPE_NAMES[i]));
}
}
}
if (childPath != null) {
// for simple range types, only [] and fsId() are allowed as child
// path
if (isSimpleRangeType && !(childPath.isBracketsOnly() || childPath.isFsIdFeature)) {
throw new CASRuntimeException(CASRuntimeException.INVALID_FEATURE_PATH, featureName);
}
// continue with the child path
childPath.typeSystemInit(rangeTypeCode, ts);
} else if (isCoveredTextFeature) {
// make sure that the type is a subtype of annotation
int annotationType = ts.ll_getCodeForTypeName(CAS.TYPE_NAME_ANNOTATION);
if (!((TypeSystemImpl) ts).subsumes(annotationType, fsType)) {
throw new CASRuntimeException(CASRuntimeException.INVALID_FEATURE_PATH, featureName);
}
valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES, CAS.TYPE_NAME_STRING)];
} else if (isFsIdFeature) {
valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES,
CAS.TYPE_NAME_INTEGER)];
} else if (isUniqueIdFeature) {
valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES,
CAS.TYPE_NAME_INTEGER)];
} else if (isTypeNameFeature) {
valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES, CAS.TYPE_NAME_STRING)];
} else {
if (!isSimpleRangeType) {
CASRuntimeException exception = new CASRuntimeException(
CASRuntimeException.NO_PRIMITIVE_TAIL);
throw exception;
}
if (isArrayOrList && (arrayIndex != USE_ALL_ENTRIES)) {
// in the case of, say, authornames[0], the feature is of type
// string array, but it will evaluate to a string.
valueTypeName = CONTAINER_TO_ELEMENTYPE_MAP.get(type.getName());
} else if (isListType) { // here, we can assume that
// arrayIndex =
// USE_ALL_ENTRIES
// we don't return lists, but arrays, so we need to map the type
// accordingly
valueTypeName = LIST_TO_ARRAYTYPE_MAP.get(type.getName());
} else {
valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES, type.getName())];
}
}
}