Package net.kindleit.gae

Source Code of net.kindleit.gae.EngineGoalBase

/* Copyright 2009 Kindleit.net Software Development
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.kindleit.gae;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;

import sun.misc.JarFilter;

/** Base MOJO class for working with the Google App Engine SDK.
*
* @author rhansen@kindleit.net
* @requiresProject true
*/
public abstract class EngineGoalBase extends AbstractMojo {
  public static final String PLUGIN_VERSION="0.9";

  protected static final String[] ARG_TYPE = new String[0];

  protected static final String APPENGINE_ARTIFACTID = "appengine-java-sdk";
  protected static final String APPENGINE_GROUPID = "com.google.appengine";

  protected static final String APPCFG_CLASS =
    "com.google.appengine.tools.admin.AppCfg";
  protected static final String KICKSTART_CLASS =
    "com.google.appengine.tools.admin.KickStart";

  protected static final String SDK_LIBS_NOTFOUND =
    "AppEngine tools SDK could not be found";
  protected static final String SDK_APPCFG_NOTFOUND =
    "AppCfg Class not found at: " + APPCFG_CLASS;
  protected static final String SDK_KICKSTART_NOTFOUND =
    "KickStart Class not found at: " + KICKSTART_CLASS;

  private static URLClassLoader classLoader;


  /** The Maven project reference.
   *
   * @parameter expression="${project}"
   * @required
   * @readonly
   */
  protected MavenProject project;

  /** The Maven settings reference.
   *
   * @parameter expression="${settings}"
   * @required
   * @readonly
   */
  protected Settings settings;

  /**
   * Location of the local repository.
   *
   * @parameter expression="${localRepository}"
   * @readonly
   * @required
   */
  protected ArtifactRepository local;

  /**
   * List of Remote Repositories used by the resolver
   *
   * @parameter expression="${project.remoteArtifactRepositories}"
   * @readonly
   * @required
   */
  protected List<?> remoteRepos;


  /**
   * Used to look up Artifacts in the remote repository.
   *
   * @component
   */
  protected org.apache.maven.artifact.factory.ArtifactFactory factory;

  /**
   * Used to look up Artifacts in the remote repository.
   *
   * @component
   */
  protected ArtifactResolver resolver;

  /**
   * To look up Archiver/UnArchiver implementations
   *
   * @component
   */
  protected ArchiverManager archiverManager;


  /** Overrides where the Project War Directory is located.
   *
   * @parameter expression="${project.build.directory}/${project.build.finalName}"
   * @required
   */
  protected String appDir;

  /** Specifies where the Google App Engine SDK is located.
   *
   * @parameter expression="${appengine.sdk.root}" default-value="${project.build.directory}/appEngine"
   * @required
   */
  protected String sdkDir;

  /** Version of the Google App Engine to use.
  *
  * @parameter expression="${gae.version}" default-value="1.2.6"
  * @required
  */
  protected String gaeVersion;

  /** Split large jar files (> 10M) into smaller fragments.
   *
   * @parameter expression="${gae.deps.split}" default-value="false"
   */
  protected boolean splitJars;

  /** The username to use. Will prompt if omitted.
   *
   * @parameter expression="${gae.email}"
   */
  protected String emailAccount;

  /** The server to connect to.
   *
   * @parameter expression="${gae.server}"
   */
  protected String uploadServer;

  /** Overrides the Host header sent with all RPCs.
   *
   * @parameter expression="${gae.host}"
   */
  protected String hostString;

  /** Do not delete temporary directory used in uploading.
   *
   * @parameter expression="${gae.keepTemps}" default-value="false"
   */
  protected boolean keepTempUploadDir;

  /** Always read the login password from stdin.
   *
   * @parameter expression="${gae.passin}" default-value="false"
   */
  protected boolean passIn;


  /**
   * @return Returns the project.
   */
  public MavenProject getProject ()
  {
      return project;
  }


  /** Passes command to the Google App Engine AppCfg runner.
  *
  * @param command command to run through AppCfg
  * @param commandArguments arguments to the AppCfg command.
   * @throws MojoExecutionException
  */
  protected final void runAppCfg(final String command,
      final String ... commandArguments) throws MojoExecutionException {

    final List<String> args = new ArrayList<String>();
    args.addAll(getAppCfgArgs());
    args.add(command);
    args.addAll(Arrays.asList(commandArguments));

    try {
      getEngineClass(APPCFG_CLASS, SDK_APPCFG_NOTFOUND)
        .getMethod("main", String[].class)
          .invoke(null, (Object) args.toArray(ARG_TYPE));
    } catch (final Exception e) {
      throw new MojoExecutionException("Unable to execute AppCfg command: " + command, e);
    }
  }

