2 Replies Latest reply on Jan 14, 2008 7:57 AM by Tom Crosman

    Ant Task not dependent upon Eclipse plugins

    Tom Crosman Newbie

      Created an Ant Task for building Archive from the .projects file. I know Max and the team created one. This one is not dependent upon the Eclipse build system rather standard Ant jar, ear, war tasks.

      Hope this might be useful to someone. Note: I've tested it mainly on jar tasks so it might need tweaked for ears and wars a bit.


      Task Defs first then the java

      Example targets below.

      The first one builds a single archive defined in .packages : The property processArchive value is set
      Second no processArchive value is set so all defined archives are processed

      if "outputAntTargetsOnly" is set to true the console displays old style packaging-build.xml tasks.

       <!-- Archive Targets -->
       <target name="makeSAR" description="build SAR" depends="compile">
       <taskdef classname="gov.wapa.rmr.ant.JBossArchiveAntTask"
       name="jbossArchive" />
       <mkdir dir='dist' />
       <jbossArchive jbosspackages=".packages"
       outputAntTargetsOnly="false"
       processArchive="AuthenticationMBean.sar" />
       </target>
      
       <target name="makeAll" description="build Archives" depends="compile">
       <taskdef classname="gov.wapa.rmr.ant.JBossArchiveAntTask"
       name="jbossArchive" />
       <mkdir dir='dist' />
       <jbossArchive jbosspackages=".packages" outputAntTargetsOnly="false" />
       </target>
      ...................................................................................
      package gov.wapa.rmr.ant;
      
      import java.io.FileInputStream;
      import java.io.InputStreamReader;
      import java.util.Collection;
      import java.util.HashMap;
      
      import javax.xml.parsers.SAXParserFactory;
      
      import org.apache.tools.ant.BuildException;
      import org.apache.tools.ant.Task;
      import org.apache.tools.ant.taskdefs.Ear;
      import org.apache.tools.ant.taskdefs.Jar;
      import org.apache.tools.ant.taskdefs.War;
      import org.apache.tools.ant.taskdefs.Zip;
      import org.xml.sax.InputSource;
      import org.xml.sax.XMLReader;
      import org.xml.sax.helpers.DefaultHandler;
      
      /************************************************************
       * JBossArchiveAntTask is responsible for
       * JBossArchiveAntTask's functionality.
       *
       * @author Tom Crosman
       ***********************************************************/
      public class JBossArchiveAntTask extends Task {
       /**
       * Packages file defaults to ".packages"
       */
       private String jbossPackages = ".packages";
      
       private boolean outputAntTargetsOnly;
      
       private String processArchive;
      
       /**
       * Invoked by the handler to create a task specific to
       * the JBoss package. Initializes new task to the
       * parent environment. Package scope so only the handler
       * can invoke it.
       * @param type The ant task type to create.
       * @return the initialed task created.
       **/
       Zip createTask(String type) {
       Zip task = null;
       if ("jar".equals(type)) {
       task = new Jar();
       } else if ("war".equals(type)) {
       task = new War();
       } else if (type.indexOf("ear") != -1) {
       task = new Ear();
       } else if (type.indexOf("ejb") != -1) {
       task = new Jar();
       } else {
       throw new IllegalArgumentException("Unsupported type: " + type);
       }
      
       /** copy as much over as possible **/
       task.setDescription(getDescription());
       task.setLocation(getLocation());
       task.setOwningTarget(getOwningTarget());
       task.setProject(getProject());
       task.setRuntimeConfigurableWrapper(getRuntimeConfigurableWrapper());
       task.setTaskName(getTaskName());
       task.setTaskType(getTaskType());
      
       return task;
       }
      
       /**
       * {@inheritDoc}.
       * @see org.apache.tools.ant.Task#execute()
       */
       @Override
       public void execute() throws BuildException {
       JBossPackagesHandler hndlr = new JBossPackagesHandler(this);
       parseMe(hndlr);
       if (isOutputAntTargetsOnly()) {
       System.out
       .println("**************** No Packages Created -- Ant Targets Only ****************");
      
       HashMap<String, StringBuilder> antDefs = hndlr.getArchives();
       if (processArchive != null) {
       StringBuilder b = antDefs.get(processArchive);
       if (b != null) {
       System.out.println(b.toString());
       } else {
       System.out.println("No Archive: " + processArchive);
       }
       } else {
       Collection<StringBuilder> antTasks = antDefs.values();
       for (StringBuilder b : antTasks) {
       System.out.println(b.toString());
       }
       }
       System.out
       .println("**************** No Packages Created -- Ant Targets Only ****************");
       } else {
       HashMap<String, Zip> tasks = hndlr.getTasks();
       if (processArchive != null) {
       Zip task = tasks.get(processArchive);
       if (task != null) {
       task.execute();
       } else {
       System.out.println("No Archive: " + processArchive);
       }
       } else {
       for (Zip tsk : tasks.values()) {
       tsk.execute();
       }
       }
       }
       }
      
       /**
       * Property getter for jbossPackages.
       * @return Returns the jbossPackages.
       */
       public String getJbossPackages() {
       return jbossPackages;
       }
      
       /**
       * Property getter for processArchive.
       * @return Returns the processArchive.
       */
       public String getProcessArchive() {
       return processArchive;
       }
      
       /**
       * Property getter for outputTarget.
       * @return Returns the outputTarget.
       */
       public boolean isOutputAntTargetsOnly() {
       return outputAntTargetsOnly;
       }
      
       /**
       * Configures and launches the parsing of our xml file.
       *
       * @param handler the DocumentHandler that support parsing the
       * authenticate.dtd formatted xml file.
       */
       private void parseMe(DefaultHandler handler) {
       try {
       SAXParserFactory parseFact = SAXParserFactory.newInstance();
       XMLReader parser = parseFact.newSAXParser().getXMLReader();
       parser.setFeature("http://xml.org/sax/features/namespaces", true);
       parser.setFeature("http://xml.org/sax/features/validation", false);
       parser.setContentHandler(handler);
       parser
       .parse(new InputSource(
       new InputStreamReader(
       new FileInputStream(
       getProject()
       .getBaseDir()
       + "/" + jbossPackages))));
       } catch (Exception e) {
       e.printStackTrace();
      
       }
       }
      
       /**
       * Property setter for jbossPackages.
       * @param jbossPackages The jbossPackages to set.
       */
       public void setJbossPackages(String jbossPackages) {
       this.jbossPackages = jbossPackages;
       }
      
       /**
       * Property setter for outputTarget.
       * @param outputTarget The outputTarget to set.
       */
       public void setOutputAntTargetsOnly(boolean outputTarget) {
       this.outputAntTargetsOnly = outputTarget;
       }
      
       /**
       * Property setter for processArchive.
       * @param processArchive The processArchive to set.
       */
       public void setProcessArchive(String processArchive) {
       this.processArchive = processArchive;
       }
      
      }
      ....................................................................................................
      package gov.wapa.rmr.ant;
      
      import java.io.File;
      import java.util.HashMap;
      
      import org.apache.tools.ant.taskdefs.Zip;
      import org.apache.tools.ant.types.ZipFileSet;
      import org.xml.sax.Attributes;
      import org.xml.sax.SAXException;
      import org.xml.sax.helpers.DefaultHandler;
      
      /************************************************************
       * JBossPackagesHandler is responsible for
       * JBossPackagesHandler's functionality.
       *
       * @author Tom Crosman
       ***********************************************************/
      public class JBossPackagesHandler extends DefaultHandler {
      
       private final HashMap<String, StringBuilder> antTaskDefs;
      
       private final HashMap<String, Zip> tasks;
      
       private StringBuilder currArchive;
      
       private String folder;
      
       private HashMap<String, String> fileset;
      
       private Zip currentTask;
      
       private final JBossArchiveAntTask parentTask;
      
       /**
       * Creates a new JBossPackagesHandler.
       * @param bossArchiveAntTask
       */
       public JBossPackagesHandler(JBossArchiveAntTask bossArchiveAntTask) {
       this.parentTask = bossArchiveAntTask;
       antTaskDefs = new HashMap<String, StringBuilder>();
       tasks = new HashMap<String, Zip>();
       }
      
       /**
       * The doFileset method.
       */
       private void doFileset(String fldr) {
       ZipFileSet set = new ZipFileSet();
       set.setDir(new File(fileset.get("dir")));
       currArchive.append(" <zipfileset dir='");
       currArchive.append(fileset.get("xmlDir") + "' ");
       if (folder != null) {
       currArchive.append("prefix='" + folder + "' ");
       set.setPrefix(folder);
      
       }
       String includes = fileset.get("includes");
       String excludes = fileset.get("excludes");
       if (includes != null) {
       currArchive.append("includes='" + includes + "' ");
       set.setIncludes(includes);
       } else {
       set.setIncludes("");
       }
       if (excludes != null) {
       currArchive.append("excludes='" + excludes + "' ");
       set.setExcludes(excludes);
       } else {
       set.setExcludes("");
       }
      
       currArchive.append("/>\n");
       currentTask.addFileset(set);
       fileset = null;
       }
      
       /**
       * {@inheritDoc}.
       * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
       */
       @Override
       public void endElement(String uri, String localName, String name)
       throws SAXException {
       if ("package".equals(localName) && (currArchive != null)) {
       currArchive.append(" </jar>\n");
       currArchive.append("</target>\n");
      
       } else if ("folder".equals(localName)) {
       if (folder != null) {
       int slash = folder.lastIndexOf('/');
       if (slash == -1) {
       folder = null;
       } else {
       folder = folder.substring(0, slash);
       }
      
       }
      
       } else if ("fileset".equals(localName)) {
       // if (folder == null) {
       doFileset(folder);
       // }
       }
       }
      
       /**
       * Property getter for archives.
       * @return Returns the archives.
       */
       public HashMap<String, StringBuilder> getArchives() {
       return antTaskDefs;
       }
      
       /**
       * Property getter for tasks.
       * @return Returns the tasks.
       */
       public HashMap<String, Zip> getTasks() {
       return tasks;
       }
      
       /**
       * {@inheritDoc}.
       * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
       */
       @Override
       public void startElement(String uri, String localName, String name,
       Attributes attributes) throws SAXException {
       if ("package".equals(localName)) {
       String type = attributes.getValue("type");
       String taskName = attributes.getValue("name");
       currentTask = parentTask.createTask(type);
       tasks.put(taskName, currentTask);
      
       try {
       currArchive = new StringBuilder("<target name='");
      
       antTaskDefs.put(taskName, currArchive);
      
       String tName = attributes.getValue("name");
       currArchive.append(tName);
       currArchive.append("' description='build " + tName + "' >\n");
       String tmpToDir = attributes.getValue("todir");
       String toDir =
       tmpToDir.substring(tmpToDir.lastIndexOf("/") + 1);
       currArchive.append(" <mkdir dir='" + toDir + "' />\n");
      
       currArchive.append(" <jar destfile='" + toDir + "/" + tName
       + "'>\n");
      
       currentTask.setDestFile(new File(currentTask.getProject()
       .getBaseDir()
       + "/" + toDir + "/" + tName));
       } catch (IllegalArgumentException iae) {
       currArchive = null;
       currentTask = null;
       iae.printStackTrace();
       }
       } else if ("folder".equals(localName)) {
       if (folder == null) {
       folder = attributes.getValue("name");
       } else {
       folder = folder + "/" + attributes.getValue("name");
       }
       } else if ("fileset".equals(localName)) {
       fileset = new HashMap<String, String>();
       String dir = attributes.getValue("dir").substring(1);
       String xmlDir = dir.substring(dir.indexOf("/") + 1);
       String includes = attributes.getValue("includes");
       String excludes = attributes.getValue("excludes");
       fileset.put("includes", includes);
       fileset.put("excludes", excludes);
       fileset.put("dir", xmlDir);
       fileset.put("xmlDir", xmlDir);
      
       }
      
       }
      
      }
      .............................................................................
      


      T


        • 1. Re: Ant Task not dependent upon Eclipse plugins
          Rob Stryker Master

          Great job, wcrossman =D

          In my own defense, the current ant task doesn't need the eclipse build system ;) It just needs some jars from the archives.core plugin, and 1 eclipse jar ;)

          And it turns out only 1 class is needed from that eclipse jar, IPath =D

          Just for further information, the build process itself in archives.core does not look once at what type of package it is (jar, ear, war, sar, etc). It doesn't affect the build process one way or the other.... as of now. There may be extensions in the future that allow other actions to be performed before or after.

          Either way, great contrib. In the future I'll be trying to clean up the ant task entry point a bit, and if it's ok with you I may consider your code when doing so?

          - Rob

          • 2. Re: Ant Task not dependent upon Eclipse plugins
            Tom Crosman Newbie

            Rob,

            I just signed the contributor agreement so feel free to use the submitted code anyway you like.