You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2014/04/04 15:50:02 UTC
svn commit: r1584687 - in
/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource: ./
impl/ metadata/impl/
Author: schor
Date: Fri Apr 4 13:50:02 2014
New Revision: 1584687
URL: http://svn.apache.org/r1584687
Log:
[UIMA-3693][UIMA-3694] skip unneeded work, synch resolve imports, make resource manager and configuration manager fields final (preferable) or volatile
Modified:
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/Resource_ImplBase.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ConfigurationManagerImplBase.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManagerPearWrapper_impl.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/FsIndexCollection_impl.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/ResourceManagerConfiguration_impl.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorities_impl.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorityList_impl.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_impl.java
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/Resource_ImplBase.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/Resource_ImplBase.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/Resource_ImplBase.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/Resource_ImplBase.java Fri Apr 4 13:50:02 2014
@@ -60,17 +60,16 @@ public abstract class Resource_ImplBase
/**
* @see org.apache.uima.resource.Resource#initialize(org.apache.uima.resource.ResourceSpecifier,
* java.util.Map)
+ *
+ * multi-thread safe, given that each instance of this class is only called on one thread, once.
+ * The critical parts that update shared information (in shared uima context) are inside a synchronize block
*/
public boolean initialize(ResourceSpecifier aSpecifier, Map<String, Object> aAdditionalParams)
throws ResourceInitializationException {
// get name of resource, to be used in error messages
- String name;
- if (getMetaData() != null) {
- name = getMetaData().getName();
- } else {
- name = getClass().getName();
- }
+ final ResourceMetaData metadata1 = getMetaData();
+ String name = (metadata1 == null) ? getClass().getName() : metadata1.getName();
// check for repeat initialization
if (mInitialized) {
@@ -79,11 +78,11 @@ public abstract class Resource_ImplBase
}
// is there a UIMAContext provided in the aAdditionalParams map?
+ // if so, use it - it could be a shared context for scale-up of the same resource
if (aAdditionalParams != null) {
mUimaContextAdmin = (UimaContextAdmin) aAdditionalParams.get(PARAM_UIMA_CONTEXT);
}
- if (mUimaContextAdmin == null) // no, we have to create one
- {
+ if (mUimaContextAdmin == null) {// no, we have to create one
// get or create ResourceManager
ResourceManager resMgr = null;
if (aAdditionalParams != null) {
@@ -126,6 +125,7 @@ public abstract class Resource_ImplBase
ResourceMetaData metadata = ((ResourceCreationSpecifier) aSpecifier).getMetaData();
name = metadata.getName();
try {
+ // the resolveImports method has synch block around updates to the metadata
metadata.resolveImports(getResourceManager());
} catch (InvalidXMLException e) {
throw new ResourceInitializationException(e);
@@ -141,20 +141,24 @@ public abstract class Resource_ImplBase
if (externalOverrides != null) {
mUimaContextAdmin.setExternalOverrides(externalOverrides);
} else {
- if (mUimaContextAdmin.getExternalOverrides() == null) {
- externalOverrides = new Settings_impl();
- try {
- externalOverrides.loadSystemDefaults();
- } catch (ResourceConfigurationException e) {
- throw new ResourceInitializationException(ResourceInitializationException.ERROR_INITIALIZING_FROM_DESCRIPTOR,
- new Object[] { name, metadata.getSourceUrlString() }, e);
+ // synch around test/set of the (possibly shared) uima-context info about external param overrides
+ synchronized(mUimaContextAdmin) {
+ if (mUimaContextAdmin.getExternalOverrides() == null) {
+ externalOverrides = new Settings_impl();
+ try {
+ externalOverrides.loadSystemDefaults();
+ } catch (ResourceConfigurationException e) {
+ throw new ResourceInitializationException(ResourceInitializationException.ERROR_INITIALIZING_FROM_DESCRIPTOR,
+ new Object[] { name, metadata.getSourceUrlString() }, e);
+ }
+ mUimaContextAdmin.setExternalOverrides(externalOverrides);
}
- mUimaContextAdmin.setExternalOverrides(externalOverrides);
}
}
// initialize configuration
try {
+ // createContext checks and skips repeated calls with same args (on different threads, for example)
mUimaContextAdmin.getConfigurationManager().createContext(
mUimaContextAdmin.getQualifiedContextName(), getMetaData(), mUimaContextAdmin.getExternalOverrides());
mUimaContextAdmin.getConfigurationManager().setSession(mUimaContextAdmin.getSession());
@@ -179,6 +183,7 @@ public abstract class Resource_ImplBase
if (!aAdditionalParams.containsKey(PARAM_RESOURCE_MANAGER)) {
aAdditionalParams.put(PARAM_RESOURCE_MANAGER, mUimaContextAdmin.getResourceManager());
}
+ // initializeExternalResources is synchronized
mUimaContextAdmin.getResourceManager().initializeExternalResources(resMgrCfg,
mUimaContextAdmin.getQualifiedContextName(), aAdditionalParams);
}
@@ -187,6 +192,7 @@ public abstract class Resource_ImplBase
ExternalResourceDependency[] resourceDependencies = ((ResourceCreationSpecifier) aSpecifier)
.getExternalResourceDependencies();
if (resourceDependencies != null) {
+ // resolveAndValidateResourceDependencies is synchronized
mUimaContextAdmin.getResourceManager().resolveAndValidateResourceDependencies(
resourceDependencies, mUimaContextAdmin.getQualifiedContextName());
}
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ConfigurationManagerImplBase.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ConfigurationManagerImplBase.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ConfigurationManagerImplBase.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ConfigurationManagerImplBase.java Fri Apr 4 13:50:02 2014
@@ -63,30 +63,42 @@ public abstract class ConfigurationManag
/**
* Map from context name to ConfigurationParameterDeclarations for that context.
+ * Not sync'd based on belief:
+ * setup of values must be complete before any reference occurs, even in multi-threaded context.
+ * The setup is done under a sync'd control to insure only one setup is done, and to
+ * publish the updated results to other threads
*/
- private Map<String, ConfigurationParameterDeclarations> mContextNameToParamDeclsMap = new HashMap<String, ConfigurationParameterDeclarations>();
+ final private Map<String, ConfigurationParameterDeclarations> mContextNameToParamDeclsMap =
+ new HashMap<String, ConfigurationParameterDeclarations>();
/**
* Map the fully-qualified name of a parameter to the fully-qualified name of the parameter it is
* linked to (from which it takes its value).
+ * Not sync'd based on belief:
+ * setup of values must be complete before any reference occurs, even in multi-threaded context.
+ * The setup is done under a sync'd control to insure only one setup is done
+ *
*/
- protected Map<String, String> mLinkMap = new HashMap<String, String>();
+ final protected Map<String, String> mLinkMap = new HashMap<String, String>();
/**
* Set of parameters (fully qualified names) that explicitly declare overrides. This is used to
* prevent implicit (name-based) overrides for these parameters.
*/
- private Set<String> mExplicitlyOverridingParameters = new HashSet<String>();
+// final private Set<String> mExplicitlyOverridingParameters = new HashSet<String>();
/**
- * Current session. Used to store parmater overrides.
+ * Current session. Used to store parameter settings done by the
+ * settings via API tae.setConfigParameterValue(...)
+ *
+ * can be set by multiple threads, but ought to be set to the same session object
*/
- private Session mSession = null;
+ private volatile Session mSession = null;
- /**
- * Holds the externalOverrideSettings from the top-level Analysis Engine
- */
- protected OperationalProperties mOperationalProperties = null;
+// /**
+// * Holds the externalOverrideSettings from the top-level Analysis Engine
+// */
+// protected OperationalProperties mOperationalProperties = null;
/*
* (non-Javadoc)
@@ -96,15 +108,20 @@ public abstract class ConfigurationManag
public void setSession(Session aSession) {
mSession = aSession;
}
-
+
/*
* (non-Javadoc)
*
* @see org.apache.uima.resource.ConfigurationManager#createContext(java.lang.String,
* org.apache.uima.resource.metadata.ResourceMetaData)
+ *
+ * Could be called multiple times on different threads - first one does the context creation
*/
- public void createContext(String aContextName, ResourceMetaData aResourceMetaData, Settings externalOverrides)
+ public synchronized void createContext(String aContextName, ResourceMetaData aResourceMetaData, Settings externalOverrides)
throws ResourceConfigurationException {
+ if (mContextNameToParamDeclsMap.containsKey(aContextName)) {
+ return;
+ }
// first internally validate settings in the ResourceMetaData (catches data type problems,
// settings for undefined parameters, etc.)
aResourceMetaData.validateConfigurationParameterSettings();
@@ -151,6 +168,8 @@ public abstract class ConfigurationManag
// validate
validateConfigurationParameterSettings(aContextName);
}
+
+
/*
* (non-Javadoc)
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManagerPearWrapper_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManagerPearWrapper_impl.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManagerPearWrapper_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManagerPearWrapper_impl.java Fri Apr 4 13:50:02 2014
@@ -21,6 +21,7 @@ package org.apache.uima.resource.impl;
import java.net.MalformedURLException;
+import org.apache.uima.analysis_engine.impl.PearAnalysisEngineWrapper;
import org.apache.uima.internal.util.UIMAClassLoader;
import org.apache.uima.resource.RelativePathResolver;
import org.apache.uima.resource.ResourceManager;
@@ -41,27 +42,42 @@ public class ResourceManagerPearWrapper_
* UIMA extension ClassLoader. ClassLoader is created if an extension classpath is specified at
* the ResourceManager
*/
- private UIMAClassLoader uimaCL = null;
-
+ private volatile UIMAClassLoader uimaCL = null;
+
/**
* Object used for resolving relative paths. This is built by parsing the data path.
*/
- private RelativePathResolver mRelativePathResolver;
+ private final RelativePathResolver mRelativePathResolver = new RelativePathResolver_impl();
+ public ResourceManagerPearWrapper_impl() {
+ super(
+ PearAnalysisEngineWrapper.newPearsParent.get().mResourceMap,
+ PearAnalysisEngineWrapper.newPearsParent.get().mInternalResourceRegistrationMap,
+ PearAnalysisEngineWrapper.newPearsParent.get().mParameterizedResourceImplClassMap,
+ PearAnalysisEngineWrapper.newPearsParent.get().mInternalParameterizedResourceImplClassMap,
+ PearAnalysisEngineWrapper.newPearsParent.get().mParameterizedResourceInstanceMap);
+// ResourceManager_impl r = PearAnalysisEngineWrapper.newPearsParent.get();
+// mResourceMap = r.mResourceMap;
+// mInternalResourceRegistrationMap = r.mInternalResourceRegistrationMap;
+// mParameterizedResourceImplClassMap = r.mParameterizedResourceImplClassMap;
+// mInternalParameterizedResourceImplClassMap = r.mInternalParameterizedResourceImplClassMap;
+// mParameterizedResourceInstanceMap = r.mParameterizedResourceInstanceMap;
+ mCasManager = PearAnalysisEngineWrapper.newPearsParent.get().getCasManager();
+ }
/**
* Initializes from the parent, a new <code>ResourceManagerForPearWrapper_impl</code>.
*/
+ @Deprecated
public void initializeFromParentResourceManager(ResourceManager resourceManager) {
- ResourceManager_impl r = (ResourceManager_impl) resourceManager;
- mRelativePathResolver = new RelativePathResolver_impl();
- mResourceMap = r.mResourceMap;
- mInternalResourceRegistrationMap = r.mInternalResourceRegistrationMap;
- mParameterizedResourceImplClassMap = r.mParameterizedResourceImplClassMap;
- mInternalParameterizedResourceImplClassMap = r.mInternalParameterizedResourceImplClassMap;
- mParameterizedResourceInstanceMap = r.mParameterizedResourceInstanceMap;
- synchronized(this) {
- mCasManager = r.getCasManager(); // synchronized - avoid findbugs noise
- }
+// ResourceManager_impl r = (ResourceManager_impl) resourceManager;
+// mResourceMap = r.mResourceMap;
+// mInternalResourceRegistrationMap = r.mInternalResourceRegistrationMap;
+// mParameterizedResourceImplClassMap = r.mParameterizedResourceImplClassMap;
+// mInternalParameterizedResourceImplClassMap = r.mInternalParameterizedResourceImplClassMap;
+// mParameterizedResourceInstanceMap = r.mParameterizedResourceInstanceMap;
+// synchronized(this) {
+// mCasManager = r.getCasManager(); // synchronized - avoid findbugs noise
+// }
}
/**
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java Fri Apr 4 13:50:02 2014
@@ -76,43 +76,43 @@ public class ResourceManager_impl implem
/**
* Map from qualified key names (declared in resource dependency XML) to Resource objects.
+ *
+ * Can't be concurrentMap because it (currently) depends on storing nulls
*/
- protected Map<String, Object> mResourceMap = new ConcurrentHashMap<String, Object>();
-
+ final protected Map<String, Object> mResourceMap;
+
/**
* Internal map from resource names (declared in resource declaration XML) to ResourceRegistration
* objects. Used during initialization only.
*/
- protected Map<String, ResourceRegistration> mInternalResourceRegistrationMap =
- new ConcurrentHashMap<String, ResourceRegistration>();
+ final protected Map<String, ResourceRegistration> mInternalResourceRegistrationMap;
/**
* Map from String keys to Class objects. For ParameterizedResources only, stores the
* implementation class corresponding to each resource name.
*/
- protected Map<String, Class<?>> mParameterizedResourceImplClassMap =
- new ConcurrentHashMap<String, Class<?>>();
+ final protected Map<String, Class<?>> mParameterizedResourceImplClassMap;
/**
* Internal map from resource names (declared in resource declaration XML) to Class objects. Used
* internally during resource initialization.
*/
- protected Map<String, Class<?>> mInternalParameterizedResourceImplClassMap =
- new ConcurrentHashMap<String, Class<?>>();
+ final protected Map<String, Class<?>> mInternalParameterizedResourceImplClassMap;
/**
* Map from ParameterizedResourceKey to Resource objects. For
* ParameterizedResources only, stores the DataResources that have already been encountered, and
* the Resources that have been instantiated therefrom.
*/
- protected Map<List<Object>, Object> mParameterizedResourceInstanceMap =
- new ConcurrentHashMap<List<Object>, Object>();
+ final protected Map<List<Object>, Object> mParameterizedResourceInstanceMap;
/**
* UIMA extension ClassLoader. ClassLoader is created if an extension classpath is specified at
* the ResourceManager
+ *
+ * volatile might be better than synch sets/gets
*/
- private UIMAClassLoader uimaCL = null;
+ private volatile UIMAClassLoader uimaCL = null;
/** CasManager - manages creation and pooling of CASes. */
// volatile to support double-checked locking idiom
@@ -136,13 +136,23 @@ public class ResourceManager_impl implem
* simultaneously is not.
*/
// leaving this as a synchronizedMap - for backwards compatibility
- private Map<String,XMLizable> importCache = Collections.synchronizedMap(new HashMap<String,XMLizable>());
+ // internal users do sync around get/set pairs anyways, but can't rely on
+ // what external users do
+ // Because internal users do a sync, only one thread at a time is using this
+ // (for internal calls) anyways, so there's no advantage to the extra overhead
+ // of making this a ConcurrentHashMap (March 2014)
+ final private Map<String,XMLizable> importCache = Collections.synchronizedMap(new HashMap<String,XMLizable>());
/**
* Creates a new <code>ResourceManager_impl</code>.
*/
public ResourceManager_impl() {
- mRelativePathResolver = new RelativePathResolver_impl();
+ mResourceMap = Collections.synchronizedMap(new HashMap<String, Object>());
+ mInternalResourceRegistrationMap = new ConcurrentHashMap<String, ResourceRegistration>();
+ mParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
+ mInternalParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
+ mParameterizedResourceInstanceMap = new ConcurrentHashMap<List<Object>, Object>();
+ mRelativePathResolver = new RelativePathResolver_impl();
}
/**
@@ -150,9 +160,31 @@ public class ResourceManager_impl implem
* resources.
*/
public ResourceManager_impl(ClassLoader aClassLoader) {
+ mResourceMap = Collections.synchronizedMap(new HashMap<String, Object>());
+ mInternalResourceRegistrationMap = new ConcurrentHashMap<String, ResourceRegistration>();
+ mParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
+ mInternalParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
+ mParameterizedResourceInstanceMap = new ConcurrentHashMap<List<Object>, Object>();
mRelativePathResolver = new RelativePathResolver_impl(aClassLoader);
}
+ /*
+ * Version for Pear wrapper
+ */
+ public ResourceManager_impl(
+ Map<String, Object> resourceMap,
+ Map<String, ResourceRegistration> internalResourceRegistrationMap,
+ Map<String, Class<?>> parameterizedResourceImplClassMap,
+ Map<String, Class<?>> internalParameterizedResourceImplClassMap,
+ Map<List<Object>, Object> parameterizedResourceInstanceMap) {
+ mResourceMap = resourceMap;
+ mInternalResourceRegistrationMap = internalResourceRegistrationMap;
+ mParameterizedResourceImplClassMap = parameterizedResourceImplClassMap;
+ mInternalParameterizedResourceImplClassMap = internalParameterizedResourceImplClassMap;
+ mParameterizedResourceInstanceMap = parameterizedResourceInstanceMap;
+ mRelativePathResolver = new RelativePathResolver_impl();
+ }
+
/**
* Support reusing UIMA Class Loader instances to speed up
* things including the Component Description Editor when
@@ -204,7 +236,7 @@ public class ResourceManager_impl implem
/**
* @see org.apache.uima.resource.ResourceManager#getExtensionClassLoader()
*/
- public synchronized ClassLoader getExtensionClassLoader() {
+ public ClassLoader getExtensionClassLoader() {
return uimaCL;
}
@@ -409,7 +441,7 @@ public class ResourceManager_impl implem
* @see org.apache.uima.resource.ResourceManager#initializeExternalResources(org.apache.uima.resource.metadata.ResourceManagerConfiguration,
* java.lang.String, java.util.Map)
*/
- public void initializeExternalResources(ResourceManagerConfiguration aConfiguration,
+ public synchronized void initializeExternalResources(ResourceManagerConfiguration aConfiguration,
String aQualifiedContextName, Map<String, Object> aAdditionalParams)
throws ResourceInitializationException {
// register resources
@@ -464,8 +496,11 @@ public class ResourceManager_impl implem
*
* @see org.apache.uima.resource.ResourceManager#resolveAndValidateResourceDependencies(org.apache.uima.resource.ExternalResourceDependency[],
* java.lang.String)
+ *
+ * Multi-threaded. Partial avoidance of re-resolving, but if a resource fails to resolve, it will be
+ * reattempted on every call
*/
- public void resolveAndValidateResourceDependencies(ExternalResourceDependency[] aDependencies,
+ public synchronized void resolveAndValidateResourceDependencies(ExternalResourceDependency[] aDependencies,
String aQualifiedContextName) throws ResourceInitializationException {
for (int i = 0; i < aDependencies.length; i++) {
// get resource
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/FsIndexCollection_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/FsIndexCollection_impl.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/FsIndexCollection_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/FsIndexCollection_impl.java Fri Apr 4 13:50:02 2014
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.TreeSet;
import org.apache.uima.UIMAFramework;
@@ -54,7 +55,7 @@ public class FsIndexCollection_impl exte
private String mVendor;
- private Import[] mImports;
+ private Import[] mImports = Import.EMPTY_IMPORTS;
private FsIndexDescription[] mFsIndexes = new FsIndexDescription[0];
@@ -120,10 +121,8 @@ public class FsIndexCollection_impl exte
* @see org.apache.uima.resource.metadata.TypeSystemDescription#getImports()
*/
public Import[] getImports() {
- // don't all this to return null
- if (mImports == null)
- mImports = new Import[0];
- return mImports;
+ // don't allow this to return null
+ return (mImports == null) ? Import.EMPTY_IMPORTS : mImports;
}
/*
@@ -190,55 +189,65 @@ public class FsIndexCollection_impl exte
*
* @see org.apache.uima.resource.metadata.TypeSystemDescription#resolveImports()
*/
- public void resolveImports() throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ // support multi-threading, avoid object creation if no imports
+ public synchronized void resolveImports() throws InvalidXMLException {
+ if (getImports().length == 0) {
+ resolveImports(null, null);
+ } else {
+ resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ }
}
- public void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), aResourceManager);
+ public synchronized void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
+ resolveImports((getImports().length == 0) ? null : new TreeSet<String>(), aResourceManager);
}
- public void resolveImports(Collection<String> aAlreadyImportedFsIndexURLs,
+ public synchronized void resolveImports(Collection<String> aAlreadyImportedFsIndexURLs,
ResourceManager aResourceManager) throws InvalidXMLException {
- // add our own URL, if known, to the collection of already imported URLs
- if (getSourceUrl() != null) {
- aAlreadyImportedFsIndexURLs.add(getSourceUrl().toString());
- }
-
- List<FsIndexDescription> importedIndexes = new ArrayList<FsIndexDescription>();
- Import[] imports = getImports();
- for (int i = 0; i < imports.length; i++) {
- // make sure Import's relative path base is set, to allow for users who create
- // new import objects
- if (imports[i] instanceof Import_impl) {
- ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ List<FsIndexDescription> importedIndexes = null;
+ if (getImports().length != 0) {
+ // add our own URL, if known, to the collection of already imported URLs
+ if (getSourceUrl() != null) {
+ aAlreadyImportedFsIndexURLs.add(getSourceUrl().toString());
}
-
- URL url = imports[i].findAbsoluteUrl(aResourceManager);
- if (!aAlreadyImportedFsIndexURLs.contains(url.toString())) {
- aAlreadyImportedFsIndexURLs.add(url.toString());
- try {
- resolveImport(url, aAlreadyImportedFsIndexURLs, importedIndexes, aResourceManager);
- } catch (IOException e) {
- throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
- new Object[] { url, imports[i].getSourceUrlString() }, e);
+
+ importedIndexes = new ArrayList<FsIndexDescription>();
+ Import[] imports = getImports();
+ for (int i = 0; i < imports.length; i++) {
+ // make sure Import's relative path base is set, to allow for users who create
+ // new import objects
+ if (imports[i] instanceof Import_impl) {
+ ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ }
+
+ URL url = imports[i].findAbsoluteUrl(aResourceManager);
+ if (!aAlreadyImportedFsIndexURLs.contains(url.toString())) {
+ aAlreadyImportedFsIndexURLs.add(url.toString());
+ try {
+ resolveImport(url, aAlreadyImportedFsIndexURLs, importedIndexes, aResourceManager);
+ } catch (IOException e) {
+ throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
+ new Object[] { url, imports[i].getSourceUrlString() }, e);
+ }
}
}
}
// update this object
FsIndexDescription[] existingIndexes = this.getFsIndexes();
if (existingIndexes == null) {
- existingIndexes = new FsIndexDescription[0];
+ this.setFsIndexes(existingIndexes = FsIndexDescription.EMPTY_FS_INDEX_DESCRIPTIONS);
}
- FsIndexDescription[] newIndexes = new FsIndexDescription[existingIndexes.length
- + importedIndexes.size()];
- System.arraycopy(existingIndexes, 0, newIndexes, 0, existingIndexes.length);
- for (int i = 0; i < importedIndexes.size(); i++) {
- newIndexes[existingIndexes.length + i] = (FsIndexDescription) importedIndexes.get(i);
+ if (null != importedIndexes) {
+ FsIndexDescription[] newIndexes = new FsIndexDescription[existingIndexes.length
+ + importedIndexes.size()];
+ System.arraycopy(existingIndexes, 0, newIndexes, 0, existingIndexes.length);
+ for (int i = 0; i < importedIndexes.size(); i++) {
+ newIndexes[existingIndexes.length + i] = (FsIndexDescription) importedIndexes.get(i);
+ }
+ this.setFsIndexes(newIndexes);
}
- this.setFsIndexes(newIndexes);
// clear imports
- this.setImports(new Import[0]);
+ this.setImports(Import.EMPTY_IMPORTS);
}
private void resolveImport(URL aURL, Collection<String> aAlreadyImportedFsIndexCollectionURLs,
@@ -247,15 +256,18 @@ public class FsIndexCollection_impl exte
//check the import cache
FsIndexCollection desc;
String urlString = aURL.toString();
- XMLizable cachedObject = aResourceManager.getImportCache().get(urlString);
- if (cachedObject instanceof FsIndexCollection) {
- desc = (FsIndexCollection)cachedObject;
- } else {
- XMLInputSource input;
- input = new XMLInputSource(aURL);
- desc = UIMAFramework.getXMLParser().parseFsIndexCollection(input);
- desc.resolveImports(aAlreadyImportedFsIndexCollectionURLs, aResourceManager);
- aResourceManager.getImportCache().put(urlString, desc);
+ Map<String, XMLizable> importCache = aResourceManager.getImportCache();
+ synchronized(importCache) {
+ XMLizable cachedObject = importCache.get(urlString);
+ if (cachedObject instanceof FsIndexCollection) {
+ desc = (FsIndexCollection)cachedObject;
+ } else {
+ XMLInputSource input;
+ input = new XMLInputSource(aURL);
+ desc = UIMAFramework.getXMLParser().parseFsIndexCollection(input);
+ desc.resolveImports(aAlreadyImportedFsIndexCollectionURLs, aResourceManager);
+ importCache.put(urlString, desc);
+ }
}
aResults.addAll(Arrays.asList(desc.getFsIndexes()));
}
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/ResourceManagerConfiguration_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/ResourceManagerConfiguration_impl.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/ResourceManagerConfiguration_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/ResourceManagerConfiguration_impl.java Fri Apr 4 13:50:02 2014
@@ -55,7 +55,7 @@ public class ResourceManagerConfiguratio
private String mVendor;
- private Import[] mImports = new Import[0];
+ private Import[] mImports = Import.EMPTY_IMPORTS;
private ExternalResourceBinding[] mBindings = new ExternalResourceBinding[0];
@@ -265,69 +265,82 @@ public class ResourceManagerConfiguratio
*
* @see org.apache.uima.resource.metadata.TypeSystemDescription#resolveImports()
*/
- public void resolveImports() throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ // support multi-threading, avoid object creation if no imports
+ public synchronized void resolveImports() throws InvalidXMLException {
+ if (getImports().length == 0) {
+ resolveImports(null, null);
+ } else {
+ resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ }
}
- public void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), aResourceManager);
+ public synchronized void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
+ resolveImports((getImports().length == 0) ? null : new TreeSet<String>(), aResourceManager);
}
- public void resolveImports(Collection<String> aAlreadyImportedURLs, ResourceManager aResourceManager)
+ public synchronized void resolveImports(Collection<String> aAlreadyImportedURLs, ResourceManager aResourceManager)
throws InvalidXMLException {
- // add our own URL, if known, to the collection of already imported URLs
- if (getSourceUrl() != null) {
- aAlreadyImportedURLs.add(getSourceUrl().toString());
- }
- List<ExternalResourceDescription> importedResources = new ArrayList<ExternalResourceDescription>();
- List<ExternalResourceBinding> importedBindings = new ArrayList<ExternalResourceBinding>();
- Import[] imports = getImports();
- for (int i = 0; i < imports.length; i++) {
- // make sure Import's relative path base is set, to allow for users who create
- // new import objects
- if (imports[i] instanceof Import_impl) {
- ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ List<ExternalResourceDescription> importedResources = null;
+ List<ExternalResourceBinding> importedBindings = null;
+ if (getImports().length != 0) {
+ // add our own URL, if known, to the collection of already imported URLs
+ if (getSourceUrl() != null) {
+ aAlreadyImportedURLs.add(getSourceUrl().toString());
}
- URL url = imports[i].findAbsoluteUrl(aResourceManager);
- if (!aAlreadyImportedURLs.contains(url.toString())) {
- aAlreadyImportedURLs.add(url.toString());
- try {
- resolveImport(url, aAlreadyImportedURLs, importedResources, importedBindings,
- aResourceManager);
- } catch (IOException e) {
- throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
- new Object[] { url, imports[i].getSourceUrlString() }, e);
+ importedResources = new ArrayList<ExternalResourceDescription>();
+ importedBindings = new ArrayList<ExternalResourceBinding>();
+ Import[] imports = getImports();
+ for (int i = 0; i < imports.length; i++) {
+ // make sure Import's relative path base is set, to allow for users who create
+ // new import objects
+ if (imports[i] instanceof Import_impl) {
+ ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ }
+ URL url = imports[i].findAbsoluteUrl(aResourceManager);
+ if (!aAlreadyImportedURLs.contains(url.toString())) {
+ aAlreadyImportedURLs.add(url.toString());
+ try {
+ resolveImport(url, aAlreadyImportedURLs, importedResources, importedBindings,
+ aResourceManager);
+ } catch (IOException e) {
+ throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
+ new Object[] { url, imports[i].getSourceUrlString() }, e);
+ }
}
}
}
-
+
// update this object
ExternalResourceDescription[] existingResources = this.getExternalResources();
if (existingResources == null) {
- existingResources = new ExternalResourceDescription[0];
+ this.setExternalResources(existingResources = ExternalResourceDescription.EMPTY_EXTERNAL_RESORUCE_DESCRIPTIONS);
}
- ExternalResourceDescription[] newResources = new ExternalResourceDescription[existingResources.length
- + importedResources.size()];
- System.arraycopy(existingResources, 0, newResources, 0, existingResources.length);
- for (int i = 0; i < importedResources.size(); i++) {
- newResources[existingResources.length + i] = (ExternalResourceDescription) importedResources
- .get(i);
+ if (importedResources != null) {
+ ExternalResourceDescription[] newResources = new ExternalResourceDescription[existingResources.length
+ + importedResources.size()];
+ System.arraycopy(existingResources, 0, newResources, 0, existingResources.length);
+ for (int i = 0; i < importedResources.size(); i++) {
+ newResources[existingResources.length + i] = (ExternalResourceDescription) importedResources
+ .get(i);
+ }
+ this.setExternalResources(newResources);
}
- this.setExternalResources(newResources);
-
+
ExternalResourceBinding[] existingBindings = this.getExternalResourceBindings();
if (existingBindings == null) {
- existingBindings = new ExternalResourceBinding[0];
+ this.setExternalResourceBindings(existingBindings = ExternalResourceBinding.EMPTY_RESOURCE_BINDINGS);
}
- ExternalResourceBinding[] newBindings = new ExternalResourceBinding[existingBindings.length
- + importedBindings.size()];
- System.arraycopy(existingBindings, 0, newBindings, 0, existingBindings.length);
- for (int i = 0; i < importedBindings.size(); i++) {
- newBindings[existingBindings.length + i] = (ExternalResourceBinding) importedBindings.get(i);
+ if (null != importedBindings) {
+ ExternalResourceBinding[] newBindings = new ExternalResourceBinding[existingBindings.length
+ + importedBindings.size()];
+ System.arraycopy(existingBindings, 0, newBindings, 0, existingBindings.length);
+ for (int i = 0; i < importedBindings.size(); i++) {
+ newBindings[existingBindings.length + i] = (ExternalResourceBinding) importedBindings.get(i);
+ }
+ this.setExternalResourceBindings(newBindings);
}
- this.setExternalResourceBindings(newBindings);
// clear imports
- this.setImports(new Import[0]);
+ this.setImports(Import.EMPTY_IMPORTS);
}
private void resolveImport(URL aURL, Collection<String> aAlreadyImportedURLs,
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorities_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorities_impl.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorities_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorities_impl.java Fri Apr 4 13:50:02 2014
@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.TreeSet;
import org.apache.uima.UIMAFramework;
@@ -48,7 +49,7 @@ import org.xml.sax.SAXException;
public class TypePriorities_impl extends MetaDataObject_impl implements TypePriorities {
static final long serialVersionUID = -4773863151055424438L;
-
+
private String mName;
private String mVersion;
@@ -57,10 +58,10 @@ public class TypePriorities_impl extends
private String mVendor;
- private Import[] mImports = new Import[0];
+ private Import[] mImports = Import.EMPTY_IMPORTS;
private List<TypePriorityList> mPriorityLists = new ArrayList<TypePriorityList>();
-
+
/**
* @see ResourceMetaData#getName()
*/
@@ -137,20 +138,27 @@ public class TypePriorities_impl extends
/**
* @see TypePriorities#getPriorityLists()
+ * synchronized to prevent concurrent mod exceptions
*/
public TypePriorityList[] getPriorityLists() {
- TypePriorityList[] result = new TypePriorityList[mPriorityLists.size()];
- mPriorityLists.toArray(result);
- return result;
+ synchronized (mPriorityLists) { // saw concurrent mod exception 3/2014
+ TypePriorityList[] result = new TypePriorityList[mPriorityLists.size()];
+ mPriorityLists.toArray(result);
+ return result;
+ }
}
/**
* @see TypePriorities#setPriorityLists(TypePriorityList[])
+ * could be called by thread doing resolve imports,
+ * while another thread was iterating over them
*/
public void setPriorityLists(TypePriorityList[] aPriorityLists) {
- mPriorityLists.clear();
- for (int i = 0; i < aPriorityLists.length; i++) {
- mPriorityLists.add(aPriorityLists[i]);
+ synchronized (mPriorityLists) { // saw concurrent mod exceptions 3/2014
+ mPriorityLists.clear();
+ for (int i = 0; i < aPriorityLists.length; i++) {
+ mPriorityLists.add(aPriorityLists[i]);
+ }
}
}
@@ -158,7 +166,9 @@ public class TypePriorities_impl extends
* @see TypePriorities#addPriorityList(TypePriorityList)
*/
public void addPriorityList(TypePriorityList aPriorityList) {
- mPriorityLists.add(aPriorityList);
+ synchronized (mPriorityLists) { // saw concurrent mod exceptions 3/2014
+ mPriorityLists.add(aPriorityList);
+ }
}
/**
@@ -166,7 +176,9 @@ public class TypePriorities_impl extends
*/
public TypePriorityList addPriorityList() {
TypePriorityList newPriorityList = new TypePriorityList_impl();
- mPriorityLists.add(newPriorityList);
+ synchronized (mPriorityLists) { // saw concurrent mod exceptions while iterating on this 3/2014
+ mPriorityLists.add(newPriorityList);
+ }
return newPriorityList;
}
@@ -174,63 +186,77 @@ public class TypePriorities_impl extends
* @see TypePriorities#removePriorityList(TypePriorityList)
*/
public void removePriorityList(TypePriorityList aPriorityList) {
- mPriorityLists.remove(aPriorityList);
+ synchronized (mPriorityLists) { // saw concurrent mod exceptions while iterating on this 3/2014
+ mPriorityLists.remove(aPriorityList);
+ }
}
/**
* @see TypeSystemDescription#resolveImports()
*/
- public void resolveImports() throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ // support multithreading,
+ // avoid object creation if already resolved
+ public synchronized void resolveImports() throws InvalidXMLException {
+ if (getImports().length == 0) {
+ resolveImports(null, null);
+ } else {
+ resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ }
}
- public void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), aResourceManager);
+ public synchronized void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
+ resolveImports((getImports().length == 0) ? null : new TreeSet<String>(), aResourceManager);
}
- public void resolveImports(Collection<String> aAlreadyImportedTypePrioritiesURLs,
+ public synchronized void resolveImports(Collection<String> aAlreadyImportedTypePrioritiesURLs,
ResourceManager aResourceManager) throws InvalidXMLException {
- // add our own URL, if known, to the collection of already imported URLs
- if (getSourceUrl() != null) {
- aAlreadyImportedTypePrioritiesURLs.add(getSourceUrl().toString());
- }
-
- List<TypePriorityList> importedPriorityLists = new ArrayList<TypePriorityList>();
- Import[] imports = getImports();
- for (int i = 0; i < imports.length; i++) {
- // make sure Import's relative path base is set, to allow for users who create
- // new import objects
- if (imports[i] instanceof Import_impl) {
- ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ List<TypePriorityList> importedPriorityLists = null;
+ if (getImports().length != 0) {
+
+ // add our own URL, if known, to the collection of already imported URLs
+ if (getSourceUrl() != null) {
+ aAlreadyImportedTypePrioritiesURLs.add(getSourceUrl().toString());
}
-
- URL url = imports[i].findAbsoluteUrl(aResourceManager);
- if (!aAlreadyImportedTypePrioritiesURLs.contains(url.toString())) {
- aAlreadyImportedTypePrioritiesURLs.add(url.toString());
- try {
- resolveImport(url, aAlreadyImportedTypePrioritiesURLs, importedPriorityLists,
- aResourceManager);
- } catch (IOException e) {
- throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
- new Object[] { url, imports[i].getSourceUrlString() }, e);
+
+ importedPriorityLists = new ArrayList<TypePriorityList>();
+ Import[] imports = getImports();
+ for (int i = 0; i < imports.length; i++) {
+ // make sure Import's relative path base is set, to allow for users who create
+ // new import objects
+ if (imports[i] instanceof Import_impl) {
+ ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ }
+
+ URL url = imports[i].findAbsoluteUrl(aResourceManager);
+ if (!aAlreadyImportedTypePrioritiesURLs.contains(url.toString())) {
+ aAlreadyImportedTypePrioritiesURLs.add(url.toString());
+ try {
+ resolveImport(url, aAlreadyImportedTypePrioritiesURLs, importedPriorityLists,
+ aResourceManager);
+ } catch (IOException e) {
+ throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
+ new Object[] { url, imports[i].getSourceUrlString() }, e);
+ }
}
}
}
- // update this object
+ //update this object
TypePriorityList[] existingPriorityLists = this.getPriorityLists();
if (existingPriorityLists == null) {
- existingPriorityLists = new TypePriorityList[0];
+ this.setPriorityLists(existingPriorityLists = TypePriorityList.EMPTY_TYPE_PRIORITY_LISTS);
}
- TypePriorityList[] newPriorityLists = new TypePriorityList[existingPriorityLists.length
- + importedPriorityLists.size()];
- System.arraycopy(existingPriorityLists, 0, newPriorityLists, 0, existingPriorityLists.length);
- for (int i = 0; i < importedPriorityLists.size(); i++) {
- newPriorityLists[existingPriorityLists.length + i] = (TypePriorityList) importedPriorityLists
- .get(i);
+ if (importedPriorityLists != null ) {
+ TypePriorityList[] newPriorityLists = new TypePriorityList[existingPriorityLists.length
+ + importedPriorityLists.size()];
+ System.arraycopy(existingPriorityLists, 0, newPriorityLists, 0, existingPriorityLists.length);
+ for (int i = 0; i < importedPriorityLists.size(); i++) {
+ newPriorityLists[existingPriorityLists.length + i] = (TypePriorityList) importedPriorityLists
+ .get(i);
+ }
+ this.setPriorityLists(newPriorityLists);
}
- this.setPriorityLists(newPriorityLists);
// clear imports
- this.setImports(new Import[0]);
+ this.setImports(Import.EMPTY_IMPORTS);
}
private void resolveImport(URL aURL, Collection<String> aAlreadyImportedTypePrioritiesURLs,
@@ -239,15 +265,18 @@ public class TypePriorities_impl extends
//check the import cache
TypePriorities desc;
String urlString = aURL.toString();
- XMLizable cachedObject = aResourceManager.getImportCache().get(urlString);
- if (cachedObject instanceof TypePriorities) {
- desc = (TypePriorities)cachedObject;
- } else {
- XMLInputSource input;
- input = new XMLInputSource(aURL);
- desc = UIMAFramework.getXMLParser().parseTypePriorities(input);
- desc.resolveImports(aAlreadyImportedTypePrioritiesURLs, aResourceManager);
- aResourceManager.getImportCache().put(urlString, desc);
+ Map<String, XMLizable> importCache = aResourceManager.getImportCache();
+ synchronized(importCache) {
+ XMLizable cachedObject = importCache.get(urlString);
+ if (cachedObject instanceof TypePriorities) {
+ desc = (TypePriorities)cachedObject;
+ } else {
+ XMLInputSource input;
+ input = new XMLInputSource(aURL);
+ desc = UIMAFramework.getXMLParser().parseTypePriorities(input);
+ desc.resolveImports(aAlreadyImportedTypePrioritiesURLs, aResourceManager);
+ importCache.put(urlString, desc);
+ }
}
aResults.addAll(Arrays.asList(desc.getPriorityLists()));
}
@@ -277,12 +306,13 @@ public class TypePriorities_impl extends
public Object clone() {
TypePriorities_impl clone = (TypePriorities_impl) super.clone();
clone.mPriorityLists = new ArrayList<TypePriorityList>();
- Iterator<TypePriorityList> priListIter = mPriorityLists.iterator();
- while (priListIter.hasNext()) {
- TypePriorityList priList = priListIter.next();
- clone.addPriorityList((TypePriorityList) priList.clone());
+ synchronized (mPriorityLists) { // saw concurrent mod exceptions while iterating on this 3/2014
+ Iterator<TypePriorityList> priListIter = mPriorityLists.iterator();
+ while (priListIter.hasNext()) {
+ TypePriorityList priList = priListIter.next();
+ clone.addPriorityList((TypePriorityList) priList.clone());
+ }
}
-
return clone;
}
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorityList_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorityList_impl.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorityList_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypePriorityList_impl.java Fri Apr 4 13:50:02 2014
@@ -37,8 +37,9 @@ public class TypePriorityList_impl exten
/**
* @see TypePriorityList#getTypes()
+ * synchronized to prevent concurrent modification exceptions
*/
- public String[] getTypes() {
+ public synchronized String[] getTypes() {
String[] result = new String[mTypeNames.size()];
mTypeNames.toArray(result);
return result;
@@ -47,7 +48,7 @@ public class TypePriorityList_impl exten
/**
* @see TypePriorityList#setTypes(java.lang.String[])
*/
- public void setTypes(String[] aTypeNames) {
+ public synchronized void setTypes(String[] aTypeNames) {
mTypeNames.clear();
for (int i = 0; i < aTypeNames.length; i++) {
mTypeNames.add(aTypeNames[i]);
@@ -57,25 +58,25 @@ public class TypePriorityList_impl exten
/**
* @see TypePriorityList#addType(java.lang.String)
*/
- public void addType(String aTypeName) {
+ public synchronized void addType(String aTypeName) {
mTypeNames.add(aTypeName);
-
}
/**
* @see TypePriorityList#removeType(java.lang.String)
*/
- public void removeType(String aTypeName) {
+ public synchronized void removeType(String aTypeName) {
mTypeNames.remove(aTypeName);
}
/*
* (non-Javadoc) Special purpose clone method to deal with ArrayList.
*/
- public Object clone() {
+ public synchronized Object clone() {
+ //surprise: super.clone sets the final field to the same array list as the original
TypePriorityList_impl clone = (TypePriorityList_impl) super.clone();
-
- clone.mTypeNames = new ArrayList<String>();
+
+ clone.mTypeNames = new ArrayList(); // because above clone has set it to the == object
for (String name : mTypeNames) {
clone.addType(name);
}
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_impl.java?rev=1584687&r1=1584686&r2=1584687&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_impl.java Fri Apr 4 13:50:02 2014
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.TreeSet;
import org.apache.uima.UIMAFramework;
@@ -47,7 +48,7 @@ public class TypeSystemDescription_impl
TypeSystemDescription {
static final long serialVersionUID = -3372766232454730201L;
-
+
private String mName;
private String mVersion;
@@ -56,7 +57,7 @@ public class TypeSystemDescription_impl
private String mVendor;
- private Import[] mImports = new Import[0];
+ private Import[] mImports = Import.EMPTY_IMPORTS;
/** Descriptions of all Types in this type system. */
private TypeDescription[] mTypes = new TypeDescription[0];
@@ -194,54 +195,63 @@ public class TypeSystemDescription_impl
/**
* @see TypeSystemDescription#resolveImports()
*/
- public void resolveImports() throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ // allow these calls to be done multiple times on this same object, in different threads
+ public synchronized void resolveImports() throws InvalidXMLException {
+ if (getImports().length == 0) {
+ resolveImports(null, null);
+ } else {
+ resolveImports(new TreeSet<String>(), UIMAFramework.newDefaultResourceManager());
+ }
}
- public void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
- resolveImports(new TreeSet<String>(), aResourceManager);
+ public synchronized void resolveImports(ResourceManager aResourceManager) throws InvalidXMLException {
+ resolveImports((getImports().length == 0) ? null : new TreeSet<String>(), aResourceManager);
}
- public void resolveImports(Collection<String> aAlreadyImportedTypeSystemURLs,
+ public synchronized void resolveImports(Collection<String> aAlreadyImportedTypeSystemURLs,
ResourceManager aResourceManager) throws InvalidXMLException {
- // add our own URL, if known, to the collection of already imported URLs
- if (getSourceUrl() != null) {
- aAlreadyImportedTypeSystemURLs.add(getSourceUrl().toString());
- }
-
- List<TypeDescription> importedTypes = new ArrayList<TypeDescription>();
- Import[] imports = getImports();
- for (int i = 0; i < imports.length; i++) {
- // make sure Import's relative path base is set, to allow for users who create
- // new import objects
- if (imports[i] instanceof Import_impl) {
- ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ List<TypeDescription> importedTypes = null;
+ if (getImports().length != 0) {
+ // add our own URL, if known, to the collection of already imported URLs
+ if (getSourceUrl() != null) {
+ aAlreadyImportedTypeSystemURLs.add(getSourceUrl().toString());
}
- URL url = imports[i].findAbsoluteUrl(aResourceManager);
- if (!aAlreadyImportedTypeSystemURLs.contains(url.toString())) {
- aAlreadyImportedTypeSystemURLs.add(url.toString());
- try {
- resolveImport(url, aAlreadyImportedTypeSystemURLs, importedTypes, aResourceManager);
- } catch (IOException e) {
- throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
- new Object[] { url, imports[i].getSourceUrlString() }, e);
+
+ importedTypes = new ArrayList<TypeDescription>();
+ Import[] imports = getImports();
+ for (int i = 0; i < imports.length; i++) {
+ // make sure Import's relative path base is set, to allow for users who create
+ // new import objects
+ if (imports[i] instanceof Import_impl) {
+ ((Import_impl) imports[i]).setSourceUrlIfNull(this.getSourceUrl());
+ }
+ URL url = imports[i].findAbsoluteUrl(aResourceManager);
+ if (!aAlreadyImportedTypeSystemURLs.contains(url.toString())) {
+ aAlreadyImportedTypeSystemURLs.add(url.toString());
+ try {
+ resolveImport(url, aAlreadyImportedTypeSystemURLs, importedTypes, aResourceManager);
+ } catch (IOException e) {
+ throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL,
+ new Object[] { url, imports[i].getSourceUrlString() }, e);
+ }
}
}
}
- // update this object
+ // maybe update this object
TypeDescription[] existingTypes = this.getTypes();
if (existingTypes == null) {
- existingTypes = new TypeDescription[0];
+ this.setTypes(existingTypes = TypeDescription.EMPTY_TYPE_DESCRIPTIONS);
}
- TypeDescription[] newTypes = new TypeDescription[existingTypes.length + importedTypes.size()];
- System.arraycopy(existingTypes, 0, newTypes, 0, existingTypes.length);
- for (int i = 0; i < importedTypes.size(); i++) {
- newTypes[existingTypes.length + i] = (TypeDescription) importedTypes.get(i);
+ if (null != importedTypes) {
+ TypeDescription[] newTypes = new TypeDescription[existingTypes.length + importedTypes.size()];
+ System.arraycopy(existingTypes, 0, newTypes, 0, existingTypes.length);
+ for (int i = 0; i < importedTypes.size(); i++) {
+ newTypes[existingTypes.length + i] = (TypeDescription) importedTypes.get(i);
+ }
+ this.setTypes(newTypes);
}
- this.setTypes(newTypes);
-
// clear imports
- this.setImports(new Import[0]);
+ this.setImports(Import.EMPTY_IMPORTS);
}
private void resolveImport(URL aURL, Collection<String> aAlreadyImportedTypeSystemURLs,
@@ -250,15 +260,18 @@ public class TypeSystemDescription_impl
//check the import cache
TypeSystemDescription desc;
String urlString = aURL.toString();
- XMLizable cachedObject = aResourceManager.getImportCache().get(urlString);
- if (cachedObject instanceof TypeSystemDescription) {
- desc = (TypeSystemDescription)cachedObject;
- } else {
- XMLInputSource input;
- input = new XMLInputSource(aURL);
- desc = UIMAFramework.getXMLParser().parseTypeSystemDescription(input);
- desc.resolveImports(aAlreadyImportedTypeSystemURLs, aResourceManager);
- aResourceManager.getImportCache().put(urlString, desc);
+ Map<String, XMLizable> importCache = aResourceManager.getImportCache();
+ synchronized(importCache) {
+ XMLizable cachedObject = importCache.get(urlString);
+ if (cachedObject instanceof TypeSystemDescription) {
+ desc = (TypeSystemDescription)cachedObject;
+ } else {
+ XMLInputSource input;
+ input = new XMLInputSource(aURL);
+ desc = UIMAFramework.getXMLParser().parseTypeSystemDescription(input);
+ desc.resolveImports(aAlreadyImportedTypeSystemURLs, aResourceManager);
+ importCache.put(urlString, desc);
+ }
}
aResults.addAll(Arrays.asList(desc.getTypes()));
}