in uimafit-core/src/main/java/org/apache/uima/fit/util/FSUtil.java [329:545]
public static <T> T getFeature(FeatureStructure aFS, Feature aFeature, Class<T> aClazz) {
if (aFeature.getRange().isPrimitive()) {
switch (aFeature.getRange().getName()) {
case CAS.TYPE_NAME_BOOLEAN:
return aClazz.cast(aFS.getBooleanValue(aFeature));
case CAS.TYPE_NAME_BYTE:
return aClazz.cast(aFS.getByteValue(aFeature));
case CAS.TYPE_NAME_DOUBLE:
return aClazz.cast(aFS.getDoubleValue(aFeature));
case CAS.TYPE_NAME_FLOAT:
return aClazz.cast(aFS.getFloatValue(aFeature));
case CAS.TYPE_NAME_INTEGER:
return aClazz.cast(aFS.getIntValue(aFeature));
case CAS.TYPE_NAME_LONG:
return aClazz.cast(aFS.getLongValue(aFeature));
case CAS.TYPE_NAME_SHORT:
return aClazz.cast(aFS.getShortValue(aFeature));
case CAS.TYPE_NAME_STRING:
return aClazz.cast(aFS.getStringValue(aFeature));
default:
throw new IllegalArgumentException(
"Unable to coerce value of feature [" + aFeature.getName() + "] with type ["
+ aFeature.getRange().getName() + "] into [" + aClazz.getName() + "]");
}
}
FeatureStructure value = aFS.getFeatureValue(aFeature);
// "null" case
if (value == null) {
return null;
}
// Here we store the values before we coerce them into the final target type
// "target" is actually an array
Object target;
int length;
// Handle case where feature is an array
if (value instanceof CommonArrayFS) {
// Shortcut if the user explicitly requests an array type
if (!Object.class.equals(aClazz) && aClazz.isAssignableFrom(value.getClass())) {
return (T) value;
}
CommonArrayFS source = (CommonArrayFS) value;
length = source.size();
if (value instanceof BooleanArrayFS) {
target = new boolean[length];
((BooleanArrayFS) source).copyToArray(0, (boolean[]) target, 0, length);
} else if (value instanceof ByteArrayFS) {
target = new byte[length];
((ByteArrayFS) source).copyToArray(0, (byte[]) target, 0, length);
} else if (value instanceof DoubleArrayFS) {
target = new double[length];
((DoubleArrayFS) source).copyToArray(0, (double[]) target, 0, length);
} else if (value instanceof FloatArrayFS) {
target = new float[length];
((FloatArrayFS) source).copyToArray(0, (float[]) target, 0, length);
} else if (value instanceof IntArrayFS) {
target = new int[length];
((IntArrayFS) source).copyToArray(0, (int[]) target, 0, length);
} else if (value instanceof LongArrayFS) {
target = new long[length];
((LongArrayFS) source).copyToArray(0, (long[]) target, 0, length);
} else if (value instanceof ShortArrayFS) {
target = new short[length];
((ShortArrayFS) source).copyToArray(0, (short[]) target, 0, length);
} else if (value instanceof StringArrayFS) {
target = new String[length];
((StringArrayFS) source).copyToArray(0, (String[]) target, 0, length);
} else {
if (aClazz.isArray()) {
target = Array.newInstance(aClazz.getComponentType(), length);
} else {
target = new FeatureStructure[length];
}
((ArrayFS) source).copyToArray(0, (FeatureStructure[]) target, 0, length);
}
}
// Handle case where feature is a list
else if (isListType(aFS.getCAS().getTypeSystem(), aFeature.getRange())) {
// Shortcut if the user explicitly requests a list type
if (!Object.class.equals(aClazz) && aClazz.isAssignableFrom(value.getClass())) {
return (T) value;
}
// Get length of list
length = 0;
{
FeatureStructure cur = value;
// We assume to by facing a non-empty element if it has a "head" feature
while (cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD) != null) {
length++;
cur = cur.getFeatureValue(cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL));
}
}
switch (aFeature.getRange().getName()) {
case CAS.TYPE_NAME_FLOAT_LIST: {
float[] floatTarget = new float[length];
int i = 0;
FeatureStructure cur = value;
// We assume to by facing a non-empty element if it has a "head" feature
while (cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD) != null) {
floatTarget[i] = cur
.getFloatValue(cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD));
cur = cur.getFeatureValue(
cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL));
}
target = floatTarget;
break;
}
case CAS.TYPE_NAME_INTEGER_LIST: {
int[] intTarget = new int[length];
int i = 0;
FeatureStructure cur = value;
// We assume to by facing a non-empty element if it has a "head" feature
while (cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD) != null) {
intTarget[i] = cur
.getIntValue(cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD));
cur = cur.getFeatureValue(
cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL));
}
target = intTarget;
break;
}
case CAS.TYPE_NAME_STRING_LIST: {
String[] stringTarget = new String[length];
int i = 0;
FeatureStructure cur = value;
// We assume to by facing a non-empty element if it has a "head" feature
while (cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD) != null) {
stringTarget[i] = cur
.getStringValue(cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD));
cur = cur.getFeatureValue(
cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL));
}
target = stringTarget;
break;
}
default: {
if (aClazz.isArray()) {
target = Array.newInstance(aClazz.getComponentType(), length);
} else {
target = new FeatureStructure[length];
}
int i = 0;
FeatureStructure cur = value;
// We assume to by facing a non-empty element if it has a "head" feature
while (cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD) != null) {
Array.set(target, i, cur.getFeatureValue(
cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD)));
i++;
cur = cur.getFeatureValue(
cur.getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL));
}
break;
}
}
} else if (aClazz.isAssignableFrom(value.getClass())) {
return (T) value;
} else if (aFS.getCAS().getTypeSystem().subsumes(CasUtil.getType(aFS.getCAS(), aClazz),
aFeature.getRange())) {
return (T) value;
} else {
throw new IllegalArgumentException(
"Unable to coerce value of feature [" + aFeature.getName() + "] with type ["
+ aFeature.getRange().getName() + "] into [" + aClazz.getName() + "]");
}
// Handle case where return value is an array
if (aClazz.isArray()) {
return aClazz.cast(target);
}
// Handle case where return value is Object
Class targetClass = aClazz;
if (Object.class.equals(aClazz)) {
targetClass = List.class;
}
// Handle case where return value is a collection
if (Collection.class.isAssignableFrom(targetClass)) {
Collection targetCollection;
if (targetClass.isInterface()) {
// If the target is an interface, try using a default implementation;
if (List.class.isAssignableFrom(targetClass)) {
targetCollection = new ArrayList(length);
} else if (Set.class.isAssignableFrom(targetClass)) {
targetCollection = new HashSet(length);
} else {
throw new IllegalArgumentException("Unable to coerce value of feature ["
+ aFeature.getName() + "] with type [" + aFeature.getRange().getName()
+ "] into [" + targetClass.getName() + "]");
}
} else {
// Try to instantiate using 0-args constructor
try {
targetCollection = (Collection) targetClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException("Unable to coerce value of feature ["
+ aFeature.getName() + "] with type [" + aFeature.getRange().getName()
+ "] into [" + targetClass.getName() + "]", e);
}
}
for (int i = 0; i < length; i++) {
targetCollection.add(Array.get(target, i));
}
return (T) targetClass.cast(targetCollection);
}
throw new IllegalArgumentException(
"Unable to coerce value of feature [" + aFeature.getName() + "] with type ["
+ aFeature.getRange().getName() + "] into [" + targetClass.getName() + "]");
}