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 2020/11/02 18:43:49 UTC
[uima-uimaj] branch
bugfix/UIMA-6287-FSArray.spliterator-fails-to-handle-PEAR-case updated:
[UIMA-6287] FSArray.spliterator() fails to handle PEAR case
This is an automated email from the ASF dual-hosted git repository.
rec pushed a commit to branch bugfix/UIMA-6287-FSArray.spliterator-fails-to-handle-PEAR-case
in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git
The following commit(s) were added to refs/heads/bugfix/UIMA-6287-FSArray.spliterator-fails-to-handle-PEAR-case by this push:
new 6ca1699 [UIMA-6287] FSArray.spliterator() fails to handle PEAR case
6ca1699 is described below
commit 6ca1699f127aedb6b5f64ec939198a0878e3ad5b
Author: Richard Eckart de Castilho <re...@apache.org>
AuthorDate: Mon Nov 2 19:37:24 2020 +0100
[UIMA-6287] FSArray.spliterator() fails to handle PEAR case
- Added unit test for the issue that the toArray is returning the wrong type
- Fixed the spliterator and toArray methods
---
.../java/org/apache/uima/jcas/cas/FSArray.java | 16 ++-
.../apache/uima/cas/test/JCasClassLoaderTest.java | 140 +++++++++++++++------
2 files changed, 113 insertions(+), 43 deletions(-)
diff --git a/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java b/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java
index 05a7d2d..3463a37 100644
--- a/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java
+++ b/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java
@@ -19,10 +19,13 @@
package org.apache.uima.jcas.cas;
-import java.util.Arrays;
+import static java.util.Spliterator.ORDERED;
+
+import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Spliterator;
+import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@@ -299,7 +302,7 @@ public final class FSArray<T extends FeatureStructure> extends TOP
@Override
public Spliterator<T> spliterator() {
- return (Spliterator<T>) Arrays.spliterator(theArray);
+ return Spliterators.spliterator(iterator(), size(), ORDERED);
}
public Stream<T> stream() {
@@ -328,12 +331,17 @@ public final class FSArray<T extends FeatureStructure> extends TOP
return false;
}
+ @Override
public <U extends TOP> U[] toArray(U[] a) {
final int sz = size();
if (a.length < sz) {
- return (U[]) Arrays.copyOf(theArray, sz, a.getClass());
+ @SuppressWarnings("unchecked")
+ U[] copy = (U[]) Array.newInstance(a.getClass().getComponentType(), sz);
+ copyToArray(0, copy, 0, sz);
+ return copy;
}
- System.arraycopy(theArray, 0, a, 0, size());
+
+ copyToArray(0, a, 0, size());
return a;
}
diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/test/JCasClassLoaderTest.java b/uimaj-core/src/test/java/org/apache/uima/cas/test/JCasClassLoaderTest.java
index ef21e5d..d39e632 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/test/JCasClassLoaderTest.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/test/JCasClassLoaderTest.java
@@ -28,6 +28,7 @@ import static org.apache.uima.cas.CAS.TYPE_NAME_ANNOTATION;
import static org.apache.uima.cas.CAS.TYPE_NAME_FS_ARRAY;
import static org.apache.uima.util.CasCreationUtils.createCas;
import static org.apache.uima.util.CasCreationUtils.mergeTypeSystems;
+import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.IOException;
@@ -60,6 +61,7 @@ import org.apache.uima.cas.impl.CASImpl;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.cas.FSArray;
+import org.apache.uima.jcas.cas.TOP;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
@@ -389,49 +391,93 @@ public class JCasClassLoaderTest {
@Test
public void thatFSArraySpliteratorReturnsProperJCasWrapper() throws Exception {
- ClassLoader rootCl = getClass().getClassLoader();
+ ClassLoader rootCl = getClass().getClassLoader();
- IsolatingClassloader clForCas = new IsolatingClassloader("CAS", rootCl)
- .hiding("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*");
+ IsolatingClassloader clForCas = new IsolatingClassloader("CAS", rootCl)
+ .hiding("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*");
- ClassLoader clForCreators = new IsolatingClassloader("Creators", rootCl)
- .hiding("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*")
- .redefining("^.*AddATokenAnnotatorNoJCas$")
- .redefining("^.*AddTokenToArrayAnnotatorNoJCas$");
+ ClassLoader clForCreators = new IsolatingClassloader("Creators", rootCl)
+ .hiding("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*")
+ .redefining("^.*AddATokenAnnotatorNoJCas$")
+ .redefining("^.*AddTokenToArrayAnnotatorNoJCas$");
- ClassLoader clForAccessors = new IsolatingClassloader("Accessors", rootCl)
- .redefining("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*")
- .redefining("^.*FetchTokenFromArrayViaSpliteratorAnnotator$");
+ ClassLoader clForAccessors = new IsolatingClassloader("Accessors", rootCl)
+ .redefining("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*")
+ .redefining("^.*FetchTokenFromArrayViaSpliteratorAnnotator$");
- TypeSystemDescription tsd = mergeTypeSystems(
- asList(loadTokensAndSentencesTS(), makeArrayTestTS()));
-
- JCas jcas = makeJCas(clForCas, tsd);
- AnalysisEngine addATokenAnnotator = makeAnalysisEngine(AddATokenAnnotatorNoJCas.class,
- clForCreators);
- AnalysisEngine addTokenToArrayAnnotator = makeAnalysisEngine(AddTokenToArrayAnnotatorNoJCas.class,
- clForCreators);
- AnalysisEngine fetchTokenFromArrayViaSpliteratorAnnotator = makeAnalysisEngine(
- FetchTokenFromArrayViaSpliteratorAnnotator.class, clForAccessors);
-
- jcas.setDocumentText("test");
-
- addATokenAnnotator.process(jcas);
- addTokenToArrayAnnotator.process(jcas);
- fetchTokenFromArrayViaSpliteratorAnnotator.process(jcas);
-
- try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
- softly.assertThat(casTokenClassViaClassloader).isNull();
- softly.assertThat(casTokenClassViaCas).isSameAs(Annotation.class);
- softly.assertThat(addTokenAETokenClass).isNotNull();
- softly.assertThat(casTokenClassViaClassloader)
- .as("JCas and AddTokenAnnotator use different Token wrappers")
- .isNotEqualTo(addTokenAETokenClass);
- softly.assertThat(tokenClassFetchedFromArray.getName())
- .as("Array spliterator returns proper Token wrapper")
- .isEqualTo(TYPE_NAME_TOKEN);
- }
+ TypeSystemDescription tsd = mergeTypeSystems(
+ asList(loadTokensAndSentencesTS(), makeArrayTestTS()));
+
+ JCas jcas = makeJCas(clForCas, tsd);
+ AnalysisEngine addATokenAnnotator = makeAnalysisEngine(AddATokenAnnotatorNoJCas.class,
+ clForCreators);
+ AnalysisEngine addTokenToArrayAnnotator = makeAnalysisEngine(
+ AddTokenToArrayAnnotatorNoJCas.class, clForCreators);
+ AnalysisEngine fetchTokenFromArrayViaSpliteratorAnnotator = makeAnalysisEngine(
+ FetchTokenFromArrayViaSpliteratorAnnotator.class, clForAccessors);
+
+ jcas.setDocumentText("test");
+
+ addATokenAnnotator.process(jcas);
+ addTokenToArrayAnnotator.process(jcas);
+ fetchTokenFromArrayViaSpliteratorAnnotator.process(jcas);
+
+ try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
+ softly.assertThat(casTokenClassViaClassloader).isNull();
+ softly.assertThat(casTokenClassViaCas).isSameAs(Annotation.class);
+ softly.assertThat(addTokenAETokenClass).isNotNull();
+ softly.assertThat(casTokenClassViaClassloader)
+ .as("JCas and AddTokenAnnotator use different Token wrappers")
+ .isNotEqualTo(addTokenAETokenClass);
+ softly.assertThat(tokenClassFetchedFromArray.getName())
+ .as("FSArray spliterator returns proper Token wrapper").isEqualTo(TYPE_NAME_TOKEN);
+ }
+ }
+
+ @Test
+ public void thatFSArrayToArrayReturnsProperJCasWrapper() throws Exception {
+ ClassLoader rootCl = getClass().getClassLoader();
+
+ IsolatingClassloader clForCas = new IsolatingClassloader("CAS", rootCl)
+ .hiding("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*");
+
+ ClassLoader clForCreators = new IsolatingClassloader("Creators", rootCl)
+ .hiding("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*")
+ .redefining("^.*AddATokenAnnotatorNoJCas$")
+ .redefining("^.*AddTokenToArrayAnnotatorNoJCas$");
+
+ ClassLoader clForAccessors = new IsolatingClassloader("Accessors", rootCl)
+ .redefining("org\\.apache\\.uima\\.cas\\.test\\.Token(_Type)?.*")
+ .redefining("^.*FetchTokenFromArrayViaToArrayAnnotator$");
+
+ TypeSystemDescription tsd = mergeTypeSystems(
+ asList(loadTokensAndSentencesTS(), makeArrayTestTS()));
+
+ JCas jcas = makeJCas(clForCas, tsd);
+ AnalysisEngine addATokenAnnotator = makeAnalysisEngine(AddATokenAnnotatorNoJCas.class,
+ clForCreators);
+ AnalysisEngine addTokenToArrayAnnotator = makeAnalysisEngine(
+ AddTokenToArrayAnnotatorNoJCas.class, clForCreators);
+ AnalysisEngine fetchTokenFromArrayViaSpliteratorAnnotator = makeAnalysisEngine(
+ FetchTokenFromArrayViaToArrayAnnotator.class, clForAccessors);
+
+ jcas.setDocumentText("test");
+
+ addATokenAnnotator.process(jcas);
+ addTokenToArrayAnnotator.process(jcas);
+ fetchTokenFromArrayViaSpliteratorAnnotator.process(jcas);
+
+ try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
+ softly.assertThat(casTokenClassViaClassloader).isNull();
+ softly.assertThat(casTokenClassViaCas).isSameAs(Annotation.class);
+ softly.assertThat(addTokenAETokenClass).isNotNull();
+ softly.assertThat(casTokenClassViaClassloader)
+ .as("JCas and AddTokenAnnotator use different Token wrappers")
+ .isNotEqualTo(addTokenAETokenClass);
+ softly.assertThat(tokenClassFetchedFromArray.getName())
+ .as("FSArray toArray returns proper Token wrapper").isEqualTo(TYPE_NAME_TOKEN);
}
+ }
public static Class<?> loadTokenClass(ClassLoader cl)
{
@@ -446,7 +492,8 @@ public class JCasClassLoaderTest {
public static void printTokenClassLoaderInfo(String context, ClassLoader cl) {
Class<?> clazz = loadTokenClass(cl);
if (clazz != null) {
- System.out.printf("[%s] %s %d %n", context, clazz.getName(), clazz.hashCode());
+ System.out.printf("[%s] %s %d loaded by %s%n", context, clazz.getName(), clazz.hashCode(),
+ clazz.getClassLoader());
} else {
System.out.printf("[%s] %s NOT AVAILABLE %n", context, Token.class.getName());
}
@@ -605,6 +652,21 @@ public class JCasClassLoaderTest {
}
}
+ public static class FetchTokenFromArrayViaToArrayAnnotator extends JCasAnnotator_ImplBase {
+ @Override
+ public void process(JCas aJCas) throws AnalysisEngineProcessException {
+ FeatureStructure arrayHost = aJCas.select(aJCas.getTypeSystem().getType(TYPE_NAME_ARRAY_HOST))
+ .single();
+
+ FSArray array = (FSArray) arrayHost.getFeatureValue(
+ arrayHost.getType().getFeatureByBaseName(FEAT_NAME_ARRAY_HOST_VALUES));
+
+ Class withEmptyTemplate = array.toArray(new TOP[0])[0].getClass();
+ tokenClassFetchedFromArray = array.toArray(new TOP[1])[0].getClass();
+ assertThat(tokenClassFetchedFromArray).isSameAs(withEmptyTemplate);
+ }
+ }
+
public static class FetchTheTokenAnnotator extends JCasAnnotator_ImplBase {
@Override
public void process(JCas aJCas) throws AnalysisEngineProcessException {