blob: 97aae8ddd2552bd4d64044c457d2871ae02705cd [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.
*/
package org.apache.uima.fit.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.CASException;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.impl.Subiterator;
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.FSArray;
import org.apache.uima.jcas.cas.FSList;
import org.apache.uima.jcas.cas.TOP;
import org.apache.uima.jcas.tcas.Annotation;
/**
* Utility methods for convenient access to the {@link JCas}.
*
*/
public final class JCasUtil {
private JCasUtil() {
// No instances
}
/**
* Convenience method to iterator over all annotations of a given type occurring within the scope
* of a provided annotation (sub-iteration).
*
* @param <T>
* the iteration type.
* @param jCas
* a JCas.
* @param container
* the containing annotation.
* @param type
* the type.
* @param ambiguous
* If set to <code>false</code>, resulting iterator will be unambiguous.
* @param strict
* Controls if annotations that overlap to the right are considered in or out.
* @return A sub-iterator iterable.
* @see AnnotationIndex#subiterator(AnnotationFS, boolean, boolean)
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> Iterable<T> subiterate(final JCas jCas, final Class<T> type,
final AnnotationFS container, final boolean ambiguous, final boolean strict) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return JCasUtil.iterator(container, type, ambiguous, strict);
}
};
}
/**
* Get an iterator over the given feature structure type.
*
* @param <T>
* the JCas type.
* @param jCas
* a JCas.
* @param type
* a type.
* @return a return value.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends TOP> Iterator<T> iterator(JCas jCas, Class<T> type) {
return (Iterator) FSCollectionFactory.create(jCas.getCas(), getType(jCas, type)).iterator();
}
/**
* Convenience method to get a sub-iterator for the specified type.
*
* @param <T>
* the iteration type.
* @param container
* the containing annotation.
* @param type
* the type.
* @param ambiguous
* If set to <code>false</code>, resulting iterator will be unambiguous.
* @param strict
* Controls if annotations that overlap to the right are considered in or out.
* @return A sub-iterator.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
@SuppressWarnings("unchecked")
public static <T extends AnnotationFS> Iterator<T> iterator(AnnotationFS container,
Class<T> type, boolean ambiguous, boolean strict) {
CAS cas = container.getCAS();
return ((AnnotationIndex<T>) cas.getAnnotationIndex(CasUtil.getType(cas, type))).subiterator(
container, ambiguous, strict);
}
/**
* Get the CAS type for the given JCas wrapper class type.
*
* @param jCas
* the JCas containing the type system.
* @param type
* the JCas wrapper class type.
* @return the CAS type.
*/
public static Type getType(JCas jCas, Class<?> type) {
return CasUtil.getType(jCas.getCas(), type);
}
/**
* Get the CAS type for the given JCas wrapper class type making sure it inherits from
* {@link Annotation}.
*
* @param jCas
* the JCas containing the type system.
* @param type
* the JCas wrapper class type.
* @return the CAS type.
*/
public static Type getAnnotationType(JCas jCas, Class<?> type) {
return CasUtil.getAnnotationType(jCas.getCas(), type);
}
/**
* Convenience method select all feature structure from the given type from an array.
*
* @param <T>
* the JCas type.
* @param array
* a feature structure array.
* @param type
* the type.
* @return A collection of the selected type.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends TOP> Collection<T> select(final FSArray array, final Class<T> type) {
return cast(CasUtil.selectFS(array, CasUtil.getType(array.getCAS(), type.getName())));
}
/**
* Convenience method select all feature structure from the given type from a list.
*
* @param <T>
* the JCas type.
* @param list
* a feature structure list.
* @param type
* the type.
* @return A collection of the selected type.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends TOP> Collection<T> select(final FSList list, final Class<T> type) {
return cast(FSCollectionFactory.create(list, CasUtil.getType(list.getCAS(), type.getName())));
}
/**
* Convenience method to iterator over all features structures of a given type.
*
* @param <T>
* the iteration type.
* @param jCas
* the JCas containing the type system.
* @param type
* the type.
* @return A collection of the selected type.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends TOP> Collection<T> select(final JCas jCas, final Class<T> type) {
return cast(CasUtil.selectFS(jCas.getCas(), getType(jCas, type)));
}
/**
* Get all annotations of the given type at the specified offsets.
*
* @param <T>
* the type of annotations to fetch.
* @param jCas
* the CAS containing the annotations.
* @param type
* the type of annotations to fetch.
* @param aBegin
* the begin offset.
* @param aEnd
* the end offset.
* @return the annotations at the specified offsets.
*/
public static <T extends Annotation> List<T> selectAt(final JCas jCas, final Class<T> type,
int aBegin, int aEnd) {
return cast(CasUtil.selectAt(jCas.getCas(), getType(jCas, type), aBegin, aEnd));
}
/**
* Get a single annotations of the given type at the specified offsets.
*
* @param <T>
* the type of annotations to fetch.
* @param jCas
* the CAS containing the annotations.
* @param type
* the type of annotations to fetch.
* @param aBegin
* the begin offset.
* @param aEnd
* the end offset.
* @return the annotation at the specified offsets.
*/
@SuppressWarnings("unchecked")
public static <T extends Annotation> T selectSingleAt(final JCas jCas, final Class<T> type,
int aBegin, int aEnd) {
return (T) CasUtil.selectSingleAt(jCas.getCas(), getType(jCas, type), aBegin, aEnd);
}
/**
* Convenience method to iterator over all features structures.
*
* @param jCas
* the JCas containing the type system. the type.
* @return A collection of the selected type.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static Collection<TOP> selectAll(final JCas jCas) {
return select(jCas, TOP.class);
}
/**
* Get a list of annotations of the given annotation type located between two annotations. Does
* not use subiterators and does not respect type priorities. Zero-width annotations what lie on
* the borders are included in the result, e.g. if the boundary annotations are [1..2] and [2..3]
* then an annotation [2..2] is returned. If there is a non-zero overlap between the boundary
* annotations, the result is empty. The method properly handles cases where the second boundary
* annotations occurs before the first boundary annotation by switching their roles.
*
* @param <T>
* the JCas type.
* @param type
* a UIMA type.
* @param ann1
* the first boundary annotation.
* @param ann2
* the second boundary annotation.
* @return a return value.
* @see Subiterator
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectBetween(final Class<T> type,
AnnotationFS ann1, AnnotationFS ann2) {
return cast(CasUtil.selectBetween(CasUtil.getType(ann1.getCAS(), type), ann1, ann2));
}
/**
* Get a list of annotations of the given annotation type located between two annotations. Does
* not use subiterators and does not respect type priorities. Zero-width annotations what lie on
* the borders are included in the result, e.g. if the boundary annotations are [1..2] and [2..3]
* then an annotation [2..2] is returned. If there is a non-zero overlap between the boundary
* annotations, the result is empty. The method properly handles cases where the second boundary
* annotations occurs before the first boundary annotation by switching their roles.
*
* @param <T>
* the JCas type.
* @param jCas
* a JCas containing the annotation.
* @param type
* a UIMA type.
* @param ann1
* the first boundary annotation.
* @param ann2
* the second boundary annotation.
* @return a return value.
* @see Subiterator
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectBetween(JCas jCas, final Class<T> type,
AnnotationFS ann1, AnnotationFS ann2) {
return cast(CasUtil.selectBetween(jCas.getCas(), getType(jCas, type), ann1, ann2));
}
/**
* Get a list of annotations of the given annotation type constrained by a 'covering' annotation.
* Iterates over all annotations of the given type to find the covered annotations. Does not use
* subiterators.
* <p>
* The covering annotation is never returned itself, even if it is of the queried-for type or a
* subtype of that type.
* <p>
* The method only returns properly covered annotations, that is annotations where the begin/end
* offsets are equal to the 'covering' annotation or where both the begin/end are included in
* the span of the 'covering' annotation. Partially overlapping annotations are not returned.
*
* @param <T>
* the JCas type.
* @param type
* a UIMA type.
* @param coveringAnnotation
* the covering annotation.
* @return a return value.
* @see Subiterator
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends AnnotationFS> List<T> selectCovered(Class<T> type,
AnnotationFS coveringAnnotation) {
return cast(CasUtil.selectCovered(CasUtil.getType(coveringAnnotation.getCAS(), type),
coveringAnnotation));
}
/**
* Get a list of annotations of the given annotation type constrained by a 'covering' annotation.
* Iterates over all annotations of the given type to find the covered annotations. Does not use
* subiterators.
* <p>
* The covering annotation is never returned itself, even if it is of the queried-for type or a
* subtype of that type.
* <p>
* The method only returns properly covered annotations, that is annotations where the begin/end
* offsets are equal to the 'covering' annotation or where both the begin/end are included in
* the span of the 'covering' annotation. Partially overlapping annotations are not returned.
*
* @param <T>
* the JCas type.
* @param jCas
* a JCas containing the annotation.
* @param type
* a UIMA type.
* @param coveringAnnotation
* the covering annotation.
* @return a return value.
* @see Subiterator
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectCovered(JCas jCas, final Class<T> type,
AnnotationFS coveringAnnotation) {
return cast(CasUtil.selectCovered(jCas.getCas(), getType(jCas, type), coveringAnnotation));
}
/**
* Get a list of annotations of the given annotation type constrained by a 'covering' annotation.
* Iterates over all annotations of the given type to find the covered annotations. Does not use
* subiterators.
* <p>
* <b>Note:</b> this is significantly slower than using
* {@link #selectCovered(JCas, Class, AnnotationFS)}. It is possible to use
* {@code selectCovered(jCas, cls, new Annotation(jCas, int, int))}, but that will allocate memory
* in the jCas for the new annotation. If you do that repeatedly many times, memory may fill up.
* <p>
* The method only returns properly covered annotations, that is annotations where the begin/end
* offsets are equal to the given begin/end or where both the begin/end are included in
* the span of the given span. Partially overlapping annotations are not returned.
*
* @param <T>
* the JCas type.
* @param jCas
* a JCas containing the annotation.
* @param type
* a UIMA type.
* @param begin
* begin offset.
* @param end
* end offset.
* @return a return value.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectCovered(JCas jCas, final Class<T> type,
int begin, int end) {
return cast(CasUtil.selectCovered(jCas.getCas(), getType(jCas, type), begin, end));
}
/**
* Get a list of annotations of the given annotation type constraint by a certain annotation.
* Iterates over all annotations to find the covering annotations.
* <p>
* The method only returns properly covering annotations, that is annotations where the begin/end
* offsets are equal to the begin/end of the given annotation or where given 'covered' annotation
* is properly contained within the span of the 'covering' annotation. Partially overlapping
* annotations are not returned.
*
* <p>
* <b>Note:</b> this is <b>REALLY SLOW!</b> You don't want to use this. Instead, consider using
* {@link #indexCovering(JCas, Class, Class)} or a {@link ContainmentIndex}.
*
* @param <T>
* the JCas type.
* @param type
* a UIMA type.
* @param coveredAnnotation
* the covered annotation.
* @return a return value.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectCovering(Class<T> type,
AnnotationFS coveredAnnotation) {
return cast(CasUtil.selectCovering(CasUtil.getType(coveredAnnotation.getCAS(), type),
coveredAnnotation));
}
/**
* Get a list of annotations of the given annotation type constraint by a certain annotation.
* Iterates over all annotations to find the covering annotations.
* <p>
* The method only returns properly covering annotations, that is annotations where the begin/end
* offsets are equal to the begin/end of the given annotation or where given 'covered' annotation
* is properly contained within the span of the 'covering' annotation. Partially overlapping
* annotations are not returned.
*
* <p>
* <b>Note:</b> this is <b>REALLY SLOW!</b> You don't want to use this. Instead, consider using
* {@link #indexCovering(JCas, Class, Class)} or a {@link ContainmentIndex}.
*
* @param <T>
* the JCas type.
* @param jCas
* a CAS.
* @param type
* a UIMA type.
* @param coveredAnnotation
* the covered annotation.
* @return a return value.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectCovering(JCas jCas, Class<T> type,
AnnotationFS coveredAnnotation) {
return cast(CasUtil.selectCovering(jCas.getCas(), getType(jCas, type), coveredAnnotation));
}
/**
* Get a list of annotations of the given annotation type constraint by a certain annotation.
* Iterates over all annotations to find the covering annotations.
* <p>
* The method only returns properly covering annotations, that is annotations where the begin/end
* offsets are equal to the given begin/end to or where given span is properly contained within
* the span of the 'covering' annotation. Partially overlapping annotations are not returned.
*
* <p>
* <b>Note:</b> this is <b>REALLY SLOW!</b> You don't want to use this. Instead, consider using
* {@link #indexCovering(JCas, Class, Class)} or a {@link ContainmentIndex}.
*
* @param <T>
* the JCas type.
* @param jCas
* a CAS.
* @param type
* a UIMA type.
* @param begin
* begin offset.
* @param end
* end offset.
* @return a return value.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectCovering(JCas jCas, Class<T> type, int begin,
int end) {
return cast(CasUtil.selectCovering(jCas.getCas(), getType(jCas, type), begin, end));
}
/**
* Create an index for quickly lookup up the annotations covering a particular annotation. This is
* preferable to using {@link #selectCovering(JCas, Class, int, int)} because the overhead of
* scanning the CAS occurs only when the index is build. Subsequent lookups to the index are fast.
* <p>
* The method only returns properly covering annotations, that is annotations where the begin/end
* offsets are equal to the begin/end of the given annotation or where given 'covered' annotation
* is properly contained within the span of the 'covering' annotation. Partially overlapping
* annotations are not returned.
* <p>
* When querying for the annotations covering a given annotation, the given annotation itself
* is never returned, even if it is of the queried type.
*
* @param <T>
* the covered JCAs type.
* @param <S>
* the covering JCas type.
* @param jCas
* a JCas.
* @param type
* type to create the index for - this is used in lookups.
* @param coveringType
* type of covering annotations.
* @return the index.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation, S extends Annotation> Map<T, Collection<S>> indexCovering(
JCas jCas, Class<? extends T> type, Class<? extends S> coveringType) {
return cast(CasUtil.indexCovering(jCas.getCas(), getType(jCas, type),
getType(jCas, coveringType)));
}
/**
* Create an index for quickly lookup up the annotations covered by a particular annotation. This
* is preferable to using {@link #selectCovered(JCas, Class, int, int)} because the overhead of
* scanning the CAS occurs only when the index is build. Subsequent lookups to the index are fast.
* The order of entries in the map is not defined. However, lists of covered annotations in
* the map are guaranteed to be in the same order as in the UIMA default annotation index.
* <p>
* The method only returns properly covered annotations, that is annotations where the begin/end
* offsets are equal to the 'covering' annotation or where both the begin/end are included in
* the span of the 'covering' annotation. Partially overlapping annotations are not returned.
* <p>
* When querying for the annotations covered by a given annotation, the given annotation itself
* is never returned, even if it is of the queried type.
*
* @param <T>
* the covering JCas type.
* @param <S>
* the covered JCas type.
* @param jCas
* a JCas.
* @param type
* type to create the index for - this is used in lookups.
* @param coveredType
* type of covered annotations.
* @return the index.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation, S extends Annotation> Map<T, Collection<S>> indexCovered(
JCas jCas, Class<? extends T> type, Class<? extends S> coveredType) {
return cast(CasUtil
.indexCovered(jCas.getCas(), getType(jCas, type), getType(jCas, coveredType)));
}
/**
* Check if the given annotation contains any annotation of the given type.
*
* @param jCas
* a JCas containing the annotation.
* @param coveringAnnotation
* the covering annotation.
* @param type
* a UIMA type.
* @return if an annotation of the given type is present.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static boolean contains(JCas jCas, AnnotationFS coveringAnnotation,
Class<? extends Annotation> type) {
return selectCovered(jCas, type, coveringAnnotation).size() > 0;
}
/**
* This method exists simply as a convenience method for unit testing. It is not very efficient
* and should not, in general be used outside the context of unit testing.
* <p>
* It is intentional that this method only allows annotation types. The CAS indexing mechanisms
* are not well defined for non-annotation types. There are no reliably, built-in indexes for
* non-annotation types.
*
* @param <T>
* JCas wrapper type.
* @param jCas
* a JCas containing the annotation.
* @param cls
* a UIMA type.
* @param index
* this can be either positive (0 corresponds to the first annotation of a type) or
* negative (-1 corresponds to the last annotation of a type.)
* @return an annotation of the given type
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
@SuppressWarnings("unchecked")
public static <T extends Annotation> T selectByIndex(JCas jCas, Class<T> cls, int index) {
return (T) CasUtil.selectByIndex(jCas.getCas(), getType(jCas, cls), index);
}
/**
* Get the single instance of the specified type from the JCas.
*
* @param <T>
* JCas wrapper type.
* @param jCas
* a JCas containing the annotation.
* @param type
* a UIMA type.
* @return the single instance of the given type. throws IllegalArgumentException if not exactly
* one instance if the given type is present.
*/
@SuppressWarnings("unchecked")
public static <T extends TOP> T selectSingle(JCas jCas, Class<T> type) {
return (T) CasUtil.selectSingle(jCas.getCas(), getType(jCas, type));
}
/**
* Return an annotation preceding or following of a given reference annotation.
*
* @param <T>
* the JCas type.
* @param aType
* a type.
* @param annotation
* anchor annotation
* @param index
* relative position to access. A negative value selects a preceding annotation while a
* positive number selects a following annotation.
* @return the addressed annotation.
* @throws IndexOutOfBoundsException
* if the relative index points beyond the type index bounds.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
@SuppressWarnings("unchecked")
public static <T extends Annotation> T selectSingleRelative(Class<T> aType,
AnnotationFS annotation, int index) {
CAS cas = annotation.getCAS();
Type t = CasUtil.getType(cas, aType);
return (T) CasUtil.selectSingleRelative(cas, t, annotation, index);
}
/**
* Return an annotation preceding or following of a given reference annotation. If the type
* parameter corresponds to the type or a subtype of the anchor annotation and the relative
* position is 0, then the anchor annotation is returned.
*
* @param <T>
* the JCas type.
* @param aJCas
* a JCas.
* @param aType
* type of the annotation to be returned.
* @param aAnchor
* anchor annotation
* @param aPosition
* relative position to access. A negative value selects a preceding annotation while a
* positive number selects a following annotation.
* @return the addressed annotation.
* @throws IndexOutOfBoundsException
* if the relative position points beyond the type index bounds.
* @throws IllegalArgumentException
* if the relative position is {@code 0} and the anchor type does not subsume the
* selected type.
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
@SuppressWarnings("unchecked")
public static <T extends Annotation> T selectSingleRelative(JCas aJCas, Class<T> aType,
AnnotationFS aAnchor, int aPosition) {
Type t = getType(aJCas, aType);
return (T) CasUtil.selectSingleRelative(aJCas.getCas(), t, aAnchor, aPosition);
}
/**
* Returns the n annotations preceding the given annotation
*
* @param <T>
* the JCas type.
* @param aType
* a type.
* @param annotation
* anchor annotation
* @param count
* number of annotations to collect
* @return List of aType annotations preceding anchor annotation
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectPreceding(Class<T> aType,
AnnotationFS annotation, int count) {
Type t = CasUtil.getType(annotation.getCAS(), aType);
return cast(CasUtil.selectPreceding(annotation.getView(), t, annotation, count));
}
/**
* Returns the n annotations preceding the given annotation
*
* @param <T>
* the JCas type.
* @param aJCas
* a JCas.
* @param aType
* a type.
* @param annotation
* anchor annotation
* @param count
* number of annotations to collect
* @return List of aType annotations preceding anchor annotation
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectPreceding(JCas aJCas, Class<T> aType,
AnnotationFS annotation, int count) {
Type t = getType(aJCas, aType);
return cast(CasUtil.selectPreceding(aJCas.getCas(), t, annotation, count));
}
/**
* Returns the n annotations following the given annotation
*
* @param <T>
* the JCas type.
* @param aType
* a type.
* @param annotation
* anchor annotation
* @param count
* number of annotations to collect
* @return List of aType annotations following anchor annotation
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectFollowing(Class<T> aType,
AnnotationFS annotation, int count) {
Type t = CasUtil.getType(annotation.getCAS(), aType);
return cast(CasUtil.selectFollowing(annotation.getView(), t, annotation, count));
}
/**
* Returns the n annotations following the given annotation
*
* @param <T>
* the JCas type.
* @param aJCas
* a JCas.
* @param aType
* a type.
* @param annotation
* anchor annotation
* @param count
* number of annotations to collect
* @return List of aType annotations following anchor annotation
* @see <a href="package-summary.html#SortOrder">Order of selected feature structures</a>
*/
public static <T extends Annotation> List<T> selectFollowing(JCas aJCas, Class<T> aType,
AnnotationFS annotation, int count) {
Type t = getType(aJCas, aType);
return cast(CasUtil.selectFollowing(aJCas.getCas(), t, annotation, count));
}
/**
* Test if a JCas contains an annotation of the given type.
*
* @param <T>
* the annotation type.
* @param aJCas
* a JCas.
* @param aType
* a annotation class.
* @return {@code true} if there is at least one annotation of the given type in the JCas.
*/
public static <T extends TOP> boolean exists(JCas aJCas, Class<T> aType) {
return JCasUtil.iterator(aJCas, aType).hasNext();
}
/**
* Convenience method to get the specified view or a default view if the requested view does not
* exist. The default can also be {@code null}.
*
* @param jcas
* a JCas
* @param viewName
* the requested view.
* @param fallback
* the default view if the requested view does not exist.
* @return the requested view or the default if the requested view does not exist.
* @throws IllegalStateException
* if the JCas wrapper cannot be obtained.
*/
public static JCas getView(JCas jcas, String viewName, JCas fallback) {
try {
CAS fallbackCas = fallback != null ? fallback.getCas() : null;
CAS view = CasUtil.getView(jcas.getCas(), viewName, fallbackCas);
return view != null ? view.getJCas() : null;
} catch (CASException e) {
throw new IllegalStateException(e);
}
}
/**
* Convenience method to get the specified view or create a new view if the requested view does
* not exist.
*
* @param jcas
* a JCas
* @param viewName
* the requested view.
* @param create
* the view is created if it does not exist.
* @return the requested view
* @throws IllegalStateException
* if the JCas wrapper cannot be obtained.
*/
public static JCas getView(JCas jcas, String viewName, boolean create) {
try {
CAS view = CasUtil.getView(jcas.getCas(), viewName, create);
return view != null ? view.getJCas() : null;
} catch (CASException e) {
throw new IllegalStateException(e);
}
}
/**
* Fetch the text covered by the specified annotations and return it as a list of strings.
*
* @param <T>
* UIMA JCas type.
* @param iterable
* annotation container.
* @return list of covered strings.
*/
public static <T extends AnnotationFS> List<String> toText(Iterable<T> iterable) {
return CasUtil.toText(iterable);
}
@SuppressWarnings({ "cast", "unchecked", "rawtypes" })
private static <T> Collection<T> cast(Collection aCollection) {
return (Collection<T>) aCollection;
}
@SuppressWarnings({ "cast", "unchecked", "rawtypes" })
private static <T> List<T> cast(List aCollection) {
return (List<T>) aCollection;
}
@SuppressWarnings({ "cast", "unchecked", "rawtypes" })
private static <K, V> Map<K, V> cast(Map aCollection) {
return (Map<K, V>) aCollection;
}
}