Skip to content

Commit

Permalink
Merge pull request #373 from apache/feature/372-Allow-adding-URLs-to-…
Browse files Browse the repository at this point in the history
…the-datapath

#372 - Allow adding URLs to the datapath
  • Loading branch information
reckart authored Aug 15, 2024
2 parents 81587d2 + 3610803 commit 2bfac0f
Show file tree
Hide file tree
Showing 10 changed files with 494 additions and 305 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ public class UIMAClassLoader extends URLClassLoader {
/**
* Transforms the string classpath to a URL array based classpath.
*
* The classpath string must be separated with the filesystem path separator.
* The classpath string must be separated with the file system path separator.
*
* @param classpath
* a classpath string
* @return URL[] array of wellformed URL's
* @return URL[] array of well-formed URL's
* @throws MalformedURLException
* if a malformed URL has occurred in the classpath string.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

/**
* Used by the resource manager to resolve relative URLs to absolute URLs.
*
*
*/
public interface RelativePathResolver {

Expand All @@ -37,21 +35,39 @@ public interface RelativePathResolver {
* Gets the data path used to resolve relative paths. More than one directory may be specified by
* separating them with the System <code>path.separator</code> character (; on windows, : on
* UNIX). Elements of this path may be absolute or relative file paths.
* <p>
* <b>Note:</b> This method will only return file paths. If any non-file URLs have been added to
* the data path e.g via {@link #setDataPathElements(URL...)}, these will not be included. Use
* {@link #getDataPathUrls()} to get a full list.
*
* @return the data path
* @deprecated Use {@link #getDataPathElements} instead.
*/
@Deprecated
@Deprecated(since = "3.3.0")
String getDataPath();

/**
* Gets the data path used to resolve relative paths. Elements of this path may be absolute or
* relative file paths.
* <p>
* <b>Note:</b> This method will only return file paths. If any non-file URLs have been added to
* the data path e.g via {@link #setDataPathElements(URL...)}, these will not be included. Use
* {@link #getDataPathUrls()} to get a full list.
*
* @return the data path
* @deprecated Use {@link #getDataPathUrls()} instead.
*/
@Deprecated(since = "3.6.0")
List<String> getDataPathElements();

/**
* Gets the data path used to resolve relative paths. Elements of this path may be absolute or
* relative URLs.
*
* @return the data path
*/
List<URL> getDataPathUrls();

/**
* Sets the data path used to resolve relative paths. More than one directory may be specified by
* separating them with the System <code>path.separator</code> character (; on windows, : on
Expand All @@ -64,12 +80,12 @@ public interface RelativePathResolver {
* if a file path could not be converted to a URL
* @deprecated Use {@link #setDataPathElements} instead.
*/
@Deprecated
@Deprecated(since = "3.3.0")
void setDataPath(String aPath) throws MalformedURLException;

/**
* Sets the data path elements used to resolve relative paths. Elements of this path may be
* absolute or relative file paths.
* Sets the data path elements used to resolve relative paths. Elements of this path may be URLs
* or absolute or relative file paths.
*
* @param aElements
* the data path elements
Expand All @@ -92,19 +108,48 @@ public interface RelativePathResolver {
void setDataPathElements(File... aElements) throws MalformedURLException;

/**
* Resolves a relative URL to an absolute URL. This will attempt to resolve the URL relative to
* each element of the data path, sequentially starting with the first element. If this results in
* an absolute URL at which a file actually exists, that absolute URL is returned. If no file
* could be found, <code>null</code> is returned.
* Sets the data path elements used to resolve relative paths. Elements of this path may be
* absolute or relative URLs.
*
* @param aURLs
* the data path aURLs
*/
void setDataPathElements(URL... aURLs);

/**
* Resolves an URLrelative to each element of the data path, sequentially starting with the first
* element. If this results in an absolute URL at which a file actually exists, that absolute URL
* is returned. If no file could be found, <code>null</code> is returned.
*
* @param aUrl
* the URL to be resolved (if an absolute URL is specified, it will be returned
* unmodified if a file actually exists at the URL; otherwise <code>null</code> will be
* returned).
*
* @return the absolute URL at which the file exists, <code>null</code> it none could be found.
* @deprecated Use {@link #resolveRelativePath(String)} instead.
*/
@Deprecated
URL resolveRelativePath(URL aUrl);

/**
* Resolves a path relative to each element of the data path, sequentially starting with the first
* element. If this results in an absolute URL at which a file actually exists, that absolute URL
* is returned. If no file could be found, <code>null</code> is returned.
* <p>
* <b>Note:</b> For backwards compatibility, it is still allowed to specify relative URLs here
* such as {@code file:foo/foo.txt} and this will effectively work as if {@code foo/foo.txt} had
* been specified. The protocol is simply discarded. Future versions will no longer accept a
* protocol in relative paths.
*
* @param aRelativeUrl
* the relative URL to be resolved (if an absolute URL is specified, it will be returned
* @param aPathOrUrl
* the path/URL to be resolved (if an absolute URL is specified, it will be returned
* unmodified if a file actually exists at the URL; otherwise <code>null</code> will be
* returned).
*
* @return the absolute URL at which the file exists, <code>null</code> it none could be found.
*/
URL resolveRelativePath(URL aRelativeUrl);
URL resolveRelativePath(String aPathOrUrl);

/**
* Sets the ClassLoader that should be used to resolve the resources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,45 @@
/**
* A <code>ResourceManager</code> holds a collection of {@link org.apache.uima.resource.Resource}
* objects, each registered under a specified key.
*
*
*/
public interface ResourceManager {

/**
* Gets the data path used to resolve relative paths. More than one directory may be specified by
* separating them with the System <code>path.separator</code> character (; on windows, : on
* UNIX).
* <p>
* <b>Note:</b> This method will only return file paths. If any non-file URLs have been added to
* the data path e.g via {@link #setDataPathUrls(URL...)}, these will not be included. Use
* {@link #getDataPathUrls()} to get a full list.
*
* @return the data path
*
* @deprecated Use {@link #getDataPathElements()} instead.
*/
@Deprecated
@Deprecated(since = "3.3.0")
String getDataPath();

/**
* Gets the data path elements used to resolve relative paths.
*
* <p>
* <b>Note:</b> This method will only return file paths. If any non-file URLs have been added to
* the data path e.g via {@link #setDataPathUrls(URL...)}, these will not be included. Use
* {@link #getDataPathUrls()} to get a full list.
*
* @return the data path elements
* @deprecated Use {@link #getDataPathUrls()}
*/
@Deprecated(since = "3.6.0")
List<String> getDataPathElements();

/**
* Gets the data path URLs used to resolve relative paths.
*
* @return the data path elements
*/
List<URL> getDataPathUrls();

/**
* Sets the data path used to resolve relative paths. More than one directory may be specified by
* separating them with the System <code>path.separator</code> character (; on windows, : on
Expand All @@ -69,18 +84,18 @@ public interface ResourceManager {
* if an element of the path is neither a valid URL or a valid file path
* @deprecated Use {@link #setDataPathElements} instead.
*/
@Deprecated
@Deprecated(since = "3.3.0")
void setDataPath(String aPath) throws MalformedURLException;

/**
* Sets the data path elements used to resolve relative paths. Elements of this path may be
* absolute or relative file paths.
* Sets the data path elements used to resolve relative paths. Elements of this path may be URLs
* or absolute or relative file paths.
*
* @param aElements
* the data path
* the data path elements
*
* @throws MalformedURLException
* if an element of the path is neither a valid URL or a valid file path
* if a file path could not be converted to a URL
*/
void setDataPathElements(String... aElements) throws MalformedURLException;

Expand All @@ -96,6 +111,15 @@ public interface ResourceManager {
*/
void setDataPathElements(File... aElements) throws MalformedURLException;

/**
* Sets the data path elements used to resolve relative paths. Elements of this path may be
* absolute or relative URLs.
*
* @param aUrls
* the data path aURLs
*/
void setDataPathUrls(URL... aUrls);

/**
* Attempts to resolve a relative path to an absolute path using the same mechanism that the
* ResourceManager uses to find resources -- a lookup in the datapath followed by a lookup in the
Expand Down Expand Up @@ -130,23 +154,23 @@ public interface ResourceManager {
*/
Object getResource(String aName) throws ResourceAccessException;

//@formatter:off
/**
* Returns one of two kinds of objects (or null):
* - an instance of the implementation object for a resource, that has
* been loaded with a DataResource resource produced by the resource given the aParms
*
* - (if there is no implementation defined for this resource)
* returns an instance of the DataResource, itself, produced by the resource given the aParms
*
* An example of a parameterized Resource is a
* dictionary whose data depend on a specified language identifier.
*
* If the implementation object class exists, but no instance has been
* created (yet) for the particular data resource corresponding to the parameters,
* then this method will create and register a new instance and call its
* load() api using the data resource corresponding to the parameters, and
* return that.
* <ul>
* <li>an instance of the implementation object for a resource, that has been loaded with a
* DataResource resource produced by the resource given the aParms
*
* <li>(if there is no implementation defined for this resource) returns an instance of the
* DataResource, itself, produced by the resource given the aParms
* </ul>
* <p>
* An example of a parameterized Resource is a dictionary whose data depend on a specified
* language identifier.
* <p>
* If the implementation object class exists, but no instance has been created (yet) for the
* particular data resource corresponding to the parameters, then this method will create and
* register a new instance and call its load() api using the data resource corresponding to the
* parameters, and return that.
*
* @param aName
* the name of the parameterized resource to retrieve
Expand All @@ -171,7 +195,6 @@ public interface ResourceManager {
* if there is a resource registered under <code>aName</code> but it could not be
* instantiated for the specified parameters.
*/
//@formatter:on
Object getResource(String aName, String[] aParams) throws ResourceAccessException;

/**
Expand Down Expand Up @@ -308,20 +331,20 @@ void initializeExternalResources(ResourceManagerConfiguration aConfiguration,
String aQualifiedContextName, Map<String, Object> aAdditionalParams)
throws ResourceInitializationException;

//@formatter:off
/**
* Resolves a component's external resource dependencies (bindings) using this resource manager.
*
* <p>
* The default implementation has special defaulting logic:
* <p>
* If a binding specifies a non-existing resource, an attempt is made to interpret the key as a
* file name, looked up using the current context for relative path resolution.
* <ul>
* <li>If successfully found, a FileResourceSpecifier is created using the file and used as the
* implementing class.
*
* If a binding specifies a non-existing resource,
* an attempt is made to interpret the key as a file name, looked up
* using the current context for relative path resolution.
* - If successfully found, a FileResourceSpecifier is created using the file
* and used as the implementing class.
*
* If no resource can be found at all, then unless the dependency is marked "optional", an
* <li>If no resource can be found at all, then unless the dependency is marked "optional", an
* ResourceInitializationException is thrown.
* </ul>
*
* Multi-threading: may be called on multiple threads, repeatedly for the same set of resources.
* Implementations should recognize this and skip repeated resolutions.
Expand All @@ -335,7 +358,6 @@ void initializeExternalResources(ResourceManagerConfiguration aConfiguration,
* @throws ResourceInitializationException
* if a required dependency is not satisfied
*/
//@formatter:on
void resolveAndValidateResourceDependencies(ExternalResourceDependency[] aDependencies,
String aQualifiedContextName) throws ResourceInitializationException;

Expand Down Expand Up @@ -423,7 +445,7 @@ default void setExtensionClassLoader(ClassLoader classLoader, boolean resolveRes
* @return A map from absolute URL to the XMLizable object that was parsed from that URL
* @deprecated Intended just for internal use.
*/
@Deprecated
@Deprecated(since = "3.3.0")
Map<String, XMLizable> getImportCache();

/**
Expand Down Expand Up @@ -465,7 +487,6 @@ default void setExtensionClassLoader(ClassLoader classLoader, boolean resolveRes
void destroy();

/**
*
* @return a List of External Shared Resource instances instantiated by this Resource Manager. For
* parameterized resources, those which have been asked for (having unique parameter sets)
* are included.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,8 @@ public boolean initialize(ResourceSpecifier aSpecifier, Map<String, Object> aAdd
relPathResolver = new RelativePathResolver_impl();
}

// Get the file URL, resolving relative path as necessary
try {
mFileUrl = relPathResolver.resolveRelativePath(new URL(mUri.toString()));
} catch (IOException e) {
// this is OK. The URI may not be a valid URL (e.g. it may use a non-standard protocol).
// in this case getUrl returns null but getUri can still be used to access the URI
}
mFileUrl = relPathResolver.resolveRelativePath(mUri.toString());

return true;
}

Expand Down Expand Up @@ -153,18 +148,22 @@ protected File getLocalCache() {
@Override
public boolean equals(Object obj) {
// obj must be a DataResource_impl
if (!(obj instanceof ConfigurableDataResource_impl))
if (!(obj instanceof ConfigurableDataResource_impl)) {
return false;
}

// URIs must be the same
URI uri = ((ConfigurableDataResource_impl) obj).getUri();
if (uri == null || !uri.equals(getUri()))
if (uri == null || !uri.equals(getUri())) {
return false;
}

// Local Cache Files must be the same
File localCache = ((ConfigurableDataResource_impl) obj).getLocalCache();
if ((localCache == null && getLocalCache() != null) || (localCache != null && !localCache.equals(getLocalCache())))
if ((localCache == null && getLocalCache() != null)
|| (localCache != null && !localCache.equals(getLocalCache()))) {
return false;
}

return true;
}
Expand All @@ -176,8 +175,9 @@ public boolean equals(Object obj) {
public int hashCode() {
// add hash codes of member variables
int hashCode = 0;
if (mUri != null)
if (mUri != null) {
hashCode += mUri.hashCode();
}

return hashCode;
}
Expand Down
Loading

0 comments on commit 2bfac0f

Please sign in to comment.