Ofer Bronstein created UIMA-3724:
------------------------------------
Summary: Adding (J)CasUtil.selectCoveredSingle()
Key: UIMA-3724
URL: https://issues.apache.org/jira/browse/UIMA-3724
Project: UIMA
Issue Type: Improvement
Components: uimaFIT
Reporter: Ofer Bronstein
Priority: Minor
JCasUtil (and its equivalent CASUtil) have two very useful methods:
- {{selectSingle(JCas jCas, Class<T> type)}}, retrieving all T type annotations
from the CAS, making sure only one exists, and returning it
- {{selectCovered(JCas jCas, final Class<T> type, AnnotationFS
coveringAnnotation)}}, retrieving all T type annotations from the CAS, that
exist in the span defined by the covering annotation.
My request is to add a {{selectCoveredSingle}} method (I already implemented
and tested, written below). It would retrieve all T type annotation in the span
of the covering annotation, make sure there is only one, and return it.
The uses for such a method would be really common, as this assists in
performing something very basic in UIMA - once you have some annotation, you
want to retrieve other information on it, and if it is a small unit, then you
know in advance that many types of information should only appear once for that
annotation. Otherwise, it's an error.
For instance, say I have linguistically annotated text, and I hold some
intersting annotation of a Token. Then I want to find out what is its Part Of
Speech. Then I would simply call: {{selectCoveredSingle(jcas,
PartOfSpeech.class, token)}}, and get exactly one PartOfSpeech annotation as I
expected. If there is none or more then one, an exception is thrown.
One could also use a method like {{selectCoveredSingleOptional}} (not
implemented yet), that does exactly the same, but returns null when no such
annotation exists, instead of throwing an exception. This makes sense when a
token can have some optional attribute. In linguistics, it could be when a
Token may be a NamedEntity, but not necessarily.
the implementation is made out of two methods - the first should be in
JCasUtil, the second should be in CASUtil.
===
Implementation:
===
/**
* Get the annotation 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.
*
* @param <T>
* the JCas type.
* @param jCas
* a JCas containing the annotation.
* @param type
* a UIMA type.
* @param coveringAnnotation
* the covering annotation.
* @return the single instance of the given type.
* @throws IllegalArgumentException if not exactly one instance if the
given type is present
* under the covering annotation.
* @see Subiterator
*
* @author Ofer Bronstein
* @since April 2014
*/
@SuppressWarnings("unchecked")
public static <T extends Annotation> T selectCoveredSingle(JCas jCas,
final Class<T> type,
AnnotationFS coveringAnnotation) {
return (T) selectCoveredSingle(jCas.getCas(),
JCasUtil.getType(jCas, type),
coveringAnnotation);
}
/**
* Get the annotation 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.
*
* @param cas
* a cas containing the annotation.
* @param type
* a UIMA type.
* @param coveringAnnotation
* the covering annotation.
* @return the single instance of the given type.
* @throws IllegalArgumentException if not exactly one instance if the
given type is present
* under the covering annotation.
* @see Subiterator
*
* @author Ofer Bronstein
* @since April 2014
*/
public static AnnotationFS selectCoveredSingle(CAS cas, Type type,
AnnotationFS coveringAnnotation) {
List<AnnotationFS> annotations = CasUtil.selectCovered(cas,
type, coveringAnnotation);
if (annotations.isEmpty()) {
throw new IllegalArgumentException("CAS does not
contain any [" + type.getName() + "]");
}
if (annotations.size() > 1) {
throw new IllegalArgumentException("CAS contains more
than one [" + type.getName()
+ "]");
}
return annotations.get(0);
}
--
This message was sent by Atlassian JIRA
(v6.2#6252)