Revision: 19985 http://sourceforge.net/p/gate/code/19985 Author: markagreenwood Date: 2017-01-25 14:20:13 +0000 (Wed, 25 Jan 2017) Log Message: ----------- moved gate.Plugin to gate.creole.Plugin which is a much more sensible place for the class to live
Modified Paths: -------------- gate/branches/sawdust2/Test-Utils/src/main/java/gate/test/GATEPluginTestCase.java gate/branches/sawdust2/gate-core/src/main/java/gate/CreoleRegister.java gate/branches/sawdust2/gate-core/src/main/java/gate/Factory.java gate/branches/sawdust2/gate-core/src/main/java/gate/Gate.java gate/branches/sawdust2/gate-core/src/main/java/gate/Main.java gate/branches/sawdust2/gate-core/src/main/java/gate/Utils.java gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleAnnotationHandler.java gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleRegisterImpl.java gate/branches/sawdust2/gate-core/src/main/java/gate/gui/MainFrame.java gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/AvailablePlugins.java gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/PluginUpdateManager.java gate/branches/sawdust2/gate-core/src/main/java/gate/util/GateClassLoader.java gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/ExpandCreoleXmls.java gate/branches/sawdust2/gate-core/src/main/java/gate/util/persistence/PersistenceManager.java gate/branches/sawdust2/gate-core/src/test/java/gate/config/TestConfig.java gate/branches/sawdust2/gate-core/src/test/java/gate/creole/DynamicRegistrationTest.java gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreole.java gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreoleAnnotationHandler.java gate/branches/sawdust2/gate-maven-plugin/src/main/java/uk/ac/gate/maven/DumpCreoleToXML.java gate/branches/sawdust2/notes.txt gate/branches/sawdust2/pom.xml Added Paths: ----------- gate/branches/sawdust2/gate-core/src/main/java/gate/creole/Plugin.java Removed Paths: ------------- gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java Modified: gate/branches/sawdust2/Test-Utils/src/main/java/gate/test/GATEPluginTestCase.java =================================================================== --- gate/branches/sawdust2/Test-Utils/src/main/java/gate/test/GATEPluginTestCase.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/Test-Utils/src/main/java/gate/test/GATEPluginTestCase.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -15,7 +15,7 @@ package gate.test; import gate.Gate; -import gate.Plugin; +import gate.creole.Plugin; import gate.Gate.ResourceInfo; import gate.util.Files; import gate.util.asm.ClassReader; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/CreoleRegister.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/CreoleRegister.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/CreoleRegister.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -16,6 +16,7 @@ package gate; +import gate.creole.Plugin; import gate.creole.ResourceData; import gate.creole.metadata.CreoleResource; import gate.event.CreoleListener; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/Factory.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/Factory.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/Factory.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -24,6 +24,7 @@ import gate.creole.CustomDuplication; import gate.creole.ParameterException; import gate.creole.ParameterList; +import gate.creole.Plugin; import gate.creole.ResourceData; import gate.creole.ResourceInstantiationException; import gate.event.CreoleEvent; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/Gate.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/Gate.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/Gate.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -18,6 +18,7 @@ import gate.config.ConfigDataProcessor; import gate.creole.CreoleRegisterImpl; +import gate.creole.Plugin; import gate.creole.ResourceData; import gate.event.CreoleListener; import gate.gui.creole.manager.PluginUpdateManager; @@ -1289,6 +1290,10 @@ public String getResourceComment() { return resourceComment; } + + public void setResourceComment(String resourceComment) { + this.resourceComment = resourceComment; + } /** * @return Returns the resourceName. @@ -1296,6 +1301,10 @@ public String getResourceName() { return resourceName; } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } /** * The class for the resource. Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/Main.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/Main.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/Main.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -16,6 +16,7 @@ package gate; +import gate.creole.Plugin; import gate.gui.MainFrame; import gate.gui.OptionsDialog; import gate.util.BomStrippingInputStreamReader; Deleted: gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -1,751 +0,0 @@ -/* - * Plugin.java - * - * Copyright (c) 2016, The University of Sheffield. See the file - * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt - * - * This file is part of GATE (see http://gate.ac.uk/), and is free - * software, licenced under the GNU Library General Public License, - * Version 3, June 2007 (in the distribution as file licence.html, - * and also available at http://gate.ac.uk/gate/licence.html). - * - * Mark A. Greenwood, 3rd April 2016 - */ - -package gate; - -import static gate.util.maven.Utils.getRepositoryList; -import static gate.util.maven.Utils.getRepositorySession; -import static gate.util.maven.Utils.getRepositorySystem; - -import java.io.File; -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; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.maven.model.Model; -import org.apache.maven.model.building.DefaultModelBuilderFactory; -import org.apache.maven.model.building.DefaultModelBuildingRequest; -import org.apache.maven.model.building.ModelBuilder; -import org.apache.maven.model.building.ModelBuildingRequest; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.collection.CollectRequest; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.DependencyNode; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.repository.WorkspaceReader; -import org.eclipse.aether.resolution.ArtifactRequest; -import org.eclipse.aether.resolution.ArtifactResult; -import org.eclipse.aether.resolution.DependencyRequest; -import org.eclipse.aether.resolution.DependencyResult; -import org.eclipse.aether.util.artifact.SubArtifact; -import org.jdom.Attribute; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jdom.input.SAXBuilder; - -import gate.Gate.ResourceInfo; -import gate.creole.metadata.CreoleResource; -import gate.util.asm.AnnotationVisitor; -import gate.util.asm.ClassReader; -import gate.util.asm.ClassVisitor; -import gate.util.asm.Opcodes; -import gate.util.asm.Type; -import gate.util.asm.commons.EmptyVisitor; -import gate.util.maven.SimpleModelResolver; - -public abstract class Plugin { - - protected static final Logger log = Logger.getLogger(Plugin.class); - - /** - * Is the plugin valid (i.e. is the location reachable and the - * creole.xml file parsable). - */ - protected transient boolean valid = true; - - /** - * This is the URL against which all relative URLs in the CREOLE - * metadata are resolved - */ - protected transient URI baseURL; - - protected transient String name; - - /** - * The list of {@link Gate.ResourceInfo} objects within this plugin - */ - protected transient List<ResourceInfo> resourceInfoList = null; - - /** - * The set of other plugins that must be loaded prior to the loading - * of this plugin - */ - protected transient Set<Plugin> requiredPlugins = null; - - public abstract org.jdom.Document getCreoleXML() throws Exception; - - public abstract String getName(); - - public Set<Plugin> getRequiredPlugins() { - if (requiredPlugins == null) parseCreole(); - - return requiredPlugins; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((baseURL == null) ? 0 : baseURL.hashCode()); - return result; - } - - @Override - public String toString() { - return getName(); - } - - @Override - public boolean equals(Object obj) { - if(this == obj) return true; - if(obj == null) return false; - if(getClass() != obj.getClass()) return false; - Plugin other = (Plugin)obj; - if(baseURL == null) { - if(other.baseURL != null) return false; - } else if(!baseURL.equals(other.baseURL)) return false; - return true; - } - - public List<ResourceInfo> getResourceInfoList() { - if (resourceInfoList == null) parseCreole(); - - return resourceInfoList; - } - - public URL getBaseURL() { - try { - return baseURL.toURL(); - } catch(MalformedURLException e) { - // this should be impossible because of the way we have got hold of the - // URI - throw new RuntimeException(e); - } - } - - public boolean isValid() { - return valid; - } - - public void copyResources(File dir) throws IOException, URISyntaxException { - throw new UnsupportedOperationException("This plugin does not contain any resources that can be copied"); - } - - public boolean hasResources() { - return false; - } - - protected void parseCreole() { - - valid = true; - - resourceInfoList = new ArrayList<ResourceInfo>(); - requiredPlugins = new LinkedHashSet<Plugin>(); - - String relativePathMarker = "$relpath$"; - String gatehomePathMarker = "$gatehome$"; - String gatepluginsPathMarker = "$gateplugins$"; - - try { - org.jdom.Document creoleDoc = getCreoleXML(); - - final Map<String, ResourceInfo> resInfos = new LinkedHashMap<String, ResourceInfo>(); - List<Element> jobsList = new ArrayList<Element>(); - List<String> jarsToScan = new ArrayList<String>(); - List<String> allJars = new ArrayList<String>(); - jobsList.add(creoleDoc.getRootElement()); - while(!jobsList.isEmpty()) { - Element currentElem = jobsList.remove(0); - if(currentElem.getName().equalsIgnoreCase("JAR")) { - @SuppressWarnings("unchecked") - List<Attribute> attrs = currentElem.getAttributes(); - Iterator<Attribute> attrsIt = attrs.iterator(); - while(attrsIt.hasNext()) { - Attribute attr = attrsIt.next(); - if(attr.getName().equalsIgnoreCase("SCAN") && attr.getBooleanValue()) { - jarsToScan.add(currentElem.getTextTrim()); - break; - } - } - allJars.add(currentElem.getTextTrim()); - } - else if(currentElem.getName().equalsIgnoreCase("RESOURCE")) { - // we don't go deeper than resources so no recursion here - String resName = currentElem.getChildTextTrim("NAME"); - String resClass = currentElem.getChildTextTrim("CLASS"); - String resComment = currentElem.getChildTextTrim("COMMENT"); - if(!resInfos.containsKey(resClass)) { - // create the handler - ResourceInfo rHandler = - new ResourceInfo(resName, resClass, resComment); - resInfos.put(resClass, rHandler); - } - } - else if(currentElem.getName().equalsIgnoreCase("REQUIRES")) { - - if (currentElem.getAttribute("GROUP") != null) { - //TODO probably need more error checking here - requiredPlugins.add(new Plugin.Maven(currentElem - .getAttributeValue("GROUP"), currentElem - .getAttributeValue("ARTIFACT"), currentElem - .getAttributeValue("VERSION"))); - } - else { - URL url = null; - String urlString = currentElem.getTextTrim(); - if(urlString.startsWith(relativePathMarker)) { - url = - new URL(getBaseURL(), urlString.substring(relativePathMarker - .length())); - } else if(urlString.startsWith(gatehomePathMarker)) { - URL gatehome = Gate.getGateHome().toURI().toURL(); - url = - new URL(gatehome, - urlString.substring(gatehomePathMarker.length())); - } else if(urlString.startsWith(gatepluginsPathMarker)) { - URL gateplugins = Gate.getPluginsHome().toURI().toURL(); - url = - new URL(gateplugins, urlString.substring(gatepluginsPathMarker - .length())); - } else { - url = new URL(getBaseURL(), urlString); - } - - requiredPlugins.add(new Plugin.Directory(url)); - - Utils.logOnce(log, Level.WARN, "Dependencies on other plugins via URL is deprecated ("+getName()+" plugin)"); - } - } - else { - // this is some higher level element -> simulate recursion - // we want Depth-first-search so we need to add at the beginning - @SuppressWarnings("unchecked") - List<Element> newJobsList = new ArrayList<Element>(currentElem.getChildren()); - newJobsList.addAll(jobsList); - jobsList = newJobsList; - } - } - - // now process the jar files with SCAN="true", looking for any extra - // CreoleResource annotated classes. - for(String jarFile : jarsToScan) { - URL jarUrl = new URL(getBaseURL(), jarFile); - scanJar(jarUrl, resInfos); - } - - // see whether any of the ResourceInfo objects are still incomplete - // (don't have a name) - List<ResourceInfo> incompleteResInfos = new ArrayList<ResourceInfo>(); - for(ResourceInfo ri : resInfos.values()) { - if(ri.getResourceName() == null) { - incompleteResInfos.add(ri); - } - } - - if(!incompleteResInfos.isEmpty()) { - fillInResInfos(incompleteResInfos, allJars); - } - - // if any of the resource infos still don't have a name, take it from - // the class name. - for(ResourceInfo ri : incompleteResInfos) { - if(ri.getResourceName() == null) { - ri.resourceName = ri.resourceClassName.substring( - ri.resourceClassName.lastIndexOf('.') + 1); - } - } - - // finally, we have the complete list of ResourceInfos - resourceInfoList.addAll(resInfos.values()); - } - catch(IOException ioe) { - valid = false; - log.error("Problem while parsing plugin " + toString() + "!\n" - + ioe.toString() + "\nPlugin not available!"); - } - catch(JDOMException jde) { - valid = false; - log.error("Problem while parsing plugin " + toString() + "!\n" - + jde.toString() + "\nPlugin not available!"); - } - catch(Exception e) { - valid = false; - log.error("Problem while parsing plugin " + toString() + "!\n" - + e.toString() + "\nPlugin not available!"); - } - } - - protected void scanJar(URL jarUrl, Map<String, ResourceInfo> resInfos) throws IOException { - JarInputStream jarInput = new JarInputStream(jarUrl.openStream(), false); - JarEntry entry = null; - while((entry = jarInput.getNextJarEntry()) != null) { - String entryName = entry.getName(); - if(entryName != null && entryName.endsWith(".class")) { - final String className = entryName.substring(0, - entryName.length() - 6).replace('/', '.'); - if(!resInfos.containsKey(className)) { - ClassReader classReader = new ClassReader(jarInput); - ResourceInfo resInfo = new ResourceInfo(null, className, null); - ResourceInfoVisitor visitor = new ResourceInfoVisitor(resInfo); - - classReader.accept(visitor, ClassReader.SKIP_CODE | - ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); - if(visitor.isCreoleResource()) { - resInfos.put(className, resInfo); - } - } - } - } - - jarInput.close(); - } - - protected void fillInResInfos(List<ResourceInfo> incompleteResInfos, - List<String> allJars) throws IOException { - // now create a temporary class loader with all the JARs (scanned or - // not), so we can look up all the referenced classes in the normal - // way and read their CreoleResource annotations (if any). - URL[] jarUrls = new URL[allJars.size()]; - for(int i = 0; i < jarUrls.length; i++) { - jarUrls[i] = new URL(getBaseURL(), allJars.get(i)); - } - - // TODO shouldn't we use a proper temp gate class loader which we - // can then throw away? - try(URLClassLoader tempClassLoader = - new URLClassLoader(jarUrls, Gate.class.getClassLoader());) { - for(ResourceInfo ri : incompleteResInfos) { - String classFile = - ri.getResourceClassName().replace('.', '/') + ".class"; - InputStream classStream = - tempClassLoader.getResourceAsStream(classFile); - if(classStream != null) { - ClassReader classReader = new ClassReader(classStream); - ClassVisitor visitor = new ResourceInfoVisitor(ri); - classReader.accept(visitor, ClassReader.SKIP_CODE - | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); - classStream.close(); - } - } - } - } - - public static class Directory extends Plugin { - - public Directory(URL directoryURL) { - try { - baseURL = Gate.normaliseCreoleUrl(directoryURL).toURI(); - } catch(URISyntaxException e) { - //this should never happen but.... - throw new RuntimeException(e); - } - } - - @Override - public Document getCreoleXML() throws Exception { - SAXBuilder builder = new SAXBuilder(false); - URL creoleFileURL = new URL(getBaseURL(), "creole.xml"); - return builder.build(creoleFileURL); - } - - @Override - public String getName() { - if(name != null) return name; - - // url.getPath() works for jar URLs; url.toURI().getPath() doesn't - // because jars aren't considered "hierarchical" - name = getBaseURL().getPath(); - if(name.endsWith("/")) { - name = name.substring(0, name.length() - 1); - } - int lastSlash = name.lastIndexOf("/"); - if(lastSlash != -1) { - name = name.substring(lastSlash + 1); - } - try { - // convert to (relative) URI and extract path. This will - // decode any %20 escapes in the name. - name = new URI(name).getPath(); - } catch(URISyntaxException ex) { - // ignore, this should have been checked when adding the URL! - } - return name; - } - } - - public static class Maven extends Plugin implements Serializable { - - private static final long serialVersionUID = -6944695755723023537L; - - 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) { - this.group = group; - this.artifact = artifact; - this.version = version; - - name = group+":"+artifact+":"+version; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((artifact == null) ? 0 : artifact.hashCode()); - result = prime * result + ((group == null) ? 0 : group.hashCode()); - result = prime * result + ((version == null) ? 0 : version.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; - Maven other = (Maven)obj; - if(artifact == null) { - if(other.artifact != null) return false; - } else if(!artifact.equals(other.artifact)) return false; - if(group == null) { - if(other.group != null) return false; - } else if(!group.equals(other.group)) return false; - if(version == null) { - if(other.version != null) return false; - } else if(!version.equals(other.version)) return false; - return true; - } - - @Override - 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(artifactURL.toURI(), new HashMap<>());) { - - Path target = Paths.get(dir.toURI()); - Path pathInZip = zipFs.getPath("/resources"); - - Files.walkFileTree(pathInZip, new SimpleFileVisitor<Path>() { - @Override - public FileVisitResult visitFile(Path filePath, - BasicFileAttributes attrs) throws IOException { - // Make sure that we conserve the hierachy of files and folders - // inside the zip - Path relativePathInZip = pathInZip.relativize(filePath); - Path targetPath = target.resolve(relativePathInZip.toString()); - Files.createDirectories(targetPath.getParent()); - - // And extract the file - Files.copy(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING); - - return FileVisitResult.CONTINUE; - } - }); - } - } - - @Override - public boolean hasResources() { - try (FileSystem zipFs = FileSystems.newFileSystem(artifactURL.toURI(), new HashMap<>());) { - Path pathInZip = zipFs.getPath("/resources"); - return Files.isDirectory(pathInZip); - } - catch (URISyntaxException | IOException e) { - return false; - } - } - - public URL getArtifactURL() throws Exception { - if (artifactURL == null) { - getCreoleXML(); - } - - return artifactURL; - } - - @Override - public Document getCreoleXML() throws Exception { - Artifact artifactObj = - new DefaultArtifact(group, artifact, "jar", version); - - Dependency dependency = new Dependency(artifactObj, "runtime"); - - List<RemoteRepository> repos = getRepositoryList(); - - ArtifactRequest artifactRequest = new ArtifactRequest(artifactObj, repos, null); - - RepositorySystem repoSystem = getRepositorySystem(); - RepositorySystemSession repoSession = getRepositorySession(repoSystem, workspace); - - - ArtifactResult artifactResult = - repoSystem.resolveArtifact(repoSession, - artifactRequest); - - //baseURL = new URI("creole://"+group+";"+artifact+";"+version+"/"); - - artifactURL = - new URL("jar:" - + artifactResult.getArtifact().getFile().toURI().toURL() - + "!/"); - - baseURL = artifactURL.toURI(); - - // check it has a creole.xml at the root - URL directoryXmlFileUrl = new URL(artifactURL, "creole.xml"); - - InputStream creoleStream = null; - - try { - creoleStream = directoryXmlFileUrl.openStream(); - } catch(IOException ioe) { - throw new IOException(getBaseURL().toExternalForm() - + " does not exist so this artifact is not a GATE plugin"); - } - - CollectRequest collectRequest = new CollectRequest(dependency,repos); - - DependencyNode node = - repoSystem.collectDependencies(repoSession, - collectRequest).getRoot(); - - DependencyRequest dependencyRequest = new DependencyRequest(); - dependencyRequest.setRoot(node); - - DependencyResult result = - repoSystem.resolveDependencies(repoSession, - dependencyRequest); - - // get the creole.xml out of the jar and add jar elements for this - // jar (marked for scanning) and the dependencies - SAXBuilder builder = new SAXBuilder(false); - Document jdomDoc = - builder.build(creoleStream, getBaseURL().toExternalForm()); - - Element creoleRoot = jdomDoc.getRootElement(); - - for(ArtifactResult ar : result.getArtifactResults()) { - - Element jarElement = new Element("JAR"); - jarElement.setText(ar.getArtifact().getFile().toURI().toURL() - .toExternalForm()); - - if(ar.getArtifact().equals(artifactResult.getArtifact())) { - jarElement.setAttribute("SCAN", "true"); - } - - creoleRoot.addContent(jarElement); - } - - artifactObj = - new SubArtifact(artifactObj,"", "pom"); - - artifactRequest.setArtifact(artifactObj); - artifactResult = - repoSystem.resolveArtifact(repoSession, - artifactRequest); - - ModelBuildingRequest req = new DefaultModelBuildingRequest(); - req.setProcessPlugins(false); - req.setPomFile(artifactResult.getArtifact().getFile()); - req.setModelResolver(new SimpleModelResolver(repoSystem, - repoSession, new ArrayList<RemoteRepository>())); - req.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); - - ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance(); - Model model = modelBuilder.build(req).getEffectiveModel(); - - - if (model.getName() != null && !model.getName().trim().equals("")) name = model.getName(); - - /*System.out.println(model.getOrganization().getName()); - for (org.apache.maven.model.Repository r : model.getRepositories()) { - System.out.println(r.getName()); - } - for (License l : model.getLicenses()) { - System.out.println(l.getName()); - }*/ - - return jdomDoc; - } - - @Override - public String getName() { - return name; - } - } - - /** - * ClassVisitor that uses information from a CreoleResource annotation on the - * visited class (if such exists) to fill in the name and comment in the - * corresponding ResourceInfo. - */ - protected static class ResourceInfoVisitor extends EmptyVisitor { - private ResourceInfo resInfo; - - private boolean foundCreoleResource = false; - - private boolean isAbstract = false; - - public ResourceInfoVisitor(ResourceInfo resInfo) { - this.resInfo = resInfo; - } - - public boolean isCreoleResource() { - return foundCreoleResource && !isAbstract; - } - - /** - * Type descriptor for the CreoleResource annotation type. - */ - private static final String CREOLE_RESOURCE_DESC = - Type.getDescriptor(CreoleResource.class); - - /** - * Visit the class header, checking whether this is an abstract class or - * interface and setting the isAbstract flag appropriately. - */ - @Override - public void visit(int version, int access, String name, String signature, - String superName, String[] interfaces) { - isAbstract = ((access & - (Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT)) != 0); - } - - /** - * Visit an annotation on the class. - */ - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - // we've found a CreoleResource annotation on this class - if(desc.equals(CREOLE_RESOURCE_DESC)) { - foundCreoleResource = true; - return new AnnotationVisitor(Opcodes.ASM5) { - @Override - public void visit(String name, Object value) { - if(name.equals("name") && resInfo.resourceName == null) { - resInfo.resourceName = (String)value; - } - else if(name.equals("comment") && resInfo.resourceComment == null) { - resInfo.resourceComment = (String)value; - } - } - - @Override - public AnnotationVisitor visitAnnotation(String name, - String desc) { - // don't want to recurse into AutoInstance annotations - return this; - } - }; - } - else { - return super.visitAnnotation(desc, visible); - } - } - } - - public static class Component extends Plugin { - - private Class<? extends Resource> resourceClass; - - public Component(Class<? extends Resource> resourceClass) throws MalformedURLException { - this.resourceClass = resourceClass; - try { - baseURL = (new URL(resourceClass.getResource("/gate/creole/CreoleRegisterImpl.class"), ".")).toURI(); - } catch(URISyntaxException e) { - //this should never happen - throw new RuntimeException(e); - } - } - - @Override - public Document getCreoleXML() throws Exception, JDOMException { - Document doc = new Document(); - Element element; - doc.addContent(element = new Element("CREOLE-DIRECTORY")); - element.addContent(element = new Element("CREOLE")); - element.addContent(element = new Element("RESOURCE")); - Element classElement = new Element("CLASS"); - classElement.setText(resourceClass.getName()); - element.addContent(classElement); - - return doc; - } - - @Override - public String getName() { - return resourceClass.getName(); - } - - } - - public static void main(String args[]) throws Exception { - Gate.runInSandbox(true); - Gate.init(); - - Plugin annieMaven = new Plugin.Maven("uk.ac.gate.plugins", "annie", "9.0-SNAPSHOT"); - - Gate.getCreoleRegister().registerPlugin(annieMaven); - - System.out.println(annieMaven.getName()); - - File r = new File("testResources"); - System.out.println(annieMaven.hasResources()); - annieMaven.copyResources(r); - - } -} Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/Utils.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/Utils.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/Utils.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -18,6 +18,7 @@ import gate.annotation.AnnotationSetImpl; import gate.annotation.ImmutableAnnotationSetImpl; import gate.creole.ConditionalSerialController; +import gate.creole.Plugin; import gate.creole.RunningStrategy; import gate.util.FeatureBearer; import gate.util.GateRuntimeException; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleAnnotationHandler.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleAnnotationHandler.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleAnnotationHandler.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -18,7 +18,6 @@ import gate.Gate; import gate.Gate.ResourceInfo; -import gate.Plugin; import gate.Resource; import gate.creole.metadata.AutoInstance; import gate.creole.metadata.AutoInstanceParam; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleRegisterImpl.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleRegisterImpl.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/creole/CreoleRegisterImpl.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -22,7 +22,6 @@ import gate.Gate; import gate.Gate.ResourceInfo; import gate.LanguageResource; -import gate.Plugin; import gate.ProcessingResource; import gate.Resource; import gate.VisualResource; Copied: gate/branches/sawdust2/gate-core/src/main/java/gate/creole/Plugin.java (from rev 19984, gate/branches/sawdust2/gate-core/src/main/java/gate/Plugin.java) =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/creole/Plugin.java (rev 0) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/creole/Plugin.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -0,0 +1,754 @@ +/* + * Plugin.java + * + * Copyright (c) 2016, The University of Sheffield. See the file + * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt + * + * This file is part of GATE (see http://gate.ac.uk/), and is free + * software, licenced under the GNU Library General Public License, + * Version 3, June 2007 (in the distribution as file licence.html, + * and also available at http://gate.ac.uk/gate/licence.html). + * + * Mark A. Greenwood, 3rd April 2016 + */ + +package gate.creole; + +import static gate.util.maven.Utils.getRepositoryList; +import static gate.util.maven.Utils.getRepositorySession; +import static gate.util.maven.Utils.getRepositorySystem; + +import java.io.File; +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; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.maven.model.Model; +import org.apache.maven.model.building.DefaultModelBuilderFactory; +import org.apache.maven.model.building.DefaultModelBuildingRequest; +import org.apache.maven.model.building.ModelBuilder; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.repository.WorkspaceReader; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResult; +import org.eclipse.aether.util.artifact.SubArtifact; +import org.jdom.Attribute; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jdom.input.SAXBuilder; + +import gate.Gate; +import gate.Resource; +import gate.Utils; +import gate.Gate.ResourceInfo; +import gate.creole.metadata.CreoleResource; +import gate.util.asm.AnnotationVisitor; +import gate.util.asm.ClassReader; +import gate.util.asm.ClassVisitor; +import gate.util.asm.Opcodes; +import gate.util.asm.Type; +import gate.util.asm.commons.EmptyVisitor; +import gate.util.maven.SimpleModelResolver; + +public abstract class Plugin { + + protected static final Logger log = Logger.getLogger(Plugin.class); + + /** + * Is the plugin valid (i.e. is the location reachable and the + * creole.xml file parsable). + */ + protected transient boolean valid = true; + + /** + * This is the URL against which all relative URLs in the CREOLE + * metadata are resolved + */ + protected transient URI baseURL; + + protected transient String name; + + /** + * The list of {@link Gate.ResourceInfo} objects within this plugin + */ + protected transient List<ResourceInfo> resourceInfoList = null; + + /** + * The set of other plugins that must be loaded prior to the loading + * of this plugin + */ + protected transient Set<Plugin> requiredPlugins = null; + + public abstract org.jdom.Document getCreoleXML() throws Exception; + + public abstract String getName(); + + public Set<Plugin> getRequiredPlugins() { + if (requiredPlugins == null) parseCreole(); + + return requiredPlugins; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((baseURL == null) ? 0 : baseURL.hashCode()); + return result; + } + + @Override + public String toString() { + return getName(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(getClass() != obj.getClass()) return false; + Plugin other = (Plugin)obj; + if(baseURL == null) { + if(other.baseURL != null) return false; + } else if(!baseURL.equals(other.baseURL)) return false; + return true; + } + + public List<ResourceInfo> getResourceInfoList() { + if (resourceInfoList == null) parseCreole(); + + return resourceInfoList; + } + + public URL getBaseURL() { + try { + return baseURL.toURL(); + } catch(MalformedURLException e) { + // this should be impossible because of the way we have got hold of the + // URI + throw new RuntimeException(e); + } + } + + public boolean isValid() { + return valid; + } + + public void copyResources(File dir) throws IOException, URISyntaxException { + throw new UnsupportedOperationException("This plugin does not contain any resources that can be copied"); + } + + public boolean hasResources() { + return false; + } + + protected void parseCreole() { + + valid = true; + + resourceInfoList = new ArrayList<ResourceInfo>(); + requiredPlugins = new LinkedHashSet<Plugin>(); + + String relativePathMarker = "$relpath$"; + String gatehomePathMarker = "$gatehome$"; + String gatepluginsPathMarker = "$gateplugins$"; + + try { + org.jdom.Document creoleDoc = getCreoleXML(); + + final Map<String, ResourceInfo> resInfos = new LinkedHashMap<String, ResourceInfo>(); + List<Element> jobsList = new ArrayList<Element>(); + List<String> jarsToScan = new ArrayList<String>(); + List<String> allJars = new ArrayList<String>(); + jobsList.add(creoleDoc.getRootElement()); + while(!jobsList.isEmpty()) { + Element currentElem = jobsList.remove(0); + if(currentElem.getName().equalsIgnoreCase("JAR")) { + @SuppressWarnings("unchecked") + List<Attribute> attrs = currentElem.getAttributes(); + Iterator<Attribute> attrsIt = attrs.iterator(); + while(attrsIt.hasNext()) { + Attribute attr = attrsIt.next(); + if(attr.getName().equalsIgnoreCase("SCAN") && attr.getBooleanValue()) { + jarsToScan.add(currentElem.getTextTrim()); + break; + } + } + allJars.add(currentElem.getTextTrim()); + } + else if(currentElem.getName().equalsIgnoreCase("RESOURCE")) { + // we don't go deeper than resources so no recursion here + String resName = currentElem.getChildTextTrim("NAME"); + String resClass = currentElem.getChildTextTrim("CLASS"); + String resComment = currentElem.getChildTextTrim("COMMENT"); + if(!resInfos.containsKey(resClass)) { + // create the handler + ResourceInfo rHandler = + new ResourceInfo(resName, resClass, resComment); + resInfos.put(resClass, rHandler); + } + } + else if(currentElem.getName().equalsIgnoreCase("REQUIRES")) { + + if (currentElem.getAttribute("GROUP") != null) { + //TODO probably need more error checking here + requiredPlugins.add(new Plugin.Maven(currentElem + .getAttributeValue("GROUP"), currentElem + .getAttributeValue("ARTIFACT"), currentElem + .getAttributeValue("VERSION"))); + } + else { + URL url = null; + String urlString = currentElem.getTextTrim(); + if(urlString.startsWith(relativePathMarker)) { + url = + new URL(getBaseURL(), urlString.substring(relativePathMarker + .length())); + } else if(urlString.startsWith(gatehomePathMarker)) { + URL gatehome = Gate.getGateHome().toURI().toURL(); + url = + new URL(gatehome, + urlString.substring(gatehomePathMarker.length())); + } else if(urlString.startsWith(gatepluginsPathMarker)) { + URL gateplugins = Gate.getPluginsHome().toURI().toURL(); + url = + new URL(gateplugins, urlString.substring(gatepluginsPathMarker + .length())); + } else { + url = new URL(getBaseURL(), urlString); + } + + requiredPlugins.add(new Plugin.Directory(url)); + + Utils.logOnce(log, Level.WARN, "Dependencies on other plugins via URL is deprecated ("+getName()+" plugin)"); + } + } + else { + // this is some higher level element -> simulate recursion + // we want Depth-first-search so we need to add at the beginning + @SuppressWarnings("unchecked") + List<Element> newJobsList = new ArrayList<Element>(currentElem.getChildren()); + newJobsList.addAll(jobsList); + jobsList = newJobsList; + } + } + + // now process the jar files with SCAN="true", looking for any extra + // CreoleResource annotated classes. + for(String jarFile : jarsToScan) { + URL jarUrl = new URL(getBaseURL(), jarFile); + scanJar(jarUrl, resInfos); + } + + // see whether any of the ResourceInfo objects are still incomplete + // (don't have a name) + List<ResourceInfo> incompleteResInfos = new ArrayList<ResourceInfo>(); + for(ResourceInfo ri : resInfos.values()) { + if(ri.getResourceName() == null) { + incompleteResInfos.add(ri); + } + } + + if(!incompleteResInfos.isEmpty()) { + fillInResInfos(incompleteResInfos, allJars); + } + + // if any of the resource infos still don't have a name, take it from + // the class name. + for(ResourceInfo ri : incompleteResInfos) { + if(ri.getResourceName() == null) { + ri.setResourceName(ri.getResourceClassName().substring( + ri.getResourceClassName().lastIndexOf('.') + 1)); + } + } + + // finally, we have the complete list of ResourceInfos + resourceInfoList.addAll(resInfos.values()); + } + catch(IOException ioe) { + valid = false; + log.error("Problem while parsing plugin " + toString() + "!\n" + + ioe.toString() + "\nPlugin not available!"); + } + catch(JDOMException jde) { + valid = false; + log.error("Problem while parsing plugin " + toString() + "!\n" + + jde.toString() + "\nPlugin not available!"); + } + catch(Exception e) { + valid = false; + log.error("Problem while parsing plugin " + toString() + "!\n" + + e.toString() + "\nPlugin not available!"); + } + } + + protected void scanJar(URL jarUrl, Map<String, ResourceInfo> resInfos) throws IOException { + JarInputStream jarInput = new JarInputStream(jarUrl.openStream(), false); + JarEntry entry = null; + while((entry = jarInput.getNextJarEntry()) != null) { + String entryName = entry.getName(); + if(entryName != null && entryName.endsWith(".class")) { + final String className = entryName.substring(0, + entryName.length() - 6).replace('/', '.'); + if(!resInfos.containsKey(className)) { + ClassReader classReader = new ClassReader(jarInput); + ResourceInfo resInfo = new ResourceInfo(null, className, null); + ResourceInfoVisitor visitor = new ResourceInfoVisitor(resInfo); + + classReader.accept(visitor, ClassReader.SKIP_CODE | + ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + if(visitor.isCreoleResource()) { + resInfos.put(className, resInfo); + } + } + } + } + + jarInput.close(); + } + + protected void fillInResInfos(List<ResourceInfo> incompleteResInfos, + List<String> allJars) throws IOException { + // now create a temporary class loader with all the JARs (scanned or + // not), so we can look up all the referenced classes in the normal + // way and read their CreoleResource annotations (if any). + URL[] jarUrls = new URL[allJars.size()]; + for(int i = 0; i < jarUrls.length; i++) { + jarUrls[i] = new URL(getBaseURL(), allJars.get(i)); + } + + // TODO shouldn't we use a proper temp gate class loader which we + // can then throw away? + try(URLClassLoader tempClassLoader = + new URLClassLoader(jarUrls, Gate.class.getClassLoader());) { + for(ResourceInfo ri : incompleteResInfos) { + String classFile = + ri.getResourceClassName().replace('.', '/') + ".class"; + InputStream classStream = + tempClassLoader.getResourceAsStream(classFile); + if(classStream != null) { + ClassReader classReader = new ClassReader(classStream); + ClassVisitor visitor = new ResourceInfoVisitor(ri); + classReader.accept(visitor, ClassReader.SKIP_CODE + | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + classStream.close(); + } + } + } + } + + public static class Directory extends Plugin { + + public Directory(URL directoryURL) { + try { + baseURL = Gate.normaliseCreoleUrl(directoryURL).toURI(); + } catch(URISyntaxException e) { + //this should never happen but.... + throw new RuntimeException(e); + } + } + + @Override + public Document getCreoleXML() throws Exception { + SAXBuilder builder = new SAXBuilder(false); + URL creoleFileURL = new URL(getBaseURL(), "creole.xml"); + return builder.build(creoleFileURL); + } + + @Override + public String getName() { + if(name != null) return name; + + // url.getPath() works for jar URLs; url.toURI().getPath() doesn't + // because jars aren't considered "hierarchical" + name = getBaseURL().getPath(); + if(name.endsWith("/")) { + name = name.substring(0, name.length() - 1); + } + int lastSlash = name.lastIndexOf("/"); + if(lastSlash != -1) { + name = name.substring(lastSlash + 1); + } + try { + // convert to (relative) URI and extract path. This will + // decode any %20 escapes in the name. + name = new URI(name).getPath(); + } catch(URISyntaxException ex) { + // ignore, this should have been checked when adding the URL! + } + return name; + } + } + + public static class Maven extends Plugin implements Serializable { + + private static final long serialVersionUID = -6944695755723023537L; + + 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) { + this.group = group; + this.artifact = artifact; + this.version = version; + + name = group+":"+artifact+":"+version; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((artifact == null) ? 0 : artifact.hashCode()); + result = prime * result + ((group == null) ? 0 : group.hashCode()); + result = prime * result + ((version == null) ? 0 : version.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; + Maven other = (Maven)obj; + if(artifact == null) { + if(other.artifact != null) return false; + } else if(!artifact.equals(other.artifact)) return false; + if(group == null) { + if(other.group != null) return false; + } else if(!group.equals(other.group)) return false; + if(version == null) { + if(other.version != null) return false; + } else if(!version.equals(other.version)) return false; + return true; + } + + @Override + 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(artifactURL.toURI(), new HashMap<>());) { + + Path target = Paths.get(dir.toURI()); + Path pathInZip = zipFs.getPath("/resources"); + + Files.walkFileTree(pathInZip, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path filePath, + BasicFileAttributes attrs) throws IOException { + // Make sure that we conserve the hierachy of files and folders + // inside the zip + Path relativePathInZip = pathInZip.relativize(filePath); + Path targetPath = target.resolve(relativePathInZip.toString()); + Files.createDirectories(targetPath.getParent()); + + // And extract the file + Files.copy(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING); + + return FileVisitResult.CONTINUE; + } + }); + } + } + + @Override + public boolean hasResources() { + try (FileSystem zipFs = FileSystems.newFileSystem(artifactURL.toURI(), new HashMap<>());) { + Path pathInZip = zipFs.getPath("/resources"); + return Files.isDirectory(pathInZip); + } + catch (URISyntaxException | IOException e) { + return false; + } + } + + public URL getArtifactURL() throws Exception { + if (artifactURL == null) { + getCreoleXML(); + } + + return artifactURL; + } + + @Override + public Document getCreoleXML() throws Exception { + Artifact artifactObj = + new DefaultArtifact(group, artifact, "jar", version); + + Dependency dependency = new Dependency(artifactObj, "runtime"); + + List<RemoteRepository> repos = getRepositoryList(); + + ArtifactRequest artifactRequest = new ArtifactRequest(artifactObj, repos, null); + + RepositorySystem repoSystem = getRepositorySystem(); + RepositorySystemSession repoSession = getRepositorySession(repoSystem, workspace); + + + ArtifactResult artifactResult = + repoSystem.resolveArtifact(repoSession, + artifactRequest); + + //baseURL = new URI("creole://"+group+";"+artifact+";"+version+"/"); + + artifactURL = + new URL("jar:" + + artifactResult.getArtifact().getFile().toURI().toURL() + + "!/"); + + baseURL = artifactURL.toURI(); + + // check it has a creole.xml at the root + URL directoryXmlFileUrl = new URL(artifactURL, "creole.xml"); + + InputStream creoleStream = null; + + try { + creoleStream = directoryXmlFileUrl.openStream(); + } catch(IOException ioe) { + throw new IOException(getBaseURL().toExternalForm() + + " does not exist so this artifact is not a GATE plugin"); + } + + CollectRequest collectRequest = new CollectRequest(dependency,repos); + + DependencyNode node = + repoSystem.collectDependencies(repoSession, + collectRequest).getRoot(); + + DependencyRequest dependencyRequest = new DependencyRequest(); + dependencyRequest.setRoot(node); + + DependencyResult result = + repoSystem.resolveDependencies(repoSession, + dependencyRequest); + + // get the creole.xml out of the jar and add jar elements for this + // jar (marked for scanning) and the dependencies + SAXBuilder builder = new SAXBuilder(false); + Document jdomDoc = + builder.build(creoleStream, getBaseURL().toExternalForm()); + + Element creoleRoot = jdomDoc.getRootElement(); + + for(ArtifactResult ar : result.getArtifactResults()) { + + Element jarElement = new Element("JAR"); + jarElement.setText(ar.getArtifact().getFile().toURI().toURL() + .toExternalForm()); + + if(ar.getArtifact().equals(artifactResult.getArtifact())) { + jarElement.setAttribute("SCAN", "true"); + } + + creoleRoot.addContent(jarElement); + } + + artifactObj = + new SubArtifact(artifactObj,"", "pom"); + + artifactRequest.setArtifact(artifactObj); + artifactResult = + repoSystem.resolveArtifact(repoSession, + artifactRequest); + + ModelBuildingRequest req = new DefaultModelBuildingRequest(); + req.setProcessPlugins(false); + req.setPomFile(artifactResult.getArtifact().getFile()); + req.setModelResolver(new SimpleModelResolver(repoSystem, + repoSession, new ArrayList<RemoteRepository>())); + req.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); + + ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance(); + Model model = modelBuilder.build(req).getEffectiveModel(); + + + if (model.getName() != null && !model.getName().trim().equals("")) name = model.getName(); + + /*System.out.println(model.getOrganization().getName()); + for (org.apache.maven.model.Repository r : model.getRepositories()) { + System.out.println(r.getName()); + } + for (License l : model.getLicenses()) { + System.out.println(l.getName()); + }*/ + + return jdomDoc; + } + + @Override + public String getName() { + return name; + } + } + + /** + * ClassVisitor that uses information from a CreoleResource annotation on the + * visited class (if such exists) to fill in the name and comment in the + * corresponding ResourceInfo. + */ + protected static class ResourceInfoVisitor extends EmptyVisitor { + private ResourceInfo resInfo; + + private boolean foundCreoleResource = false; + + private boolean isAbstract = false; + + public ResourceInfoVisitor(ResourceInfo resInfo) { + this.resInfo = resInfo; + } + + public boolean isCreoleResource() { + return foundCreoleResource && !isAbstract; + } + + /** + * Type descriptor for the CreoleResource annotation type. + */ + private static final String CREOLE_RESOURCE_DESC = + Type.getDescriptor(CreoleResource.class); + + /** + * Visit the class header, checking whether this is an abstract class or + * interface and setting the isAbstract flag appropriately. + */ + @Override + public void visit(int version, int access, String name, String signature, + String superName, String[] interfaces) { + isAbstract = ((access & + (Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT)) != 0); + } + + /** + * Visit an annotation on the class. + */ + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + // we've found a CreoleResource annotation on this class + if(desc.equals(CREOLE_RESOURCE_DESC)) { + foundCreoleResource = true; + return new AnnotationVisitor(Opcodes.ASM5) { + @Override + public void visit(String name, Object value) { + if(name.equals("name") && resInfo.getResourceName() == null) { + resInfo.setResourceName((String)value); + } + else if(name.equals("comment") && resInfo.getResourceComment() == null) { + resInfo.setResourceComment((String)value); + } + } + + @Override + public AnnotationVisitor visitAnnotation(String name, + String desc) { + // don't want to recurse into AutoInstance annotations + return this; + } + }; + } + else { + return super.visitAnnotation(desc, visible); + } + } + } + + public static class Component extends Plugin { + + private Class<? extends Resource> resourceClass; + + public Component(Class<? extends Resource> resourceClass) throws MalformedURLException { + this.resourceClass = resourceClass; + try { + baseURL = (new URL(resourceClass.getResource("/gate/creole/CreoleRegisterImpl.class"), ".")).toURI(); + } catch(URISyntaxException e) { + //this should never happen + throw new RuntimeException(e); + } + } + + @Override + public Document getCreoleXML() throws Exception, JDOMException { + Document doc = new Document(); + Element element; + doc.addContent(element = new Element("CREOLE-DIRECTORY")); + element.addContent(element = new Element("CREOLE")); + element.addContent(element = new Element("RESOURCE")); + Element classElement = new Element("CLASS"); + classElement.setText(resourceClass.getName()); + element.addContent(classElement); + + return doc; + } + + @Override + public String getName() { + return resourceClass.getName(); + } + + } + + public static void main(String args[]) throws Exception { + Gate.runInSandbox(true); + Gate.init(); + + Plugin annieMaven = new Plugin.Maven("uk.ac.gate.plugins", "annie", "9.0-SNAPSHOT"); + + Gate.getCreoleRegister().registerPlugin(annieMaven); + + System.out.println(annieMaven.getName()); + + File r = new File("testResources"); + System.out.println(annieMaven.hasResources()); + annieMaven.copyResources(r); + + } +} Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/gui/MainFrame.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/gui/MainFrame.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/gui/MainFrame.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -155,13 +155,13 @@ import gate.GateConstants; import gate.LanguageResource; import gate.Main; -import gate.Plugin; import gate.ProcessingResource; import gate.Resource; import gate.VisualResource; import gate.creole.ANNIEConstants; import gate.creole.ConditionalSerialAnalyserController; import gate.creole.PackagedController; +import gate.creole.Plugin; import gate.creole.ResourceData; import gate.creole.ResourceInstantiationException; import gate.creole.annic.Constants; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/AvailablePlugins.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/AvailablePlugins.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/AvailablePlugins.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -19,8 +19,8 @@ import gate.Gate; import gate.Gate.ResourceInfo; -import gate.Plugin; import gate.creole.CreoleRegisterImpl; +import gate.creole.Plugin; import gate.gui.MainFrame; import gate.resources.img.svg.AddIcon; import gate.resources.img.svg.AvailableIcon; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/PluginUpdateManager.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/PluginUpdateManager.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/gui/creole/manager/PluginUpdateManager.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -15,7 +15,7 @@ package gate.gui.creole.manager; import gate.Gate; -import gate.Plugin; +import gate.creole.Plugin; import gate.gui.MainFrame; import gate.resources.img.svg.AddIcon; import gate.resources.img.svg.AdvancedIcon; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/util/GateClassLoader.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/util/GateClassLoader.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/util/GateClassLoader.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -39,9 +39,9 @@ import gate.Gate; import gate.Gate.ResourceInfo; -import gate.Plugin; import gate.Resource; import gate.creole.AbstractResource; +import gate.creole.Plugin; /** * GATE's class loader, which allows loading of classes over the net. A Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/ExpandCreoleXmls.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/ExpandCreoleXmls.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/ExpandCreoleXmls.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -1,8 +1,8 @@ package gate.util.ant; import gate.Gate; -import gate.Plugin; import gate.creole.CreoleAnnotationHandler; +import gate.creole.Plugin; import gate.creole.metadata.CreoleResource; import gate.util.CreoleXmlUpperCaseFilter; import gate.util.GateException; Modified: gate/branches/sawdust2/gate-core/src/main/java/gate/util/persistence/PersistenceManager.java =================================================================== --- gate/branches/sawdust2/gate-core/src/main/java/gate/util/persistence/PersistenceManager.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/main/java/gate/util/persistence/PersistenceManager.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -70,11 +70,11 @@ import gate.Gate; import gate.LanguageAnalyser; import gate.LanguageResource; -import gate.Plugin; import gate.ProcessingResource; import gate.VisualResource; import gate.creole.ConditionalController; import gate.creole.ConditionalSerialAnalyserController; +import gate.creole.Plugin; import gate.creole.ResourceInstantiationException; import gate.creole.SerialAnalyserController; import gate.event.ProgressListener; Modified: gate/branches/sawdust2/gate-core/src/test/java/gate/config/TestConfig.java =================================================================== --- gate/branches/sawdust2/gate-core/src/test/java/gate/config/TestConfig.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/test/java/gate/config/TestConfig.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -26,8 +26,8 @@ import gate.CreoleRegister; import gate.Gate; import gate.GateConstants; -import gate.Plugin; import gate.corpora.TestDocument; +import gate.creole.Plugin; import gate.util.Files; import gate.util.GateException; import gate.util.OptionsMap; Modified: gate/branches/sawdust2/gate-core/src/test/java/gate/creole/DynamicRegistrationTest.java =================================================================== --- gate/branches/sawdust2/gate-core/src/test/java/gate/creole/DynamicRegistrationTest.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/test/java/gate/creole/DynamicRegistrationTest.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -17,7 +17,6 @@ import gate.Document; import gate.Factory; import gate.Gate; -import gate.Plugin; import gate.ProcessingResource; import gate.creole.metadata.CreoleResource; import junit.framework.TestCase; Modified: gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreole.java =================================================================== --- gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreole.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreole.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -32,7 +32,6 @@ import gate.FeatureMap; import gate.Gate; import gate.LanguageResource; -import gate.Plugin; import gate.ProcessingResource; import gate.Resource; import gate.corpora.TestDocument; Modified: gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreoleAnnotationHandler.java =================================================================== --- gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreoleAnnotationHandler.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-core/src/test/java/gate/creole/TestCreoleAnnotationHandler.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -31,7 +31,6 @@ import org.w3c.dom.Node; import gate.Gate; -import gate.Plugin; import gate.corpora.TestDocument; import gate.util.GateException; import junit.framework.Test; Modified: gate/branches/sawdust2/gate-maven-plugin/src/main/java/uk/ac/gate/maven/DumpCreoleToXML.java =================================================================== --- gate/branches/sawdust2/gate-maven-plugin/src/main/java/uk/ac/gate/maven/DumpCreoleToXML.java 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/gate-maven-plugin/src/main/java/uk/ac/gate/maven/DumpCreoleToXML.java 2017-01-25 14:20:13 UTC (rev 19985) @@ -38,7 +38,7 @@ import gate.Gate; import gate.Gate.ResourceInfo; -import gate.Plugin; +import gate.creole.Plugin; import gate.creole.CreoleAnnotationHandler; import gate.util.GateClassLoader; import gate.util.asm.ClassReader; Modified: gate/branches/sawdust2/notes.txt =================================================================== --- gate/branches/sawdust2/notes.txt 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/notes.txt 2017-01-25 14:20:13 UTC (rev 19985) @@ -41,12 +41,8 @@ gate.swing.VerticalTextIcon gate.swing.WaitDialog -gate.util.Coordinates -gate.util.CorpusSaver gate.util.DocumentProcessor gate.util.LanguageAnalyserDocumentProcessor -gate.util.HtmlLinksExtractor -gate.util.JarFiles gate.util.LaxErrorHandler gate.util.TemplateLaxErrorHandler gate.util.LuckyException -- replace with RuntimeException @@ -54,9 +50,7 @@ gate.util.ObjectWriter gate.util.OrderByRestriction gate.util.Pair -gate.util.ProgressPrinter gate.util.RawEditorKit -gate.util.Restriction to move into plugins ==================== @@ -66,7 +60,9 @@ ========================= log.error() calls in MainFrame.loadApplicationAction just disappear so I've added a printStackTrace as well but it would be nice if we could fix the logging +Plugin.getCreoleXml() doesn't cache the result which could be a real performance issue Things still to do ================== alignment plugin has metadata in creole.xml not as annotations + Modified: gate/branches/sawdust2/pom.xml =================================================================== --- gate/branches/sawdust2/pom.xml 2017-01-25 13:51:29 UTC (rev 19984) +++ gate/branches/sawdust2/pom.xml 2017-01-25 14:20:13 UTC (rev 19985) @@ -1,6 +1,5 @@ - -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- this is the description of this plugin --> @@ -41,5 +40,6 @@ <module>Test-Utils</module> <module>Plugin_Base</module> <module>plugins</module> - </modules> -</project> + <module>benchmarking</module> + </modules> +</project> \ No newline at end of file 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