blob: 40e39a64a769da4a237df512d7e8b44b61fee895 [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.
getCoveredAnnotations() contains code adapted from the UIMA Subiterator class.
*/
package org.apache.uima.fit.util;
import static java.util.Arrays.asList;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.uima.cas.ArrayFS;
import org.apache.uima.cas.BooleanArrayFS;
import org.apache.uima.cas.ByteArrayFS;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.DoubleArrayFS;
import org.apache.uima.cas.FSIndexRepository;
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.FloatArrayFS;
import org.apache.uima.cas.IntArrayFS;
import org.apache.uima.cas.LongArrayFS;
import org.apache.uima.cas.ShortArrayFS;
import org.apache.uima.cas.StringArrayFS;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.TypeSystem;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.cas.text.AnnotationIndex;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.cas.BooleanArray;
import org.apache.uima.jcas.cas.ByteArray;
import org.apache.uima.jcas.cas.DoubleArray;
import org.apache.uima.jcas.cas.FSArray;
import org.apache.uima.jcas.cas.FSList;
import org.apache.uima.jcas.cas.FloatArray;
import org.apache.uima.jcas.cas.FloatList;
import org.apache.uima.jcas.cas.IntegerArray;
import org.apache.uima.jcas.cas.IntegerList;
import org.apache.uima.jcas.cas.LongArray;
import org.apache.uima.jcas.cas.NonEmptyFSList;
import org.apache.uima.jcas.cas.NonEmptyFloatList;
import org.apache.uima.jcas.cas.NonEmptyIntegerList;
import org.apache.uima.jcas.cas.NonEmptyStringList;
import org.apache.uima.jcas.cas.ShortArray;
import org.apache.uima.jcas.cas.StringArray;
import org.apache.uima.jcas.cas.StringList;
import org.apache.uima.jcas.cas.TOP;
/**
* Bridge between Java {@link Collection Collections} from different representations of collections
* of UIMA {@link FeatureStructure FeatureStructures}.
*/
public abstract class FSCollectionFactory {
private FSCollectionFactory() {
// No instances.
}
/**
* Create a {@link Collection} of the given type of feature structures. This collection is backed
* by the CAS, either via an {@link CAS#getAnnotationIndex(Type)} or
* {@link FSIndexRepository#getAllIndexedFS(Type)}.
*
* @param cas
* the CAS to select from.
* @param type
* the type of feature structures to select. All sub-types are returned as well.
* @return a {@link Collection} of the given type of feature structures backed live by the CAS.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
* @deprecated Use {@code cas.select(type).asList()}
*/
@Deprecated
@SuppressWarnings({ "unchecked", "rawtypes" })
public static List<FeatureStructure> create(CAS cas, Type type) {
// If the type is an annotation type, we can use the annotation index, which directly
// provides us with its size. If not, we have to use getAllIndexedFS() which we have to
// scan from beginning to end in order to determine its size.
TypeSystem ts = cas.getTypeSystem();
if (ts.subsumes(cas.getAnnotationType(), type)) {
return (List) create(cas.getAnnotationIndex(type));
} else {
return (List) cas.select(type).asList();
}
}
/**
* Convert an {@link FSIterator} to a {@link Collection}.
*
* @param <T>
* the feature structure type
* @param aIterator
* the iterator to convert.
* @return the wrapped iterator.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends FeatureStructure> Collection<T> create(FSIterator<T> aIterator) {
return new FSIteratorAdapter<T>(aIterator);
}
/**
* Convert an {@link AnnotationIndex} to a {@link Collection}.
*
* @param <T>
* the feature structure type
* @param aIndex
* the index to convert.
* @return the wrapped index.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
* @deprecated Use {@code index.select().asList()}
*/
@Deprecated
public static <T extends AnnotationFS> List<T> create(AnnotationIndex<T> aIndex) {
return aIndex.select().asList();
}
/**
* Convert an {@link ArrayFS} to a {@link Collection}.
*
* @param aArray
* the array to convert.
* @return a new collection containing the same feature structures as the provided array.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends FeatureStructure> List<T> create(ArrayFS<T> aArray) {
return create(aArray, (Type) null);
}
/**
* Fetch all annotations of the given type or its sub-types from the given FS array.
*
* @param <T>
* the JCas type.
* @param aArray
* the FS array
* @param aType
* the JCas wrapper class.
* @return a new collection of all feature structures of the given type.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends TOP> List<T> create(ArrayFS aArray, Class<T> aType) {
return create(aArray, CasUtil.getType(aArray.getCAS(), aType));
}
/**
* Fetch all annotations of the given type or its sub-types from the given FS array.
*
* @param aArray
* the FS array
* @param aType
* the CAS type.
* @return a new collection of all feature structures of the given type.
*/
public static <T extends FeatureStructure> List<T> create(ArrayFS<T> aArray, Type aType) {
TypeSystem ts = aArray.getCAS().getTypeSystem();
List<FeatureStructure> data = new ArrayList<FeatureStructure>(aArray.size());
for (int i = 0; i < aArray.size(); i++) {
FeatureStructure value = aArray.get(i);
if (value != null && (aType == null || ts.subsumes(aType, value.getType()))) {
data.add(value);
}
}
return (List<T>) asList(data.toArray(new FeatureStructure[data.size()]));
}
public static <T extends FeatureStructure> ArrayFS<T> createArrayFS(CAS aCas,
Collection<T> aCollection) {
return fillArrayFS(aCas.createArrayFS(aCollection.size()), aCollection);
}
public static <T extends FeatureStructure> ArrayFS<T> createArrayFS(CAS aCas, T... aArray) {
return fillArrayFS(aCas.createArrayFS(aArray.length), asList(aArray));
}
public static <T extends FeatureStructure> FSArray<T> createFSArray(JCas aJCas,
Collection<T> aCollection) {
return fillArray(new FSArray<T>(aJCas, aCollection.size()), aCollection);
}
public static <T extends FeatureStructure> FSArray<T> createFSArray(JCas aJCas, T... aArray) {
return fillArray(new FSArray<T>(aJCas, aArray.length), asList(aArray));
}
public static BooleanArrayFS createBooleanArrayFS(CAS aCas, Collection<Boolean> aCollection) {
return fillArrayFS(aCas.createBooleanArrayFS(aCollection.size()), aCollection);
}
public static BooleanArrayFS createBooleanArrayFS(CAS aCas, boolean... aArray) {
return fillArrayFS(aCas.createBooleanArrayFS(aArray.length), aArray);
}
public static BooleanArray createBooleanArray(JCas aJCas, Collection<Boolean> aCollection) {
return fillArray(new BooleanArray(aJCas, aCollection.size()), aCollection);
}
public static BooleanArray createBooleanArray(JCas aJCas, boolean... aArray) {
return fillArray(new BooleanArray(aJCas, aArray.length), aArray);
}
public static ByteArrayFS createByteArrayFS(CAS aCas, Collection<Byte> aCollection) {
return fillArrayFS(aCas.createByteArrayFS(aCollection.size()), aCollection);
}
public static ByteArrayFS createByteArrayFS(CAS aCas, byte... aArray) {
return fillArrayFS(aCas.createByteArrayFS(aArray.length), aArray);
}
public static ByteArray createByteArray(JCas aJCas, Collection<Byte> aCollection) {
return fillArray(new ByteArray(aJCas, aCollection.size()), aCollection);
}
public static ByteArray createByteArray(JCas aJCas, byte... aArray) {
return fillArray(new ByteArray(aJCas, aArray.length), aArray);
}
public static DoubleArrayFS createDoubleArrayFS(CAS aCas, Collection<Double> aCollection) {
return fillArrayFS(aCas.createDoubleArrayFS(aCollection.size()), aCollection);
}
public static DoubleArrayFS createDoubleArrayFS(CAS aCas, double... aArray) {
return fillArrayFS(aCas.createDoubleArrayFS(aArray.length), aArray);
}
public static DoubleArray createDoubleArray(JCas aJCas, Collection<Double> aCollection) {
return fillArray(new DoubleArray(aJCas, aCollection.size()), aCollection);
}
public static DoubleArray createDoubleArray(JCas aJCas, double... aArray) {
return fillArray(new DoubleArray(aJCas, aArray.length), aArray);
}
public static FloatArrayFS createFloatArrayFS(CAS aCas, Collection<Float> aCollection) {
return fillArrayFS(aCas.createFloatArrayFS(aCollection.size()), aCollection);
}
public static FloatArrayFS createFloatArrayFS(CAS aCas, float... aArray) {
return fillArrayFS(aCas.createFloatArrayFS(aArray.length), aArray);
}
public static FloatArray createFloatArray(JCas aJCas, Collection<Float> aCollection) {
return fillArray(new FloatArray(aJCas, aCollection.size()), aCollection);
}
public static FloatArray createFloatArray(JCas aJCas, float... aArray) {
return fillArray(new FloatArray(aJCas, aArray.length), aArray);
}
public static IntArrayFS createIntArrayFS(CAS aCas, Collection<Integer> aCollection) {
return fillArrayFS(aCas.createIntArrayFS(aCollection.size()), aCollection);
}
public static IntArrayFS createIntArrayFS(CAS aCas, int... aArray) {
return fillArrayFS(aCas.createIntArrayFS(aArray.length), aArray);
}
public static IntegerArray createIntArray(JCas aJCas, Collection<Integer> aCollection) {
return fillArray(new IntegerArray(aJCas, aCollection.size()), aCollection);
}
public static IntegerArray createIntArray(JCas aJCas, int... aArray) {
return fillArray(new IntegerArray(aJCas, aArray.length), aArray);
}
public static LongArrayFS createLongArrayFS(CAS aCas, Collection<Long> aCollection) {
return fillArrayFS(aCas.createLongArrayFS(aCollection.size()), aCollection);
}
public static LongArrayFS createLongArrayFS(CAS aCas, long... aArray) {
return fillArrayFS(aCas.createLongArrayFS(aArray.length), aArray);
}
public static LongArray createLongArray(JCas aJCas, Collection<Long> aCollection) {
return fillArray(new LongArray(aJCas, aCollection.size()), aCollection);
}
public static LongArray createLongArray(JCas aJCas, long... aArray) {
return fillArray(new LongArray(aJCas, aArray.length), aArray);
}
public static ShortArrayFS createShortArrayFS(CAS aCas, Collection<Short> aCollection) {
return fillArrayFS(aCas.createShortArrayFS(aCollection.size()), aCollection);
}
public static ShortArrayFS createShortArrayFS(CAS aCas, short... aArray) {
return fillArrayFS(aCas.createShortArrayFS(aArray.length), aArray);
}
public static ShortArray createShortArray(JCas aJCas, Collection<Short> aCollection) {
return fillArray(new ShortArray(aJCas, aCollection.size()), aCollection);
}
public static ShortArray createShortArray(JCas aJCas, short... aArray) {
return fillArray(new ShortArray(aJCas, aArray.length), aArray);
}
public static StringArrayFS createStringArrayFS(CAS aCas, Collection<String> aCollection) {
return fillArrayFS(aCas.createStringArrayFS(aCollection.size()), aCollection);
}
public static StringArrayFS createStringArrayFS(CAS aCas, String... aArray) {
return fillArrayFS(aCas.createStringArrayFS(aArray.length), aArray);
}
public static StringArray createStringArray(JCas aJCas, Collection<String> aCollection) {
return fillArray(new StringArray(aJCas, aCollection.size()), aCollection);
}
public static StringArray createStringArray(JCas aJCas, String... aArray) {
return fillArray(new StringArray(aJCas, aArray.length), aArray);
}
public static <T extends FeatureStructure> FSArray<T> fillArray(FSArray<T> aArray,
Iterable<? extends T> aValues) {
return (FSArray<T>) fillArrayFS(aArray, aValues);
}
public static <T extends FeatureStructure> FSArray<T> fillArray(FSArray<T> aArray,
FeatureStructure... aValues) {
return (FSArray<T>) fillArrayFS(aArray, aValues);
}
public static <T extends FeatureStructure> ArrayFS<T> fillArrayFS(ArrayFS<T> aArrayFs,
Iterable<? extends T> aCollection) {
int i = 0;
for (T fs : aCollection) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static <T extends FeatureStructure> ArrayFS<T> fillArrayFS(ArrayFS<T> aArrayFs,
FeatureStructure... aArray) {
aArrayFs.copyFromArray(aArray, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static BooleanArray fillArray(BooleanArray aArray, Iterable<Boolean> aValues) {
return (BooleanArray) fillArrayFS(aArray, aValues);
}
public static BooleanArray fillArray(BooleanArray aArray, boolean... aValues) {
return (BooleanArray) fillArrayFS(aArray, aValues);
}
public static BooleanArrayFS fillArrayFS(BooleanArrayFS aArrayFs, Iterable<Boolean> aValues) {
int i = 0;
for (Boolean fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static BooleanArrayFS fillArrayFS(BooleanArrayFS aArrayFs, boolean... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static ByteArray fillArray(ByteArray aArray, Iterable<Byte> aValues) {
return (ByteArray) fillArrayFS(aArray, aValues);
}
public static ByteArray fillArray(ByteArray aArray, byte... aValues) {
return (ByteArray) fillArrayFS(aArray, aValues);
}
public static ByteArrayFS fillArrayFS(ByteArrayFS aArrayFs, Iterable<Byte> aValues) {
int i = 0;
for (Byte fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static ByteArrayFS fillArrayFS(ByteArrayFS aArrayFs, byte... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static DoubleArray fillArray(DoubleArray aArray, Iterable<Double> aValues) {
return (DoubleArray) fillArrayFS(aArray, aValues);
}
public static DoubleArray fillArray(DoubleArray aArray, double... aValues) {
return (DoubleArray) fillArrayFS(aArray, aValues);
}
public static DoubleArrayFS fillArrayFS(DoubleArrayFS aArrayFs, Iterable<Double> aValues) {
int i = 0;
for (Double fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static DoubleArrayFS fillArrayFS(DoubleArrayFS aArrayFs, double... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static FloatArray fillArray(FloatArray aArray, Iterable<Float> aValues) {
return (FloatArray) fillArrayFS(aArray, aValues);
}
public static FloatArray fillArray(FloatArray aArray, float... aValues) {
return (FloatArray) fillArrayFS(aArray, aValues);
}
public static FloatArrayFS fillArrayFS(FloatArrayFS aArrayFs, Iterable<Float> aValues) {
int i = 0;
for (Float fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static FloatArrayFS fillArrayFS(FloatArrayFS aArrayFs, float... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static IntegerArray fillArray(IntegerArray aArray, Iterable<Integer> aValues) {
return (IntegerArray) fillArrayFS(aArray, aValues);
}
public static IntegerArray fillArray(IntegerArray aArray, int... aValues) {
return (IntegerArray) fillArrayFS(aArray, aValues);
}
public static IntArrayFS fillArrayFS(IntArrayFS aArrayFs, Iterable<Integer> aValues) {
int i = 0;
for (Integer fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static IntArrayFS fillArrayFS(IntArrayFS aArrayFs, int... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static LongArray fillArray(LongArray aArray, Iterable<Long> aValues) {
return (LongArray) fillArrayFS(aArray, aValues);
}
public static LongArray fillArray(LongArray aArray, long... aValues) {
return (LongArray) fillArrayFS(aArray, aValues);
}
public static LongArrayFS fillArrayFS(LongArrayFS aArrayFs, Iterable<Long> aValues) {
int i = 0;
for (Long fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static LongArrayFS fillArrayFS(LongArrayFS aArrayFs, long... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static ShortArray fillArray(ShortArray aArray, Iterable<Short> aValues) {
return (ShortArray) fillArrayFS(aArray, aValues);
}
public static ShortArray fillArray(ShortArray aArray, short... aValues) {
return (ShortArray) fillArrayFS(aArray, aValues);
}
public static ShortArrayFS fillArrayFS(ShortArrayFS aArrayFs, Iterable<Short> aValues) {
int i = 0;
for (Short fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static ShortArrayFS fillArrayFS(ShortArrayFS aArrayFs, short... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
public static StringArray fillArray(StringArray aArray, Iterable<String> aValues) {
return (StringArray) fillArrayFS(aArray, aValues);
}
public static StringArray fillArray(StringArray aArray, String... aValues) {
return (StringArray) fillArrayFS(aArray, aValues);
}
public static StringArrayFS fillArrayFS(StringArrayFS aArrayFs, Iterable<String> aValues) {
int i = 0;
for (String fs : aValues) {
aArrayFs.set(i, fs);
i++;
}
return aArrayFs;
}
public static StringArrayFS fillArrayFS(StringArrayFS aArrayFs, String... aValues) {
aArrayFs.copyFromArray(aValues, 0, 0, aArrayFs.size());
return aArrayFs;
}
// Using TOP here because FSList is only available in the JCas.
public static <T extends TOP> Collection<T> create(FSList<T> aList) {
return create(aList, (Type) null);
}
/**
* Fetch all annotations of the given type or its sub-types from the given FS list.
*
* @param <T>
* the JCas type.
* @param aList
* the FS list
* @param aType
* the JCas wrapper class.
* @return a new collection of all feature structures of the given type.
*/
public static <T extends TOP> Collection<T> create(FSList<T> aList, Class<? extends T> aType) {
return create(aList, CasUtil.getType(aList.getCAS(), aType));
}
// Using TOP here because FSList is only available in the JCas.
public static <T extends TOP> List<T> create(FSList<T> aList, Type type) {
TypeSystem ts = aList.getCAS().getTypeSystem();
List<FeatureStructure> data = new ArrayList<FeatureStructure>();
FSList<T> i = aList;
while (i instanceof NonEmptyFSList) {
NonEmptyFSList<T> l = (NonEmptyFSList<T>) i;
TOP value = l.getHead();
if (value != null && (type == null || ts.subsumes(type, value.getType()))) {
data.add(l.getHead());
}
i = l.getTail();
}
return (List<T>) asList(data.toArray(new TOP[data.size()]));
}
public static List<String> create(StringList aList) {
List<String> data = new ArrayList<String>();
StringList i = aList;
while (i instanceof NonEmptyStringList) {
NonEmptyStringList l = (NonEmptyStringList) i;
data.add(l.getHead());
i = l.getTail();
}
return asList(data.toArray(new String[data.size()]));
}
public static List<Integer> create(IntegerList aList) {
List<Integer> data = new ArrayList<Integer>();
IntegerList i = aList;
while (i instanceof NonEmptyIntegerList) {
NonEmptyIntegerList l = (NonEmptyIntegerList) i;
data.add(l.getHead());
i = l.getTail();
}
return asList(data.toArray(new Integer[data.size()]));
}
public static List<Float> create(FloatList aList) {
List<Float> data = new ArrayList<Float>();
FloatList i = aList;
while (i instanceof NonEmptyFloatList) {
NonEmptyFloatList l = (NonEmptyFloatList) i;
data.add(l.getHead());
i = l.getTail();
}
return asList(data.toArray(new Float[data.size()]));
}
public static <T extends TOP> FSList<T> createFSList(JCas aJCas, Collection<T> aCollection) {
return createFSList(aJCas.getCas(), aCollection);
}
public static <T extends TOP> FSList<T> createFSList(CAS aCas, T... aValues) {
return createFSList(aCas, asList(aValues));
}
public static <T extends TOP> FSList<T> createFSList(CAS aCas, Collection<T> aValues) {
if (aValues == null) {
return null;
}
TypeSystem ts = aCas.getTypeSystem();
if (aValues.size() == 0) {
return aCas.emptyFSList();
}
Type nonEmptyType = ts.getType(CAS.TYPE_NAME_NON_EMPTY_FS_LIST);
Feature headFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD);
Feature tailFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL);
FeatureStructure head = aCas.createFS(nonEmptyType);
FeatureStructure list = head;
Iterator<? extends FeatureStructure> i = aValues.iterator();
while (i.hasNext()) {
head.setFeatureValue(headFeature, i.next());
if (i.hasNext()) {
FeatureStructure tail = aCas.createFS(nonEmptyType);
head.setFeatureValue(tailFeature, tail);
head = tail;
} else {
head.setFeatureValue(tailFeature, aCas.emptyFSList());
}
}
return (FSList<T>) list;
}
public static FloatList createFloatList(JCas aJCas, float... aValues) {
return createFloatList(aJCas.getCas(), aValues);
}
public static <T extends FeatureStructure> T createFloatList(CAS aCas, float... aValues) {
if (aValues == null) {
return null;
}
TypeSystem ts = aCas.getTypeSystem();
Type emptyType = ts.getType(CAS.TYPE_NAME_EMPTY_FLOAT_LIST);
if (aValues.length == 0) {
return aCas.createFS(emptyType);
}
Type nonEmptyType = ts.getType(CAS.TYPE_NAME_NON_EMPTY_FLOAT_LIST);
Feature headFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD);
Feature tailFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL);
FeatureStructure head = aCas.createFS(nonEmptyType);
FeatureStructure list = head;
int i = 0;
while (i < aValues.length) {
head.setFloatValue(headFeature, aValues[i]);
i++;
if (i < aValues.length) {
FeatureStructure tail = aCas.createFS(nonEmptyType);
head.setFeatureValue(tailFeature, tail);
head = tail;
} else {
head.setFeatureValue(tailFeature, aCas.createFS(emptyType));
}
}
return (T) list;
}
public static <T extends FeatureStructure> T createFloatList(CAS aCas, Collection<Float> aValues) {
if (aValues == null) {
return null;
}
TypeSystem ts = aCas.getTypeSystem();
Type emptyType = ts.getType(CAS.TYPE_NAME_EMPTY_FLOAT_LIST);
if (aValues.size() == 0) {
return aCas.createFS(emptyType);
}
Type nonEmptyType = ts.getType(CAS.TYPE_NAME_NON_EMPTY_FLOAT_LIST);
Feature headFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD);
Feature tailFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL);
FeatureStructure head = aCas.createFS(nonEmptyType);
FeatureStructure list = head;
Iterator<Float> i = aValues.iterator();
while (i.hasNext()) {
head.setFloatValue(headFeature, i.next());
if (i.hasNext()) {
FeatureStructure tail = aCas.createFS(nonEmptyType);
head.setFeatureValue(tailFeature, tail);
head = tail;
} else {
head.setFeatureValue(tailFeature, aCas.createFS(emptyType));
}
}
return (T) list;
}
public static FloatList createFloatList(JCas aJCas, Collection<Float> aCollection) {
return createFloatList(aJCas.getCas(), aCollection);
}
public static IntegerList createIntegerList(JCas aJCas, int... aValues) {
return createIntegerList(aJCas.getCas(), aValues);
}
public static <T extends FeatureStructure> T createIntegerList(CAS aCas, int... aValues) {
if (aValues == null) {
return null;
}
TypeSystem ts = aCas.getTypeSystem();
Type emptyType = ts.getType(CAS.TYPE_NAME_EMPTY_INTEGER_LIST);
if (aValues.length == 0) {
return aCas.createFS(emptyType);
}
Type nonEmptyType = ts.getType(CAS.TYPE_NAME_NON_EMPTY_INTEGER_LIST);
Feature headFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD);
Feature tailFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL);
FeatureStructure head = aCas.createFS(nonEmptyType);
FeatureStructure list = head;
int i = 0;
while (i < aValues.length) {
head.setIntValue(headFeature, aValues[i]);
i++;
if (i < aValues.length) {
FeatureStructure tail = aCas.createFS(nonEmptyType);
head.setFeatureValue(tailFeature, tail);
head = tail;
} else {
head.setFeatureValue(tailFeature, aCas.createFS(emptyType));
}
}
return (T) list;
}
public static <T extends FeatureStructure> T createIntegerList(CAS aCas, Collection<Integer> aValues) {
if (aValues == null) {
return null;
}
TypeSystem ts = aCas.getTypeSystem();
Type emptyType = ts.getType(CAS.TYPE_NAME_EMPTY_INTEGER_LIST);
if (aValues.size() == 0) {
return aCas.createFS(emptyType);
}
Type nonEmptyType = ts.getType(CAS.TYPE_NAME_NON_EMPTY_INTEGER_LIST);
Feature headFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD);
Feature tailFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL);
FeatureStructure head = aCas.createFS(nonEmptyType);
FeatureStructure list = head;
Iterator<Integer> i = aValues.iterator();
while (i.hasNext()) {
head.setIntValue(headFeature, i.next());
if (i.hasNext()) {
FeatureStructure tail = aCas.createFS(nonEmptyType);
head.setFeatureValue(tailFeature, tail);
head = tail;
} else {
head.setFeatureValue(tailFeature, aCas.createFS(emptyType));
}
}
return (T) list;
}
public static IntegerList createIntegerList(JCas aJCas, Collection<Integer> aCollection) {
return createIntegerList(aJCas.getCas(), aCollection);
}
public static StringList createStringList(JCas aJCas, String... aValues) {
return createStringList(aJCas.getCas(), aValues);
}
public static <T extends FeatureStructure> T createStringList(CAS aCas, String... aValues) {
return createStringList(aCas, asList(aValues));
}
public static <T extends FeatureStructure> T createStringList(CAS aCas, Collection<String> aValues) {
if (aValues == null) {
return null;
}
TypeSystem ts = aCas.getTypeSystem();
Type emptyType = ts.getType(CAS.TYPE_NAME_EMPTY_STRING_LIST);
if (aValues.size() == 0) {
return aCas.createFS(emptyType);
}
Type nonEmptyType = ts.getType(CAS.TYPE_NAME_NON_EMPTY_STRING_LIST);
Feature headFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD);
Feature tailFeature = nonEmptyType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL);
FeatureStructure head = aCas.createFS(nonEmptyType);
FeatureStructure list = head;
Iterator<String> i = aValues.iterator();
while (i.hasNext()) {
head.setStringValue(headFeature, i.next());
if (i.hasNext()) {
FeatureStructure tail = aCas.createFS(nonEmptyType);
head.setFeatureValue(tailFeature, tail);
head = tail;
} else {
head.setFeatureValue(tailFeature, aCas.createFS(emptyType));
}
}
return (T) list;
}
public static StringList createStringList(JCas aJCas, Collection<String> aCollection) {
return createStringList(aJCas.getCas(), aCollection);
}
private static class FSIteratorAdapter<T extends FeatureStructure> extends AbstractCollection<T> {
private int sizeCache = -1;
private final FSIterator<T> index;
public FSIteratorAdapter(final FSIterator<T> aIterator) {
index = aIterator.copy();
index.moveToFirst();
}
@Override
public Iterator<T> iterator() {
return index.copy();
}
@Override
public int size() {
// Unfortunately FSIterator does not expose the sizes of its internal collection,
// neither the current position although FSIteratorAggregate has a private field
// with that information.
if (sizeCache == -1) {
synchronized (this) {
if (sizeCache == -1) {
FSIterator<T> clone = index.copy();
clone.moveToFirst();
sizeCache = 0;
while (clone.isValid()) {
sizeCache++;
clone.moveToNext();
}
}
}
}
return sizeCache;
}
}
private static class AnnotationIndexAdapter<T extends AnnotationFS> extends AbstractCollection<T> {
private final AnnotationIndex<T> index;
public AnnotationIndexAdapter(AnnotationIndex<T> aIndex) {
index = aIndex;
}
@Override
public Iterator<T> iterator() {
return index.withSnapshotIterators().iterator();
}
@Override
public int size() {
return index.size();
}
}
}