  /** Passes command to the Google App Engine KickStart runner.
   *
   * @param startClass command to run through KickStart
   * @param commandArguments arguments to the KickStart command.
   * @throws MojoExecutionException
   */
  protected final void runKickStart(final String startClass,
    final String ... commandArguments) throws MojoExecutionException {

    final List<String> args = new ArrayList<String>();
    args.add(startClass);
    args.addAll(getCommonArgs());
    args.addAll(Arrays.asList(commandArguments));

    try {
      getEngineClass(KICKSTART_CLASS, SDK_KICKSTART_NOTFOUND)
        .getMethod("main", String[].class)
          .invoke(null, (Object) args.toArray(ARG_TYPE));
    } catch (final Exception e) {
      throw new MojoExecutionException("Unable to execute Kickstart class: " + startClass, e);
    }
  }

  /** Generate all common Google AppEngine Task Parameters for use in all the
   * goals.
   *
   * @return List of arguments to add.
   */
  protected final List<String> getAppCfgArgs () {
    final List<String> args = getCommonArgs();


    addBooleanOption(args, "--disable_prompt", !settings.getInteractiveMode());

    addStringOption(args, "--email=", emailAccount);
    addStringOption(args, "--host=", hostString);
    addBooleanOption(args, "--passin", passIn);
    addBooleanOption(args, "--enable_jar_splitting", splitJars);
    addBooleanOption(args, "--retain_upload_dir", keepTempUploadDir);

    return args;
  }

  protected final List<String> getCommonArgs() {
    final List<String> args = new ArrayList<String>(8);

    args.add("--sdk_root=" + sdkDir);
    addStringOption(args, "--server=", uploadServer);

    return args;
  }

  private final void addBooleanOption(final List<String> args, final String key,
      final boolean var) {
    if (var) {
      args.add(key);
    }
  }

  private final void addStringOption(final List<String> args, final String key,
      final String var) {
    if (var != null && var.length() > 0) {
      args.add(key + var);
    }
  }

  protected Class<?> getEngineClass(final String clsName,
      final String clsErrorMsg) throws MojoExecutionException {
    try {
      return getClassLoader().loadClass(clsName);
    } catch (final ClassNotFoundException e) {
      throw new MojoExecutionException(clsErrorMsg, e);
    }
  }

  private ClassLoader getClassLoader() throws MojoExecutionException {
    synchronized (EngineGoalBase.class) {
      if (classLoader != null) {
        return classLoader;
      }
    }
    synchronized (EngineGoalBase.class) {
      try {
        final List<URL> urls = new ArrayList<URL>();

        for(final File jar : getSdkLibDir().listFiles(new JarFilter())) {
          urls.add(jar.toURI().toURL());
        }

        classLoader = new URLClassLoader(urls.toArray(new URL[0]));
      } catch (final MalformedURLException e) {
        throw new MojoExecutionException(SDK_LIBS_NOTFOUND, e);
      }
      return classLoader;
    }
  }

  private File getSdkLibDir() throws MojoExecutionException {
    final File sdkLibDir = new File(sdkDir);
    if (!sdkLibDir.exists()) {
      unpackSDK(sdkLibDir);
    }
    return sdkLibDir;
  }

  /**
   * This method gets the Artifact object and calls DependencyUtil.unpackFile.
   *
   * @param artifactItem
   *            containing the information about the Artifact to unpack.
   *
   * @throws MojoExecutionException
   *             with a message if an error occurs.
   *
   * @see #getArtifact
   * @see DependencyUtil#unpackFile(Artifact, File, File, ArchiverManager,
   *      Log)
   */
  private void unpackSDK (final File sdkLibDir) throws MojoExecutionException {
    Artifact sdkArtifact;
    try {
      sdkArtifact =
          factory.createArtifact(APPENGINE_GROUPID, APPENGINE_ARTIFACTID,
              gaeVersion, "compile", "zip");

      resolver.resolveAlways(sdkArtifact, remoteRepos, local);

    } catch ( final ArtifactResolutionException e ) {
      throw new MojoExecutionException( "Unable to resolve artifact.", e );

    } catch ( final ArtifactNotFoundException e ) {
      throw new MojoExecutionException( "Unable to find artifact.", e );
    }
    unpack(sdkArtifact.getFile(), sdkLibDir);
  }

  /** Unpacks the archive file.
   *
   * @param file File to be unpacked.
   * @param location Location where to put the unpacked files.
   */
  private void unpack (final File file, final File location)
  throws MojoExecutionException {
    try {
      getLog().info("Unpacking " + file.getPath()
          + " to\n  " + location.getPath());

      location.mkdirs();

      UnArchiver unArchiver;
      unArchiver = archiverManager.getUnArchiver(file);
      unArchiver.setSourceFile(file);
      unArchiver.setDestDirectory(location);
      unArchiver.extract();

    } catch (final NoSuchArchiverException e) {
      throw new MojoExecutionException("Unknown archiver type", e);

    } catch (final ArchiverException e) {
      e.printStackTrace();
      throw new MojoExecutionException("Error unpacking file: " + file
                                       + " to: " + location + "\r\n"
                                       + e.toString(), e);
    }
  }

}
TOP

Related Classes of net.kindleit.gae.EngineGoalBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.