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

Reply via email to