You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2017/03/17 17:50:12 UTC
svn commit: r1787457 - in /uima/uimafit/trunk/uimafit-core/src:
main/java/org/apache/uima/fit/util/CasUtil.java
main/java/org/apache/uima/fit/util/JCasUtil.java
test/java/org/apache/uima/fit/util/JCasUtilTest.java
Author: rec
Date: Fri Mar 17 17:50:11 2017
New Revision: 1787457
URL: http://svn.apache.org/viewvc?rev=1787457&view=rev
Log:
[UIMA-5067] JCasUtil.selectSingleRelative returns wrong object
- Throw an IllegalArgumentException if the anchor type does not subsume the selected type and position is 0
- Added unit tests to for both cases (subsumed/not subsumed)
- Document new behavior
- Renamed arguments (cosmetic change)
Modified:
uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/CasUtil.java
uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/JCasUtil.java
uima/uimafit/trunk/uimafit-core/src/test/java/org/apache/uima/fit/util/JCasUtilTest.java
Modified: uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/CasUtil.java
URL: http://svn.apache.org/viewvc/uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/CasUtil.java?rev=1787457&r1=1787456&r2=1787457&view=diff
==============================================================================
--- uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/CasUtil.java (original)
+++ uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/CasUtil.java Fri Mar 17 17:50:11 2017
@@ -980,33 +980,38 @@ public final class CasUtil {
}
/**
- * Return an annotation preceding or following of a given reference annotation.
+ * 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 cas
* a CAS containing the annotation.
* @param type
* a type.
- * @param annotation
+ * @param aAnchor
* anchor annotation
- * @param index
+ * @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 index points beyond the type index bounds.
+ * 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>
*/
- public static AnnotationFS selectSingleRelative(CAS cas, Type type, AnnotationFS annotation,
- int index) {
+ public static AnnotationFS selectSingleRelative(CAS cas, Type type, AnnotationFS aAnchor,
+ int aPosition) {
if (!cas.getTypeSystem().subsumes(cas.getAnnotationType(), type)) {
throw new IllegalArgumentException("Type [" + type.getName() + "] is not an annotation type");
}
// move to first previous annotation
FSIterator<AnnotationFS> itr = cas.getAnnotationIndex(type).iterator();
- itr.moveTo(annotation);
+ itr.moveTo(aAnchor);
- if (index < 0) {
+ if (aPosition < 0) {
// If the insertion point is beyond the index, move back to the last.
if (!itr.isValid()) {
itr.moveToLast();
@@ -1020,11 +1025,11 @@ public final class CasUtil {
// the same offset as the reference annotation.
// make sure we're past the beginning of the reference annotation
- while (itr.isValid() && itr.get().getEnd() > annotation.getBegin()) {
+ while (itr.isValid() && itr.get().getEnd() > aAnchor.getBegin()) {
itr.moveToPrevious();
}
- for (int i = 0; i < (-index - 1) && itr.isValid(); ++i, itr.moveToPrevious()) {
+ for (int i = 0; i < (-aPosition - 1) && itr.isValid(); ++i, itr.moveToPrevious()) {
// Seeking
}
@@ -1033,7 +1038,7 @@ public final class CasUtil {
} else {
return itr.get();
}
- } else if (index > 0) {
+ } else if (aPosition > 0) {
// When seeking forward, there is no need to check if the insertion point is beyond the
// index. If it was, there would be nothing beyond it that could be found and returned.
// The moveTo operation also does not yield an iterator being invalid because it points
@@ -1045,11 +1050,11 @@ public final class CasUtil {
// the same offset as the reference annotation.
// make sure we're past the end of the reference annotation
- while (itr.isValid() && itr.get().getBegin() < annotation.getEnd()) {
+ while (itr.isValid() && itr.get().getBegin() < aAnchor.getEnd()) {
itr.moveToNext();
}
- for (int i = 0; i < (index - 1) && itr.isValid(); ++i, itr.moveToPrevious()) {
+ for (int i = 0; i < (aPosition - 1) && itr.isValid(); ++i, itr.moveToPrevious()) {
// Seeking
}
@@ -1058,8 +1063,13 @@ public final class CasUtil {
} else {
return itr.get();
}
- } else {
- return annotation;
+ } else if (cas.getTypeSystem().subsumes(aAnchor.getType(), type)) {
+ return aAnchor;
+ }
+ else {
+ throw new IllegalArgumentException(
+ "Relative position cannot be 0 if the type of the anchor annotator does not subsume "
+ + "the selected type.");
}
}
Modified: uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/JCasUtil.java
URL: http://svn.apache.org/viewvc/uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/JCasUtil.java?rev=1787457&r1=1787456&r2=1787457&view=diff
==============================================================================
--- uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/JCasUtil.java (original)
+++ uima/uimafit/trunk/uimafit-core/src/main/java/org/apache/uima/fit/util/JCasUtil.java Fri Mar 17 17:50:11 2017
@@ -67,6 +67,7 @@ public final class JCasUtil {
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);
}
@@ -613,29 +614,34 @@ public final class JCasUtil {
}
/**
- * Return an annotation preceding or following of a given reference annotation.
+ * 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
- * a type.
- * @param annotation
+ * type of the annotation to be returned.
+ * @param aAnchor
* anchor annotation
- * @param index
+ * @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 index points beyond the type index bounds.
+ * 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 annotation, int index) {
+ AnnotationFS aAnchor, int aPosition) {
Type t = getType(aJCas, aType);
- return (T) CasUtil.selectSingleRelative(aJCas.getCas(), t, annotation, index);
+ return (T) CasUtil.selectSingleRelative(aJCas.getCas(), t, aAnchor, aPosition);
}
/**
Modified: uima/uimafit/trunk/uimafit-core/src/test/java/org/apache/uima/fit/util/JCasUtilTest.java
URL: http://svn.apache.org/viewvc/uima/uimafit/trunk/uimafit-core/src/test/java/org/apache/uima/fit/util/JCasUtilTest.java?rev=1787457&r1=1787456&r2=1787457&view=diff
==============================================================================
--- uima/uimafit/trunk/uimafit-core/src/test/java/org/apache/uima/fit/util/JCasUtilTest.java (original)
+++ uima/uimafit/trunk/uimafit-core/src/test/java/org/apache/uima/fit/util/JCasUtilTest.java Fri Mar 17 17:50:11 2017
@@ -461,6 +461,37 @@ public class JCasUtilTest extends Compon
assertEquals(secondToken.getBegin(), a.getBegin());
assertEquals(secondToken.getEnd(), a.getEnd());
}
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testSingleRelativeDifferentTypeSamePositionFail() {
+ String text = "one two three";
+ tokenBuilder.buildTokens(jCas, text);
+
+ List<Token> tokens = new ArrayList<Token>(select(jCas, Token.class));
+
+ for (Token token : tokens) {
+ new AnalyzedText(jCas, token.getBegin(), token.getEnd()).addToIndexes();
+ }
+
+ Token firstToken = tokens.get(0);
+ selectSingleRelative(jCas, AnalyzedText.class, firstToken, 0);
+ }
+
+ @Test
+ public void testSingleRelativeDifferentTypeSamePositionOk() {
+ String text = "one two three";
+ tokenBuilder.buildTokens(jCas, text);
+
+ List<Token> tokens = new ArrayList<Token>(select(jCas, Token.class));
+
+ for (Token token : tokens) {
+ new AnalyzedText(jCas, token.getBegin(), token.getEnd()).addToIndexes();
+ }
+
+ Token firstToken = tokens.get(0);
+ Token a = selectSingleRelative(jCas, Token.class, firstToken, 0);
+ assertEquals(firstToken, a);
+ }
@Test
public void testSelectFollowing() {