BuildPlugin.java :  » Build » antmod » org » antmod » buildplugin » Java Open Source

Java Open Source » Build » antmod 
antmod » org » antmod » buildplugin » BuildPlugin.java
package org.antmod.buildplugin;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;

import org.antmod.util.AntUtil;
import org.apache.commons.io.FileUtils;
import org.apache.tools.ant.Project;

/**
 * Represents an Antmod build plugin.
 * 
 * @author Klaas Waslander
 */
public final class BuildPlugin {
  public final static int BUILDLEVEL_MODULE = 1111;
  public final static int BUILDLEVEL_RELEASE = 2222;

  private File pluginDir;

  private Project moduleAntProject;
  private ArrayList moduleAntTargets;

  private Project releaseAntProject;
  private ArrayList releaseAntTargets;

  /**
   * Only to be instantiated by this package;
   * this constructor uses reflection to get properties out of
   * the given object, assuming the 'otherBuildPlugin' is a
   * BuildPlugin loaded in another classloader instance. 
   */
  BuildPlugin(Project invokingAntProject, Object otherBuildPlugin) {
      this.pluginDir = (File)invokeGetter(otherBuildPlugin, "getPluginHome");
      this.moduleAntProject = (Project)invokeGetter(otherBuildPlugin, "getModuleAntProject");
      this.moduleAntTargets = (ArrayList)invokeGetter(otherBuildPlugin, "getModuleAntTargets");
      this.releaseAntProject = (Project)invokeGetter(otherBuildPlugin, "getReleaseAntProject");
      this.releaseAntTargets = (ArrayList)invokeGetter(otherBuildPlugin, "getReleaseAntTargets");
      /*
      if (moduleAntProject != null) {
          moduleAntProject.log("[ " + invokingAntProject.getProperty("ant.file") + "] CACHED BUILD PLUGIN: " + pluginDir, Project.MSG_WARN);
      }
      else if (releaseAntProject != null) {
          releaseAntProject.log("[ " + invokingAntProject.getProperty("ant.file") + "] CACHED BUILD PLUGIN: " + pluginDir, Project.MSG_WARN);
      }
      */
  }

