Revision: 19976
http://sourceforge.net/p/gate/code/19976
Author: markagreenwood
Date: 2017-01-23 05:00:32 +0000 (Mon, 23 Jan 2017)
Log Message:
-----------
creole:// URLs now allow us to refer to resources inside plugins without
knowing (or caring) where they actually live on disc, making it easy to refer
to files across plugins. This means I should now be able to convert the Twitter
plugin -- still need to decide exactly how/when/where to do the init of the
handler but this works for now
Modified Paths:
--------------
gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java
Added Paths:
-----------
gate/branches/sawdust2/gate-core/src/main/java/sun/
gate/branches/sawdust2/gate-core/src/main/java/sun/net/
gate/branches/sawdust2/gate-core/src/main/java/sun/net/www/
gate/branches/sawdust2/gate-core/src/main/java/sun/net/www/protocol/
gate/branches/sawdust2/gate-core/src/main/java/sun/net/www/protocol/creole/
gate/branches/sawdust2/gate-core/src/main/java/sun/net/www/protocol/creole/Handler.java
Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java
===================================================================
--- gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java
2017-01-23 02:23:21 UTC (rev 19975)
+++ gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java
2017-01-23 05:00:32 UTC (rev 19976)
@@ -22,11 +22,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
+import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
@@ -83,13 +86,87 @@
import gate.util.asm.Opcodes;
import gate.util.asm.Type;
import gate.util.asm.commons.EmptyVisitor;
-import gate.util.maven.SimpleMavenCache;
import gate.util.maven.SimpleModelResolver;
public abstract class Plugin {
protected static final Logger log = Logger.getLogger(Plugin.class);
+
+ static {
+ if(!Plugin.class.getClassLoader()
+ .equals(ClassLoader.getSystemClassLoader())) {
+ // we only need to register the factory if the handler classes are not
+ // already on the system classloader
+
+ log.debug("registering URLStreamHandlerFactory");
+
+ Field factoryField = null;
+
+ try {
+ // get the factory field from java.net.URL via reflection
+ factoryField = URL.class.getDeclaredField("factory");
+
+ // it's usually package protected but we need access to it
+ factoryField.setAccessible(true);
+
+ // get the current factory out of the protected field. This will be
null
+ // if a factory hasn't already been set
+ URLStreamHandlerFactory currentFactory =
+ (URLStreamHandlerFactory)factoryField.get(null);
+
+ // now we define out custom factory
+ URLStreamHandlerFactory newFactory = new URLStreamHandlerFactory() {
+
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ if(currentFactory != null) {
+ // if there was already a factory then delegate to it first to
see
+ // if it can handle the protocol
+ URLStreamHandler handler =
+ currentFactory.createURLStreamHandler(protocol);
+
+ // if so our work here is done
+ if(handler != null) return handler;
+ }
+
+ // build up the normal classname from the protocol
+ String className = "sun.net.www.protocol." + protocol + ".Handler";
+
+ try {
+ // try to load the class
+ Class<?> handler = Class.forName(className);
+
+ // create and return an instance of the protocol handler
+ return (URLStreamHandler)handler.newInstance();
+
+ } catch(ClassNotFoundException | InstantiationException
+ | IllegalAccessException e) {
+ // skip over this to the null return;
+ }
+
+ // either there is no handler for the protocol or something went
+ // wrong, either way just return null
+ return null;
+ }
+ };
+
+ // make sure the factory field is set to null so that setting it won't
+ // cause an exception
+ factoryField.set(null, null);
+
+ // register our deligating factory
+ URL.setURLStreamHandlerFactory(newFactory);
+ } catch(NoSuchFieldException | IllegalAccessException e) {
+ //this is a problem as it means our custom protocol handlers aren't
going to get used
+ e.printStackTrace();
+ } finally {
+ // make sure we put the field back the way it was before we started
+ if(factoryField != null) factoryField.setAccessible(false);
+ }
+ }
+ }
+
/**
* Is the plugin valid (i.e. is the location reachable and the
* creole.xml file parsable).
@@ -165,7 +242,7 @@
return valid;
}
- public void copyResources(File dir) throws IOException {
+ public void copyResources(File dir) throws IOException, URISyntaxException {
throw new UnsupportedOperationException("This plugin does not contain any
resources that can be copied");
}
@@ -417,6 +494,8 @@
private String group, artifact, version;
+ private transient URL artifactURL;
+
private WorkspaceReader workspace = null;//new SimpleMavenCache(new
File("cache"));
public Maven(String group, String artifact, String version) {
@@ -459,14 +538,14 @@
}
@Override
- public void copyResources(File dir) throws IOException {
+ public void copyResources(File dir) throws URISyntaxException, IOException
{
if (!hasResources())
throw new UnsupportedOperationException(
"this plugin doesn't have any resources you can copy as you would
know had you called hasResources first :P");
try (FileSystem zipFs =
- FileSystems.newFileSystem(baseURL, new HashMap<>());) {
+ FileSystems.newFileSystem(artifactURL.toURI(), new HashMap<>());) {
Path target = Paths.get(dir.toURI());
Path pathInZip = zipFs.getPath("/resources");
@@ -492,14 +571,22 @@
@Override
public boolean hasResources() {
- try (FileSystem zipFs = FileSystems.newFileSystem(baseURL, new
HashMap<>());) {
+ try (FileSystem zipFs = FileSystems.newFileSystem(artifactURL.toURI(),
new HashMap<>());) {
Path pathInZip = zipFs.getPath("/resources");
return Files.isDirectory(pathInZip);
}
- catch (IOException e) {
+ catch (URISyntaxException | IOException e) {
return false;
}
}
+
+ public URL getArtifactURL() throws Exception {
+ if (artifactURL == null) {
+ getCreoleXML();
+ }
+
+ return artifactURL;
+ }
@Override
public Document getCreoleXML() throws Exception {
@@ -520,20 +607,22 @@
repoSystem.resolveArtifact(repoSession,
artifactRequest);
- baseURL =
- new URI("jar:"
+ baseURL = new URI("creole://"+group+";"+artifact+";"+version+"/");
+
+ artifactURL =
+ new URL("jar:"
+ artifactResult.getArtifact().getFile().toURI().toURL()
+ "!/");
// check it has a creole.xml at the root
- URL directoryXmlFileUrl = new URL(getBaseURL(), "creole.xml");
+ URL directoryXmlFileUrl = new URL(artifactURL, "creole.xml");
InputStream creoleStream = null;
try {
creoleStream = directoryXmlFileUrl.openStream();
} catch(IOException ioe) {
- throw new IOException(directoryXmlFileUrl.toExternalForm()
+ throw new IOException(getBaseURL().toExternalForm()
+ " does not exist so this artifact is not a GATE plugin");
}
@@ -554,7 +643,7 @@
// jar (marked for scanning) and the dependencies
SAXBuilder builder = new SAXBuilder(false);
Document jdomDoc =
- builder.build(creoleStream,
directoryXmlFileUrl.toExternalForm());
+ builder.build(creoleStream, getBaseURL().toExternalForm());
Element creoleRoot = jdomDoc.getRootElement();
Added:
gate/branches/sawdust2/gate-core/src/main/java/sun/net/www/protocol/creole/Handler.java
===================================================================
---
gate/branches/sawdust2/gate-core/src/main/java/sun/net/www/protocol/creole/Handler.java
(rev 0)
+++
gate/branches/sawdust2/gate-core/src/main/java/sun/net/www/protocol/creole/Handler.java
2017-01-23 05:00:32 UTC (rev 19976)
@@ -0,0 +1,58 @@
+package sun.net.www.protocol.creole;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.util.Set;
+
+import org.apache.commons.io.IOUtils;
+
+import gate.Gate;
+import gate.Plugin;
+
+public class Handler extends URLStreamHandler {
+
+ @Override
+ protected URLConnection openConnection(URL u) throws IOException {
+
+ String[] data = u.getHost().split(";");
+
+ if (data.length != 3)
+ throw new IOException(u.getHost()+" does not refer to a CREOLE plugin");
+
+ Plugin plugin = new Plugin.Maven(data[0], data[1], data[2]);
+
+ Set<Plugin> plugins = Gate.getCreoleRegister().getPlugins();
+
+ for (Plugin registered : plugins) {
+ System.out.println(registered.getName());
+ if (registered.equals(plugin)) {
+
+ try {
+ URL baseURL = ((Plugin.Maven)registered).getArtifactURL();
+
+ URL actualURL = new URL(baseURL,u.getFile());
+ return actualURL.openConnection();
+ }
+ catch (Exception e) {
+ throw new IOException("Unable to access plugin",e);
+ }
+
+ }
+ }
+
+ throw new IOException("Plugin specified by URL has not been loaded into
GATE");
+ }
+
+ public static void main(String args[]) throws Exception {
+ Gate.init();
+
+ Plugin plugin = new Plugin.Maven("uk.ac.gate.plugins", "annie",
"9.0-SNAPSHOT");
+ Gate.getCreoleRegister().registerPlugin(plugin);
+
+ URL url = new
URL("creole://uk.ac.gate.plugins;annie;9.0-SNAPSHOT/META-INF/gate/creole.xml");
+ System.out.println(IOUtils.toString(url));
+ }
+
+}
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