This is an automated email from the ASF dual-hosted git repository. rec pushed a commit to branch bugfix/346-Helper-annotation-created-by-subiterator-may-remain-in-CAS in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git
commit 3c8c85a9ea6eee4f0306034c7d21cadd447ff941 Author: Richard Eckart de Castilho <r...@apache.org> AuthorDate: Mon Sep 18 11:27:05 2023 +0200 Issue #346: Helper annotation created by subiterator may remain in CAS - Use internal helper method from SelectFSs_impl to produce temporary annotation - Clean up test class --- .../org/apache/uima/cas/impl/SelectFSs_impl.java | 5 + .../java/org/apache/uima/cas/impl/Subiterator.java | 4 +- .../org/apache/uima/cas/test/SubiteratorTest.java | 105 +++++++-------------- 3 files changed, 40 insertions(+), 74 deletions(-) diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java index 77ff9bb07..d059c60cc 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java @@ -56,6 +56,7 @@ import org.apache.uima.cas.impl.Subiterator.BoundsUse; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.cas.text.AnnotationIndex; import org.apache.uima.cas.text.AnnotationPredicates; +import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.EmptyFSList; import org.apache.uima.jcas.cas.FSArray; import org.apache.uima.jcas.cas.FSList; @@ -1018,6 +1019,10 @@ public class SelectFSs_impl<T extends FeatureStructure> implements SelectFSs<T> // } private Annotation makePosAnnot(int begin, int end) { + return makePosAnnot(jcas, begin, end); + } + + static Annotation makePosAnnot(JCas jcas, int begin, int end) { if (end < begin) { throw new IllegalArgumentException("End value must be >= Begin value"); } diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java index 63c55673f..613b30c86 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java @@ -365,7 +365,7 @@ public class Subiterator<T extends AnnotationFS> implements LowLevelIterator<T> if (begin < 0) { begin = 0; } - coveringStartPos = new Annotation(jcas, begin, Integer.MAX_VALUE); + coveringStartPos = SelectFSs_impl.makePosAnnot(jcas, begin, Integer.MAX_VALUE); } else { coveringStartPos = null; } @@ -759,7 +759,7 @@ public class Subiterator<T extends AnnotationFS> implements LowLevelIterator<T> */ private void moveToJustPastBoundsAndBackup(int begin, int end, Predicate<Annotation> continue_going_backwards) { - it.moveToNoReinit(new Annotation(jcas, begin, end)); + it.moveToNoReinit(SelectFSs_impl.makePosAnnot(jcas, begin, end)); if (!it.isValid()) { it.moveToLastNoReinit(); diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/test/SubiteratorTest.java b/uimaj-core/src/test/java/org/apache/uima/cas/test/SubiteratorTest.java index dbdefcafb..e3ed7b63a 100644 --- a/uimaj-core/src/test/java/org/apache/uima/cas/test/SubiteratorTest.java +++ b/uimaj-core/src/test/java/org/apache/uima/cas/test/SubiteratorTest.java @@ -19,26 +19,23 @@ package org.apache.uima.cas.test; -import static org.junit.Assert.assertTrue; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.contentOf; import java.io.File; -import java.io.IOException; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; -import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.text.AnnotationIndex; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation; -import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; -import org.apache.uima.util.FileUtils; -import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; -import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -53,83 +50,47 @@ import org.junit.jupiter.api.Test; //@formatter:on public class SubiteratorTest { - private AnalysisEngine ae = null; + private static AnalysisEngine segmenter = null; - @BeforeEach - public void setUp() { + private JCas jcas; + + @BeforeAll + static void setupClass() throws Exception { File descriptorFile = JUnitExtension.getFile("CASTests/desc/TokensAndSentences.xml"); - assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), - descriptorFile.exists()); - - try { - XMLParser parser = UIMAFramework.getXMLParser(); - ResourceSpecifier spec = (ResourceSpecifier) parser.parse(new XMLInputSource(descriptorFile)); - this.ae = UIMAFramework.produceAnalysisEngine(spec); - } catch (IOException e) { - e.printStackTrace(); - assertTrue(false); - } catch (InvalidXMLException e) { - e.printStackTrace(); - assertTrue(false); - } catch (ResourceInitializationException e) { - e.printStackTrace(); - assertTrue(false); - } + assertThat(descriptorFile).exists(); + + XMLParser parser = UIMAFramework.getXMLParser(); + ResourceSpecifier spec = (ResourceSpecifier) parser.parse(new XMLInputSource(descriptorFile)); + segmenter = UIMAFramework.produceAnalysisEngine(spec); } - @AfterEach - public void tearDown() { - if (this.ae != null) { - this.ae.destroy(); - this.ae = null; - } + @BeforeEach + public void setUp() throws Exception { + String text = contentOf(getClass().getResource("/CASTests/verjuice.txt"), UTF_8); + + jcas = segmenter.newJCas(); + jcas.setDocumentText(text); + + segmenter.process(jcas); } @Test - public void testAnnotator() { - File textFile = JUnitExtension.getFile("CASTests/verjuice.txt"); - String text = null; - try { - text = FileUtils.file2String(textFile, "utf-8"); - } catch (IOException e) { - e.printStackTrace(); - assertTrue(false); - } - JCas jcas = null; - try { - jcas = this.ae.newJCas(); - } catch (ResourceInitializationException e) { - e.printStackTrace(); - assertTrue(false); - } - jcas.setDocumentText(text); - try { - this.ae.process(jcas); - - iterateAndcheck(jcas); - - iterateAndcheck(jcas); - } catch (AnalysisEngineProcessException e) { - e.printStackTrace(); - assertTrue(false); - } catch (ClassCastException e) { - // UIMA-464: Subiterator.moveTo() throws ClassCastException. - assertTrue(false); - } + public void testAnnotator() throws Exception { + iterateAndCheck(jcas); + + iterateAndCheck(jcas); } - private void iterateAndcheck(JCas jcas) { - AnnotationIndex<Token> tokenIndex = jcas.getAnnotationIndex(Token.class); - Annotation sentence = jcas.getAnnotationIndex(Sentence.class).iterator().next(); - FSIterator<Token> tokenIterator = tokenIndex.subiterator(sentence); - Annotation token = tokenIndex.iterator().next(); - // debug token.toString(); - tokenIterator.moveTo(token); // throws ClassCastException + private void iterateAndCheck(JCas aJCas) { + AnnotationIndex<Token> tokenIndex = aJCas.getAnnotationIndex(Token.class); + Annotation firstSentence = aJCas.getAnnotationIndex(Sentence.class).iterator().next(); + FSIterator<Token> tokenIterator = tokenIndex.subiterator(firstSentence); + Annotation firstToken = tokenIndex.iterator().next(); + tokenIterator.moveTo(firstToken); // check unambiguous iterator creation - FSIterator<Token> it = tokenIndex.iterator(false); - it.moveTo(token); + it.moveTo(firstToken); } }