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
GATE-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gate-cvs

Reply via email to