Merge pull request #122 from apache/UIMA-6270-Add-selectOverlapping-to-JCasUtil
[UIMA-6270] Add selectOverlapping to (J)CasUtil
diff --git a/Jenkinsfile b/Jenkinsfile
index f7c905b..5bd0abc 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -16,7 +16,10 @@
// under the License.
pipeline {
- agent any
+ agent {
+ label '!Windows'
+ }
+
tools {
maven 'Maven (latest)'
jdk 'JDK 1.8 (latest)'
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
index a8fa976..10827f4 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
@@ -30,6 +30,7 @@
import org.apache.uima.fit.descriptor.FsIndex;
import org.apache.uima.fit.descriptor.FsIndexKey;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
import org.apache.uima.fit.internal.MetaDataType;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.metadata.FsIndexCollection;
@@ -44,13 +45,12 @@
import org.apache.uima.util.XMLInputSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.util.ClassUtils;
/**
*/
public final class FsIndexFactory {
- private static Logger LOG = LoggerFactory.getLogger(FsIndexFactory.class);
-
+ private static Logger LOG = LoggerFactory.getLogger(FsIndexFactory.class);
+
/**
* Comparator that orders FeatureStructures according to the standard order of their key features.
* For integer and float values, this is the standard linear order, and for strings it is
@@ -262,7 +262,7 @@
* if the index collection could not be assembled
*/
public static FsIndexCollection createFsIndexCollection() throws ResourceInitializationException {
- ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ ClassLoader cl = ClassLoaderUtils.findClassloader();
FsIndexCollection aggFsIdxCol = fsIndexCollectionsByClassloader.get(cl);
if (aggFsIdxCol == null) {
synchronized (CREATE_LOCK) {
@@ -301,7 +301,7 @@
*/
public static String[] scanIndexDescriptors() throws ResourceInitializationException {
synchronized (SCAN_LOCK) {
- ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ ClassLoader cl = ClassLoaderUtils.findClassloader();
String[] indexLocations = fsIndexLocationsByClassloader.get(cl);
if (indexLocations == null) {
indexLocations = scanDescriptors(MetaDataType.FS_INDEX);
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
index 2073441..4c83f45 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.WeakHashMap;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
import org.apache.uima.fit.internal.MetaDataType;
import org.apache.uima.fit.internal.ResourceManagerFactory;
import org.apache.uima.jcas.cas.TOP;
@@ -40,11 +41,10 @@
import org.apache.uima.util.XMLInputSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.util.ClassUtils;
public final class TypePrioritiesFactory {
private static final Logger LOG = LoggerFactory.getLogger(TypePrioritiesFactory.class);
-
+
private static final Object SCAN_LOCK = new Object();
private static final Object CREATE_LOCK = new Object();
@@ -76,7 +76,7 @@
if (!TOP.class.isAssignableFrom(prioritizedTypes[i])) {
throw new IllegalArgumentException("[" + prioritizedTypes[i] + "] is not a JCas type");
}
-
+
String typeName = prioritizedTypes[i].getName();
if (typeName.startsWith(UIMA_BUILTIN_JCAS_PREFIX)) {
typeName = "uima." + typeName.substring(UIMA_BUILTIN_JCAS_PREFIX.length());
@@ -114,7 +114,7 @@
* if the collected type priorities cannot be merged.
*/
public static TypePriorities createTypePriorities() throws ResourceInitializationException {
- ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ ClassLoader cl = ClassLoaderUtils.findClassloader();
TypePriorities aggTypePriorities = typePrioritiesByClassloader.get(cl);
if (aggTypePriorities == null) {
synchronized (CREATE_LOCK) {
@@ -153,7 +153,7 @@
*/
public static String[] scanTypePrioritiesDescriptors() throws ResourceInitializationException {
synchronized (SCAN_LOCK) {
- ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ ClassLoader cl = ClassLoaderUtils.findClassloader();
String[] typePrioritesLocations = typePrioritesLocationsByClassloader.get(cl);
if (typePrioritesLocations == null) {
typePrioritesLocations = scanDescriptors(MetaDataType.TYPE_PRIORITIES);
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
index dc05a40..0c1af58 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.WeakHashMap;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
import org.apache.uima.fit.internal.MetaDataType;
import org.apache.uima.fit.internal.ResourceManagerFactory;
import org.apache.uima.resource.ResourceInitializationException;
@@ -39,11 +40,10 @@
import org.apache.uima.util.XMLInputSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.util.ClassUtils;
public final class TypeSystemDescriptionFactory {
private static final Logger LOG = LoggerFactory.getLogger(TypeSystemDescriptionFactory.class);
-
+
private static final Object SCAN_LOCK = new Object();
private static final Object CREATE_LOCK = new Object();
@@ -113,7 +113,7 @@
*/
public static TypeSystemDescription createTypeSystemDescription()
throws ResourceInitializationException {
- ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ ClassLoader cl = ClassLoaderUtils.findClassloader();
TypeSystemDescription tsd = typeDescriptorByClassloader.get(cl);
if (tsd == null) {
synchronized (CREATE_LOCK) {
@@ -149,7 +149,7 @@
*/
public static String[] scanTypeDescriptors() throws ResourceInitializationException {
synchronized (SCAN_LOCK) {
- ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ ClassLoader cl = ClassLoaderUtils.findClassloader();
String[] typeDescriptorLocations = typeDescriptorLocationsByClassloader.get(cl);
if (typeDescriptorLocations == null) {
typeDescriptorLocations = scanDescriptors(MetaDataType.TYPE_SYSTEM);
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.java
index e0c54e6..535782d 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.java
@@ -6,9 +6,9 @@
* 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
@@ -19,11 +19,12 @@
package org.apache.uima.fit.factory.initializable;
import org.apache.uima.UimaContext;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
import org.apache.uima.resource.ResourceInitializationException;
/**
* Please see {@link Initializable} for a description of how this class is intended to be used.
- *
+ *
* @see Initializable
*/
public final class InitializableFactory {
@@ -35,7 +36,7 @@
* Provides a way to create an instance of T. If the class specified by className implements
* {@link Initializable}, then the UimaContext provided here will be passed to its initialize
* method.
- *
+ *
* @param <T>
* the interface type
* @param context
@@ -50,7 +51,14 @@
*/
public static <T> T create(UimaContext context, String className, Class<T> superClass)
throws ResourceInitializationException {
- Class<? extends T> cls = getClass(className, superClass);
+ Class<? extends T> cls;
+ try {
+ ClassLoader cl = ClassLoaderUtils.findClassloader(context);
+ cls = Class.forName(className, true, cl).asSubclass(superClass);
+ } catch (Exception e) {
+ throw new ResourceInitializationException(new IllegalStateException("classname = "
+ + className + " superClass = " + superClass.getName(), e));
+ }
return create(context, cls);
}
@@ -68,7 +76,8 @@
public static <T> Class<? extends T> getClass(String className, Class<T> superClass)
throws ResourceInitializationException {
try {
- return Class.forName(className).asSubclass(superClass);
+ ClassLoader cl = ClassLoaderUtils.findClassloader();
+ return Class.forName(className, true, cl).asSubclass(superClass);
} catch (Exception e) {
throw new ResourceInitializationException(new IllegalStateException("classname = "
+ className + " superClass = " + superClass.getName(), e));
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/internal/ClassLoaderUtils.java b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ClassLoaderUtils.java
new file mode 100644
index 0000000..f498264
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ClassLoaderUtils.java
@@ -0,0 +1,123 @@
+/*
+ * 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.internal;
+
+import org.apache.uima.UimaContext;
+import org.apache.uima.UimaContextAdmin;
+import org.apache.uima.UimaContextHolder;
+import org.apache.uima.resource.ResourceManager;
+import org.springframework.util.ClassUtils;
+
+/**
+ * INTERNAL API - Helper functions to obtain a suitable classloader.
+ */
+public final class ClassLoaderUtils {
+ private ClassLoaderUtils() {
+ // No instances
+ }
+
+ /**
+ * Looks up a suitable classloader in the following order:
+ * <ol>
+ * <li>The {@link UimaContext} in the {@link UimaContextHolder} of the current thread(if any)</li>
+ * <li>The current thread-context classloader (if any)</li>
+ * <li>The classloader through which uimaFIT (i.e. this class) was loaded.</li>
+ * <li>For backwards compatibility then delegates to {@link ClassUtils#getDefaultClassLoader()}</li>
+ * </ol>
+ *
+ * @return a classloader or {@code null} if no suitable classloader could be found.
+ */
+ public static ClassLoader findClassloader() {
+ ClassLoader uimaThreadContextClassLoader = getExtensionClassloader(
+ UimaContextHolder.getContext());
+ if (uimaThreadContextClassLoader != null) {
+ return uimaThreadContextClassLoader;
+ }
+
+ ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ if (contextClassLoader != null) {
+ return contextClassLoader;
+ }
+
+ ClassLoader uimaFITClassLoader = ClassLoaderUtils.class.getClassLoader();
+ if (uimaFITClassLoader != null) {
+ return uimaFITClassLoader;
+ }
+
+ return ClassUtils.getDefaultClassLoader();
+ }
+
+ /**
+ * Looks up a suitable classloader in the following order:
+ * <ol>
+ * <li>The extension classloader of the given {@link ResourceManager}</li>
+ * <li>See {@link #findClassloader()}</li>
+ * </ol>
+ *
+ * @return a classloader or {@code null} if no suitable classloader could be found.
+ */
+ public static ClassLoader findClassloader(ResourceManager aResMgr) {
+ ClassLoader resourceManagerExtensionClassloader = getExtensionClassloader(aResMgr);
+ if (resourceManagerExtensionClassloader != null) {
+ return resourceManagerExtensionClassloader;
+ }
+
+ return findClassloader();
+ }
+
+ /**
+ * Looks up a suitable classloader in the following order:
+ * <ol>
+ * <li>The extension classloader of the {@link ResourceManager} associated with the given
+ * {@link UimaContext} (if any)</li>
+ * <li>See {@link #findClassloader(ResourceManager)}</li>
+ * </ol>
+ *
+ * @return a classloader or {@code null} if no suitable classloader could be found.
+ */
+ public static ClassLoader findClassloader(UimaContext aContext) {
+ ClassLoader uimaContextExtensionClassloader = getExtensionClassloader(aContext);
+ if (uimaContextExtensionClassloader != null) {
+ return uimaContextExtensionClassloader;
+ }
+
+ return findClassloader((ResourceManager) null);
+ }
+
+ private static ClassLoader getExtensionClassloader(UimaContext aContext) {
+ if (aContext instanceof UimaContextAdmin) {
+ return getExtensionClassloader(((UimaContextAdmin) aContext).getResourceManager());
+ }
+
+ return null;
+ }
+
+ private static ClassLoader getExtensionClassloader(ResourceManager aResMgr) {
+ if (aResMgr == null) {
+ return null;
+ }
+
+ ClassLoader cl = aResMgr.getExtensionClassLoader();
+ if (cl != null) {
+ return aResMgr.getExtensionClassLoader();
+ }
+
+ return null;
+ }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.java
index 656e4bb..11e1f59 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.java
@@ -6,9 +6,9 @@
* 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
@@ -18,8 +18,6 @@
*/
package org.apache.uima.fit.internal;
-import java.net.MalformedURLException;
-
import org.apache.uima.UIMAFramework;
import org.apache.uima.UimaContext;
import org.apache.uima.UimaContextAdmin;
@@ -28,25 +26,23 @@
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.impl.ResourceManager_impl;
-import org.springframework.util.ClassUtils;
/**
* INTERNAL API - Helper functions for dealing with resource managers and classloading
- *
- * This API is experimental and is very likely to be removed or changed in future versions.
+ *
+ * This API is experimental and is very likely to be removed or changed in future versions.
*/
public class ResourceManagerFactory {
private static ResourceManagerCreator resourceManagerCreator = new DefaultResourceManagerCreator();
-
+
private ResourceManagerFactory() {
// No instances
}
- public static ResourceManager newResourceManager() throws ResourceInitializationException
- {
+ public static ResourceManager newResourceManager() throws ResourceInitializationException {
return resourceManagerCreator.newResourceManager();
}
-
+
/**
* Mind that returning a singleton resource manager from {@link ResourceManagerFactory} is
* generally a bad idea because it gets destroyed on a regular basis. For this reason, it is
@@ -57,15 +53,15 @@
ResourceManagerCreator resourceManagerCreator) {
ResourceManagerFactory.resourceManagerCreator = resourceManagerCreator;
}
-
+
public static ResourceManagerCreator getResourceManagerCreator() {
return resourceManagerCreator;
}
-
- public static interface ResourceManagerCreator {
+
+ public interface ResourceManagerCreator {
ResourceManager newResourceManager() throws ResourceInitializationException;
}
-
+
public static class DefaultResourceManagerCreator implements ResourceManagerCreator {
@Override
public ResourceManager newResourceManager() throws ResourceInitializationException {
@@ -77,41 +73,34 @@
// See https://issues.apache.org/jira/browse/UIMA-5056
return ((UimaContextAdmin) activeContext).getResourceManager();
}
- else {
- // If there is no UIMA context, then we create a new resource manager
- // UIMA core still does not fall back to the context classloader in all cases.
- // This was the default behavior until uimaFIT 2.2.0.
- ResourceManager resMgr;
- if (Thread.currentThread().getContextClassLoader() != null) {
- // If the context classloader is set, then we want the resource manager to fallb
- // back to it. However, it may not reliably do that that unless we explictly pass
- // null here. See. UIMA-6239.
- resMgr = new ResourceManager_impl(null);
- }
- else {
- resMgr = UIMAFramework.newDefaultResourceManager();
- }
-
- // Since UIMA Core version 2.10.3 and 3.0.1 the thread context classloader is taken
- // into account by the core framework. Thus, we no longer have to explicitly set a
- // classloader these or more recent versions. (cf. UIMA-5802)
- short maj = UimaVersion.getMajorVersion();
- short min = UimaVersion.getMinorVersion();
- short rev = UimaVersion.getBuildRevision();
- boolean uimaCoreIgnoresContextClassloader =
- (maj == 2 && (min < 10 || (min == 10 && rev < 3))) || // version < 2.10.3
- (maj == 3 && ((min == 0 && rev < 1))); // version < 3.0.1
- if (uimaCoreIgnoresContextClassloader) {
- try {
- resMgr.setExtensionClassPath(ClassUtils.getDefaultClassLoader(), "", true);
- }
- catch (MalformedURLException e) {
- throw new ResourceInitializationException(e);
- }
- }
-
- return resMgr;
+
+ // If there is no UIMA context, then we create a new resource manager
+ // UIMA core still does not fall back to the context classloader in all cases.
+ // This was the default behavior until uimaFIT 2.2.0.
+ ResourceManager resMgr;
+ if (Thread.currentThread().getContextClassLoader() != null) {
+ // If the context classloader is set, then we want the resource manager to fallb
+ // back to it. However, it may not reliably do that that unless we explictly pass
+ // null here. See. UIMA-6239.
+ resMgr = new ResourceManager_impl(null);
+ } else {
+ resMgr = UIMAFramework.newDefaultResourceManager();
}
+
+ // Since UIMA Core version 2.10.3 and 3.0.1 the thread context classloader is taken
+ // into account by the core framework. Thus, we no longer have to explicitly set a
+ // classloader these or more recent versions. (cf. UIMA-5802)
+ short maj = UimaVersion.getMajorVersion();
+ short min = UimaVersion.getMinorVersion();
+ short rev = UimaVersion.getBuildRevision();
+ boolean uimaCoreIgnoresContextClassloader =
+ (maj == 2 && (min < 10 || (min == 10 && rev < 3))) || // version < 2.10.3
+ (maj == 3 && ((min == 0 && rev < 1))); // version < 3.0.1
+ if (uimaCoreIgnoresContextClassloader) {
+ resMgr.setExtensionClassLoader(ClassLoaderUtils.findClassloader(), true);
+ }
+
+ return resMgr;
}
}
}