  /** Only to be instantiated by this package */
  BuildPlugin(Project antProject, File pluginDirectory) {
      //antProject.log("[ " + antProject.getProperty("ant.file") + "] NEW BUILD PLUGIN: " + pluginDirectory, Project.MSG_WARN);
    this.pluginDir = pluginDirectory;

    // analyze buildfiles
    //System.err.println("Scanning modulebuild.xml of " + getName() + "...");
    File modulebuildFile = new File(pluginDirectory, "modulebuild.xml");
    if (modulebuildFile.exists()) {
      this.moduleAntProject = AntUtil.getAntProject(antProject, modulebuildFile, true);
      if (this.moduleAntProject == null) {
        throw new RuntimeException("modulebuild.xml for plugin " + getName() + " not found or initialized");
      }
        //AntUtil.inheritRefs(antProject, this.moduleAntProject);
      this.moduleAntProject.setProperty("antmod.plugins." + getName() + ".home", pluginDirectory.getAbsolutePath());
      this.moduleAntTargets = AntUtil.getAntTargets(this.moduleAntProject);
    }

    //System.err.println("Scanning releaseebuild.xml of " + getName() + "...");
    File releasebuildFile = new File(pluginDirectory, "releasebuild.xml");
    if (releasebuildFile.exists()) {
      this.releaseAntProject = AntUtil.getAntProject(antProject, releasebuildFile, true);
      if (this.releaseAntProject == null) {
        throw new RuntimeException("releasebuild.xml for plugin " + getName() + " not found or initialized");
      }
        //AntUtil.inheritRefs(antProject, this.releaseAntProject);
      this.releaseAntProject.setProperty("antmod.plugins." + getName() + ".home", pluginDirectory.getAbsolutePath());
      this.releaseAntTargets = AntUtil.getAntTargets(this.releaseAntProject);
    }
    //System.err.println("Scanning done for " + getName() + "!");
  }
  
  
  private static Object invokeGetter(Object instance, String getMethod) {
      Method m;
        try {
            m = instance.getClass().getMethod(getMethod, null);
            return m.invoke(instance, null);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
  }
  
  /**
   * The plugin home directory.
   */
  public File getPluginHome() {
      return pluginDir;
  }

  /**
   * The name of this build plugin.
   */
  public String getName() {
    return pluginDir.getName();
  }
  
  public Project getModuleAntProject() {
      return moduleAntProject;
  }
  public ArrayList getModuleAntTargets() {
      return moduleAntTargets;
  }
  public Project getReleaseAntProject() {
      return releaseAntProject;
  }
  public ArrayList getReleaseAntTargets() {
      return releaseAntTargets;
  }

  /**
   * Check whether this plugin has the given Ant target in the given ant file.
   * @param buildLevel Either BUILDLEVEL_MODULE or BUILDLEVEL_RELEASE
   * @param antTarget The name of the Ant target that possibly exists for the given buildlevel
   */  
  public boolean hasAntTarget(int buildLevel, String antTarget) {
    if (buildLevel == BUILDLEVEL_MODULE) {
      return this.moduleAntTargets != null && this.moduleAntTargets.contains(antTarget);
    } else if (buildLevel == BUILDLEVEL_RELEASE) {
      return this.releaseAntTargets != null && this.releaseAntTargets.contains(antTarget);
    }
    throw new IllegalArgumentException("Invalid build level - should be either BUILDLEVEL_MODULE or BUILDLEVEL_RELEASE");
  }
  
  /**
   * Invoke the given ant target of the plugin, properties created by the plugin are
   * pushed back into the parentProject for reuse elsewhere in the Antmod builds.
   * @param parentProject The project that receives the properties created by the plugin
   * @param buildLevel Either BUILDLEVEL_MODULE or BUILDLEVEL_RELEASE
   * @param antTarget The name of the Ant target to invoke for the given buildlevel
   */
  public void invokeAntTarget(Project parentProject, int buildLevel, String antTarget) {
    if (hasAntTarget(buildLevel, antTarget)) {
      // execute target
      if (buildLevel == BUILDLEVEL_MODULE) {
          /*
                this.moduleAntProject.setBaseDir(parentProject.getBaseDir());
                this.moduleAntProject.setProperty("basedir",parentProject.getBaseDir().getAbsolutePath());
          AntUtil.inheritRefs(parentProject, this.moduleAntProject);
        passBackProperties("antmod.", parentProject, this.moduleAntProject);

          this.moduleAntProject.executeTarget(antTarget);
        passBackProperties("antmod." + getName(), this.moduleAntProject, parentProject);
        */

          // REMIND: need to re-create Ant project every time, because basedir is not properly changeable it seems...
          Project newModuleProject = AntUtil.getAntProject(parentProject, new File(this.pluginDir, "modulebuild.xml"), true);
          AntUtil.inheritRefs(parentProject, newModuleProject);
          newModuleProject.executeTarget(antTarget);
        passBackProperties("antmod." + getName(), newModuleProject, parentProject);
      }
      else if (buildLevel == BUILDLEVEL_RELEASE) {
          /*
                this.releaseAntProject.setBaseDir(parentProject.getBaseDir());
                this.releaseAntProject.setProperty("basedir",parentProject.getBaseDir().getAbsolutePath());
          AntUtil.inheritRefs(parentProject, this.releaseAntProject);
        passBackProperties("antmod.", parentProject, this.releaseAntProject);

                this.releaseAntProject.executeTarget(antTarget);
        passBackProperties("antmod." + getName(), this.releaseAntProject, parentProject);
        */

          // REMIND: need to re-create Ant project every time, because basedir is not properly changeable it seems...
          Project newReleaseProject = AntUtil.getAntProject(parentProject, new File(this.pluginDir, "releasebuild.xml"), true); 
          AntUtil.inheritRefs(parentProject, newReleaseProject);
          newReleaseProject.executeTarget(antTarget);
        passBackProperties("antmod." + getName(), newReleaseProject, parentProject);
      }
      else {
        throw new IllegalArgumentException("Invalid build level - should be either BUILDLEVEL_MODULE or BUILDLEVEL_RELEASE");
      }
    }
  }
  
  /**
   * Get the contents of the "injectrelease.xml" file of this plugin.
   * @return Null if no injectrelease file existed
   */
  public String getInjectReleaseContents() {
      File injectRelease = new File(this.pluginDir, "injectrelease.xml");
      if (injectRelease.exists()) {
          try {
              return FileUtils.readFileToString(injectRelease, System.getProperty("file.encoding"));
          } catch (IOException ioe) {
              throw new IllegalStateException("Cannot read contents of file \"" + injectRelease.getPath() + "\": " + ioe);
          }
      }
      return null;
  }

  /**
   * Get the contents of the "injectmodule.xml" file of this plugin.
   * @return Null if no injectmodule file existed
   */
  public String getInjectModuleContents() {
      File injectModule = new File(this.pluginDir, "injectmodule.xml");
      if (injectModule.exists()) {
          try {
              return FileUtils.readFileToString(injectModule, System.getProperty("file.encoding"));
          } catch (IOException ioe) {
              throw new IllegalStateException("Cannot read contents of file \"" + injectModule.getPath() + "\": " + ioe);
          }
      }
      return null;
  }
  
  /** 'passes' only Antmod properties (starting with 'antmod.') from this Antmod plugin from 'fromProject' to 'toProject' */
  private void passBackProperties(String propnameStart, Project fromProject, Project toProject) {
    Hashtable props = fromProject.getProperties();
    Enumeration propNames = props.keys();
    String propName;
    while (propNames.hasMoreElements()) {
      propName = (String)propNames.nextElement();
      if (propName.startsWith(propnameStart)) {
        toProject.setProperty(propName, fromProject.getProperty(propName));
      }
    }
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.