Revision: 19594
http://sourceforge.net/p/gate/code/19594
Author: markagreenwood
Date: 2016-09-23 12:50:36 +0000 (Fri, 23 Sep 2016)
Log Message:
-----------
code clean up and documentation
Modified Paths:
--------------
gate/branches/sawdust2/gate-maven-plugin/src/main/java/uk/ac/gate/maven/DumpCreoleToXML.java
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
2016-09-23 01:22:02 UTC (rev 19593)
+++
gate/branches/sawdust2/gate-maven-plugin/src/main/java/uk/ac/gate/maven/DumpCreoleToXML.java
2016-09-23 12:50:36 UTC (rev 19594)
@@ -1,15 +1,15 @@
/*
- * DumpCreoleToXML.java
+ * DumpCreoleToXML.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
+ * 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).
+ * 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, 19th September 2016
+ * Mark A. Greenwood, 19th September 2016
*/
package uk.ac.gate.maven;
@@ -19,7 +19,6 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
-import java.net.URL;
import java.util.HashSet;
import java.util.Set;
@@ -30,6 +29,7 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
+import org.jdom.Comment;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
@@ -43,109 +43,188 @@
import gate.util.GateClassLoader;
import gate.util.asm.ClassReader;
+/**
+ * This Maven plugin creates a fully expanded copy of creole.xml and stores it
+ * inside META-INF/gate. This copy is useful for interoperability with other
+ * frameworks which might want to know the resources contained within the
plugin
+ * without needing an instance of GATE to extract the information via the API.
+ * Note that the generated file is for information only and in no way effects
+ * the operation of the plugin within GATE.
+ *
+ * @author Mark A. Greenwood
+ **/
@Mojo(name = "DumpCreoleToXML", defaultPhase = LifecyclePhase.PROCESS_CLASSES)
public class DumpCreoleToXML extends AbstractMojo {
private XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
- @Parameter(defaultValue = "${project.build.outputDirectory}", property =
"dir", required = true)
- private File dir;
+ @Parameter(defaultValue = "${project}", readonly = true, required = true)
+ private MavenProject project;
- @Parameter(defaultValue = "${project.groupId}", property = "group", required
= true)
- private String group;
+ @SuppressWarnings("unchecked")
+ public void execute() throws MojoExecutionException {
- @Parameter(defaultValue = "${project.artifactId}", property = "artifact",
required = true)
- private String artifact;
+ // get the output folder from the project (i.e. where everything goes
before
+ // the jar is built)
+ File dir = new File(project.getBuild().getOutputDirectory());
- @Parameter(defaultValue = "${project.version}", property = "version",
required = true)
- private String version;
+ // the normal creole.xml file which ends up at the root of the jar
+ File creoleXML = new File(dir, "creole.xml");
- @Parameter(defaultValue="${project}", readonly=true, required=true)
- private MavenProject project;
-
- public void execute() throws MojoExecutionException {
-
- File creoleXML = new File(dir, "creole.xml");
-
- if (creoleXML == null || !creoleXML.exists()) return;
-
+ // if there is no creole.xml then we quit as there is clearly nothing for
us
+ // to do so why bother carrying on
+ if(creoleXML == null || !creoleXML.exists()) return;
+
+ // this is the file we are going to create...
File expandedXML = new File(dir, "META-INF/gate/creole.xml");
+
+ // ...and we need to know there is somewhere to write it to
expandedXML.getParentFile().mkdirs();
-
+
+ // we'll need a temporary classloader to hold any referenced jars
GateClassLoader cl = null;
-
+
+ // if we can open the output file for writing then...
try (FileOutputStream fos = new FileOutputStream(expandedXML);) {
+
+ // initialise GATE and get a temportary classloader
Gate.init();
cl = Gate.getClassLoader().getDisposableClassLoader(dir.toString());
+
+ // add the output directory to the classloader so we can access the
+ // classes in the plugin we are currently processing
cl.addURL(dir.toURI().toURL());
-
- for (Artifact artifact :
(Set<Artifact>)project.getDependencyArtifacts()) {
- //This seems wrong as it's also adding GATE itself which we should
probably try and avoid
-
- //Why do we need this null check when running under jenkins?
- if (artifact != null && artifact.getFile() != null) {
+
+ for(Artifact artifact : (Set<Artifact>)project.getDependencyArtifacts())
{
+ // for each dependency of the plugin try and get a URL to it's jar file
+ // and add that to the classloader
+
+ // why do we need this null check when running under jenkins?
+ if(artifact != null && artifact.getFile() != null) {
cl.addURL(artifact.getFile().toURI().toURL());
}
}
-
- Plugin plugin = new TargetPlugin(creoleXML,cl);
- CreoleAnnotationHandler annotationHandler = new
CreoleAnnotationHandler(plugin);
+
+ // Now create a plugin...
+ Plugin plugin = new TargetPlugin(dir, project.getGroupId(),
+ project.getArtifactId(), project.getVersion());
+
+ // and a creole annotation handler
+ CreoleAnnotationHandler annotationHandler =
+ new CreoleAnnotationHandler(plugin);
+
+ // get a handle on the existing creole.xml file
Document creoleDoc = plugin.getCreoleXML();
- annotationHandler.processAnnotations(creoleDoc);
+
+ // process the java annotations to add them to the XML file
+ annotationHandler.processAnnotations(creoleDoc);
+
+ // save the document to the file
outputter.output(creoleDoc, fos);
} catch(Exception e) {
+ // goodness knows what happened so just throw up our hands in defeat and
+ // chuck the exception back
throw new MojoExecutionException("error expanding creole", e);
- }
- finally {
+ } finally {
+ // forget the classloader so we don't end up with lots of class
+ // definitions hanging around that we don't need
Gate.getClassLoader().forgetClassLoader(cl);
}
}
+ /**
+ * A plugin type we can use to extract information from an existing
creole.xml
+ * file and a directory of classes, while pretending to load the entire thing
+ * from a Maven repository.
+ */
@SuppressWarnings("serial")
- class TargetPlugin extends Plugin.Maven {
+ private static class TargetPlugin extends Plugin.Maven {
+
private File creoleFile;
- private GateClassLoader cl;
- public TargetPlugin(File creoleFile, GateClassLoader cl) throws
MalformedURLException {
+ public TargetPlugin(File dir, String group, String artifact, String
version)
+ throws MalformedURLException {
super(group, artifact, version);
- this.cl = cl;
- this.creoleFile = creoleFile;
- this.baseURL = new URL(creoleFile.toURI().toURL(), ".");
+
+ this.baseURL = dir.toURI().toURL();
+ this.creoleFile = new File(dir, "creole.xml");
}
@Override
public Document getCreoleXML() throws Exception {
+ // load the existing creole.xml file into memory
SAXBuilder builder = new SAXBuilder(false);
Document jdomDoc = builder.build(new FileInputStream(creoleFile),
baseURL.toExternalForm());
Element creoleRoot = jdomDoc.getRootElement();
- Set<String> resources = new HashSet<String>();
+
+ // add a comment to make it clear the expanded version is just for info
+ Comment comment = new Comment(
+ "this file is auto-generated, modifications will have no effect");
+ creoleRoot.addContent(0, comment);
+
+ // get the full directory path, ending with a separator
String dir = creoleFile.getParent();
if(!dir.endsWith(File.separator)) dir = dir + File.separator;
+
+ // recurse trhough the folder finding all the creole resources
+ Set<String> resources = new HashSet<String>();
scanDir(dir.length(), creoleFile.getParentFile(), resources);
+
for(String resource : resources) {
+ // for each creole resource...
+
+ // create a new entry in the XML file so that we know which classes to
+ // scan for further information
Element resourceElement = new Element("RESOURCE");
Element classElement = new Element("CLASS");
classElement.setText(resource);
resourceElement.addContent(classElement);
creoleRoot.addContent(resourceElement);
}
+
+ //return the part expanded creole.xml file
return jdomDoc;
}
+ /**
+ * Recursively scan through a directory structure to find all class files
+ * and store the names of those which are creole resources
+ *
+ * @param prefix
+ * the number of characters to remove from the beginning of the
+ * path in order to convert the path into a fully specified
+ * classname
+ * @param dir
+ * the current directory to scan for class files
+ * @param resources
+ * a set containing the classnames of any creole resources found
so
+ * far
+ * @throws IOException
+ * if an exception occurs reading a class file
+ */
private void scanDir(int prefix, File dir, Set<String> resources)
throws IOException {
+
for(File file : dir.listFiles()) {
+ // for each file in the current directory...
+
if(file.isDirectory()) {
+ // ... if it's a directory recurse into it
scanDir(prefix, file, resources);
} else if(file.getName().endsWith((".class"))) {
+ // ... if it's a class file convert the path to a classname
String className = file.getAbsolutePath().substring(prefix);
className =
className.substring(0, className.length() - 6).replace('/', '.');
+
+ // access the class so we can extract any annotations etc. from it
ClassReader classReader = new ClassReader(new FileInputStream(file));
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 the class is a creole resource store the classname
if(visitor.isCreoleResource()) {
resources.add(className);
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
_______________________________________________
GATE-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gate-cvs