Revision: 20033
http://sourceforge.net/p/gate/code/20033
Author: markagreenwood
Date: 2017-01-31 17:40:16 +0000 (Tue, 31 Jan 2017)
Log Message:
-----------
simplified the constructors slightly, updated the tests to match, and added a
boat load of documentation
Modified Paths:
--------------
gate/branches/sawdust2/gate-core/src/main/java/gate/creole/ResourceReference.java
gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestResourceReference.java
Modified:
gate/branches/sawdust2/gate-core/src/main/java/gate/creole/ResourceReference.java
===================================================================
---
gate/branches/sawdust2/gate-core/src/main/java/gate/creole/ResourceReference.java
2017-01-31 17:39:47 UTC (rev 20032)
+++
gate/branches/sawdust2/gate-core/src/main/java/gate/creole/ResourceReference.java
2017-01-31 17:40:16 UTC (rev 20033)
@@ -17,133 +17,231 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
-import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
+import org.apache.log4j.Logger;
+
import gate.Gate;
+/**
+ * This class provides a common way of referencing a resource regardless of
+ * where it is located. Specifically it allows resources stored within plugins
+ * to be referenced without needing to know where the resource is actually
+ * located as that information is determined when the resource is accessed.
+ * Previously most GATE components used {@link java.net.URL URL} instances to
+ * refer to resources and to aid in converting existing code to use
+ * {@code ResourceReference} instead the public API follows that of {@code URL}
+ * where possible.
+ */
public class ResourceReference implements Serializable {
private static final long serialVersionUID = 2526144106607856721L;
+ protected static final Logger log =
Logger.getLogger(ResourceReference.class);
+
+ // internal we store the location of the resource as a URI, the exact format
+ // of the URI will depend on numerous factors and no specific URI scheme is
+ // assumed
private URI uri;
+ /**
+ * Create a new instance that references a resource accessible via a known
+ * {@link java.net.URL URL}. While a useful constructor in it's own right
this
+ * also allows old applications that contain URLs as parameters to PRs that
+ * now take a {@code ResourceReference} to continue to work as the URL will
+ * get passed into this constructor automatically as the application is
+ * reloaded.
+ *
+ * @param url
+ * the {@link java.net.URL URL} of the resource you wish to
reference
+ * @throws URISyntaxException
+ * if the URL does not strictly conform to RFC 2396 or if it cannot
+ * be converted to an absolute URI
+ */
public ResourceReference(URL url) throws URISyntaxException {
uri = url.toURI();
+
+ // we only support absolute URIs as there would be no way to access a
+ // resource at a relative URI as we wouldn't know what to resolve it
against
+ if(!uri.isAbsolute())
+ throw new URISyntaxException(uri.toString(),
+ "We only support absolute URIs");
}
- public ResourceReference(URI uri) {
+ /**
+ * Create a new instance that references a resource described by a
+ * {@link java.net.URI URI}.
+ *
+ * @param uri
+ * the {@link java.net.URI URI} of the resource you wish to
reference
+ * @throws URISyntaxException
+ * if the URI is not absolute
+ */
+ public ResourceReference(URI uri) throws URISyntaxException {
this.uri = uri;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((uri == null) ? 0 : uri.hashCode());
- return result;
+ // we only support absolute URIs as there would be no way to access a
+ // resource at a relative URI as we wouldn't know what to resolve it
against
+ if(!uri.isAbsolute())
+ throw new URISyntaxException(uri.toString(),
+ "We only support absolute URIs");
}
- @Override
- public boolean equals(Object obj) {
- if(this == obj) return true;
- if(obj == null) return false;
- if(getClass() != obj.getClass()) return false;
- ResourceReference other = (ResourceReference)obj;
- if(uri == null) {
- if(other.uri != null) return false;
- } else if(!uri.equals(other.uri)) return false;
- return true;
- }
-
+ /**
+ * Creates a new instance that references a resource within a given
+ * {@link gate.creole.Plugin Plugin}.
+ *
+ * @param plugin
+ * a {@link gate.creole.Plugin Plugin} against which to resolve the
+ * path. Can be null, but only if the path can be parsed as an
+ * absolute URI
+ * @param path
+ * the path to the resource which will be resolved against the
+ * {@link gate.creole.Plugin Plugin}
+ * @throws URISyntaxException
+ * if the reference cannot be converted to an absolute URI
+ */
public ResourceReference(Plugin plugin, String path)
throws URISyntaxException {
+
+ // if the path is null this causes problems later but it's safe to use the
+ // empty string instead so we'll do that
if(path == null) path = "";
if(plugin != null) {
+ // if the plugin isn't null then we can simply resolve the path against
+ // it's base URI
uri = plugin.getBaseURI().resolve(path);
} else {
+ // there is no plugin so we just use the path to create the URI
uri = new URI(path);
}
+ // we only support absolute URIs as there would be no way to access a
+ // resource at a relative URI as we wouldn't know what to resolve it
against
if(!uri.isAbsolute())
- throw new URISyntaxException(path,
- "Context is null and path is not absolute");
+ throw new URISyntaxException(path, "We only support absolute URIs");
}
- public ResourceReference(URL context, String path)
- throws URISyntaxException, MalformedURLException {
+ /**
+ * Creates a new instance that references a resource identified by resolving
+ * the path against an existing {@code ResourceReference}.
+ *
+ * @param context
+ * a {@code ResourceReference} against which to resolve the path.
Can
+ * be null, but only if the path can be parsed as an absolute URI
+ * @param path
+ * the path to the resource which will be resolved against the
+ * context.
+ * @throws URISyntaxException
+ * if the reference cannot be converted to an absolute URI
+ */
+ public ResourceReference(ResourceReference context, String path)
+ throws URISyntaxException {
- // not sure if we need this constructor as we could just assume people can
- // do the right thing before calling the constructor
-
- uri = new URI(path);
-
- if(context != null && !uri.isAbsolute()) {
- uri = (new URL(context, path)).toURI();
- }
-
- if(!uri.isAbsolute())
- throw new URISyntaxException(path,
- "Context is null and path is not absolute");
- }
-
- public ResourceReference(URI context, String path) throws URISyntaxException
{
-
- // not sure if we need this constructor as we could just assume people can
- // do the right thing before calling the constructor
-
if(context != null) {
- uri = context.resolve(path);
- } else {
- uri = new URI(path);
- }
-
- if(!uri.isAbsolute())
- throw new URISyntaxException(path,
- "Context is null and path is not absolute");
- }
-
- public ResourceReference(ResourceReference context, String path)
- throws IOException, URISyntaxException {
- if(context != null) {
+ // if a context is provided then try and resolve the path against the
+ // encapsulated URI
uri = context.uri.resolve(path);
} else {
+ // there is no context so we just use the path to create the URI
uri = new URI(path);
}
+ // we only support absolute URIs as there would be no way to access a
+ // resource at a relative URI as we wouldn't know what to resolve it
against
if(!uri.isAbsolute())
- throw new URISyntaxException(path,
- "Context is null and path is not absolute");
+ throw new URISyntaxException(path, "We only support absolute URIs");
}
+ /**
+ * Opens a connection to this {@code ResourceReference} and returns an
+ * {@code InputStream} for reading from that connection. This method is a
+ * shorthand for: <blockquote>
+ *
+ * <pre>
+ * toURL().openConnection().getInputStream()
+ * </pre>
+ *
+ * </blockquote>
+ *
+ * @return an input stream for reading from the URL connection.
+ * @exception IOException
+ * if an I/O exception occurs.
+ */
public InputStream openStream() throws IOException {
return toURL().openStream();
}
+ /**
+ * Returns a {@link java.net.URLConnection URLConnection} instance that
+ * represents a connection to the resource referred to by this
+ * {@code ResourceReference}.
+ * <P>
+ * It should be noted that a URLConnection instance does not establish the
+ * actual network connection on creation. This will happen only when calling
+ * {@linkplain java.net.URLConnection#connect() URLConnection.connect()}.
+ * </P>
+ * This method is a shorthand for: <blockquote>
+ *
+ * <pre>
+ * toURL().openConnection()
+ * </pre>
+ *
+ * </blockquote>
+ *
+ * @return a {@link java.net.URLConnection URLConnection} linking to the
+ * underlying resource.
+ * @exception IOException
+ * if an I/O exception occurs.
+ */
public URLConnection openConnection() throws IOException {
return toURL().openConnection();
}
+ /**
+ * Creates a {@link java,net.URL URL} instance that can be used to access the
+ * underlying resource. It should be noted that the result is not guaranteed
+ * to be valid long term and should never be persisted. If you want
persistent
+ * access then store the {@code ResourceReference} instance instead.
+ *
+ * @return a {@link java.net.URL URL} that currently gives access to the
+ * referenced resource.
+ * @throws IOException
+ * if an I/O exception occurs.
+ */
public URL toURL() throws IOException {
+ // if the URI scheme is anything but creole then let java handle the
+ // conversion to a URL as it already knows how to do that
if(!uri.getScheme().equals("creole")) return uri.toURL();
try {
+ // create a URI that should point to the base of the plugin in which this
+ // resource resides
URI base = new URI("creole", uri.getAuthority(), "/", null, null);
+
for(Plugin plugin : Gate.getCreoleRegister().getPlugins()) {
+ // go through each plugin we know about until....
+
if(plugin.getBaseURI().equals(base)) {
- // requiring the additional . seems like a hack but I can't figure
out
- // any other way of doing it
+ // ... we find one with the base URI we are expecting and then
+
+ // create a new URL using the base URL of the plugin and the path
from
+ // the URI we know points to the resource
+ // NOTE: requiring the additional . seems like a hack
return new URL(plugin.getBaseURL(), "." + uri.getPath());
}
}
+
+ // TODO if we can't find the plugin should we try loading it?
+
} catch(URISyntaxException e) {
// this is impossible so ignore it
- e.printStackTrace();
+ log.debug("An impossible exception case happened, how?", e);
}
throw new IOException("Unable to locate URI: " + uri);
@@ -161,4 +259,24 @@
public String toExternalForm() {
return toString();
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this == obj) return true;
+ if(obj == null) return false;
+ if(getClass() != obj.getClass()) return false;
+ ResourceReference other = (ResourceReference)obj;
+ if(uri == null) {
+ if(other.uri != null) return false;
+ } else if(!uri.equals(other.uri)) return false;
+ return true;
+ }
}
Modified:
gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestResourceReference.java
===================================================================
---
gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestResourceReference.java
2017-01-31 17:39:47 UTC (rev 20032)
+++
gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestResourceReference.java
2017-01-31 17:40:16 UTC (rev 20033)
@@ -124,17 +124,14 @@
URL creoleURL =
new URL(TestDocument.getTestServerName() + "tests/creole.xml");
- ResourceReference rr = new ResourceReference(testURL, "./creole.xml");
+ ResourceReference context = new ResourceReference(testURL);
+ ResourceReference rr = new ResourceReference(context, "./creole.xml");
assertEquals("References do not match (1)", creoleURL, rr.toURL());
- ResourceReference context = new ResourceReference(testURL);
- rr = new ResourceReference(context, "./creole.xml");
- assertEquals("References do not match (2)", creoleURL, rr.toURL());
-
Plugin plugin = new Plugin.Directory(testURL);
context = new ResourceReference(plugin, "abc");
rr = new ResourceReference(context, "./creole.xml");
- assertEquals("References do not match (3)", creoleURL, rr.toURL());
+ assertEquals("References do not match (2)", creoleURL, rr.toURL());
context = new ResourceReference(plugin, "html/");
rr = new ResourceReference(context, "../creole.xml");
@@ -154,27 +151,15 @@
ResourceReference rr = new ResourceReference((ResourceReference)null,
path);
assertEquals("String representations don't match (1)", path,
rr.toString());
- rr = new ResourceReference((URL)null, path);
+ rr = new ResourceReference((Plugin)null, path);
assertEquals("String representations don't match (2)", path,
rr.toString());
- rr = new ResourceReference((URI)null, path);
- assertEquals("String representations don't match (3)", path,
rr.toString());
-
- rr = new ResourceReference((Plugin)null, path);
- assertEquals("String representations don't match (4)", path,
rr.toString());
-
rr = new ResourceReference(
new ResourceReference(new URL("http://gate.ac.uk")), path);
- assertEquals("String representations don't match (5)", path,
rr.toString());
+ assertEquals("String representations don't match (3)", path,
rr.toString());
- rr = new ResourceReference(new URL("http://gate.ac.uk"), path);
- assertEquals("String representations don't match (6)", path,
rr.toString());
-
- rr = new ResourceReference(new URI("http://gate.ac.uk"), path);
- assertEquals("String representations don't match (7)", path,
rr.toString());
-
rr = new ResourceReference(creolePlugin, path);
- assertEquals("String representations don't match (8)", path,
rr.toString());
+ assertEquals("String representations don't match (4)", path,
rr.toString());
}
public void testDefaultValue() throws Exception {
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
GATE-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gate-cvs