All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.appops.maven.plugin.mojo.SlimJarMojo Maven / Gradle / Ivy

/*
 * AppOps is a Java framework to develop, deploy microservices with ease and is available for free
 * and common use developed by AinoSoft ( www.ainosoft.com )
 *
 * AppOps and AinoSoft are registered trademarks of Aino Softwares private limited, India.
 *
 * Copyright (C) <2016> 
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version along with applicable additional terms as
 * provisioned by GPL 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License and applicable additional terms
 * along with this program.
 *
 * If not, see  and 
 */

package org.appops.maven.plugin.mojo;


import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.appops.core.annotation.Slim;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.jar.JarArchiver;

/**
 * Mojo class for creating a slim jar from project classes.
 */
@Mojo(name = "slim-jar")
public class SlimJarMojo extends AbstractMojo {

  private final String defaultClassifier = "slim";
  private final String type = "jar";


  /**
   * Directory containing the generated JAR.
   */
  @Parameter(defaultValue = "${project.build.directory}", readonly = true)
  private File outputDirectory;

  /**
   * Name of the generated JAR.
   */
  @Parameter(defaultValue = "${project.build.finalName}", readonly = true)
  private String finalName;

  @Parameter(defaultValue = "${project}", readonly = true, required = true)
  private MavenProject project;

  /**
   * The {@link MavenSession}.
   */
  @Parameter(defaultValue = "${session}", readonly = true, required = true)
  private MavenSession session;

  /**
   * Directory containing the classes and resource files that should be packaged into the JAR.
   */
  @Parameter(defaultValue = "${project.build.outputDirectory}", required = true)
  private File classesDirectory;

  @Parameter(defaultValue = "${project.build.outputTimestamp}")
  private String outputTimestamp;

  /**
   * The archive configuration to use. See
   * Maven Archiver
   * Reference.
   */
  @Parameter
  private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();

  @Component
  private MavenProjectHelper projectHelper;

  /**
   * The Jar archiver.
   */
  @Component
  private Map archivers;



  /**
   * Returns the Jar file to generate, based on an optional classifier.
   *
   * @param basedir the output directory
   * @param resultFinalName the name of the ear file
   * @param classifier an optional classifier
   * @return the file to generate
   */
  protected File getJarFile(File basedir, String resultFinalName, String classifier) {
    if (basedir == null) {

      throw new IllegalArgumentException("basedir is not allowed to be null");
    }
    if (resultFinalName == null) {

      throw new IllegalArgumentException("finalName is not allowed to be null");
    }

    StringBuilder fileName = new StringBuilder(resultFinalName);
    fileName.append("-").append(classifier);
    fileName.append(".jar");
    return new File(basedir, fileName.toString());
  }

  /**
   * Generates the JAR.
   * 
   * @return The instance of File for the created archive file.
   * @throws MojoExecutionException in case of an error.
   */
  public File createArchive() throws MojoExecutionException {
    try {

      File jarFile = getJarFile(outputDirectory, finalName, defaultClassifier);

      MavenArchiver archiver = new MavenArchiver();
      archiver.setCreatedBy("Maven Jar Plugin", "org.apache.maven.plugins", "maven-jar-plugin");
      archiver.setArchiver((JarArchiver) archivers.get("jar"));
      archiver.setOutputFile(jarFile);
      archiver.configureReproducible(outputTimestamp);

      if (!classesDirectory.exists()) {

        getLog().warn("JAR will be empty - no content was marked for inclusion!");
      } else {

        List runtimeClasspathElements = project.getRuntimeClasspathElements();
        URL[] runtimeUrls = new URL[runtimeClasspathElements.size()];
        for (int i = 0; i < runtimeClasspathElements.size(); i++) {

          String element = (String) runtimeClasspathElements.get(i);
          runtimeUrls[i] = new File(element).toURI().toURL();
        }
        URLClassLoader loader =
            new URLClassLoader(runtimeUrls, Thread.currentThread().getContextClassLoader());
        keepSlimsOnly(archiver, classesDirectory.listFiles(), loader);
      }

      archiver.createArchive(session, project, archive);

      return jarFile;
    } catch (Exception e) {

      throw new MojoExecutionException("Error assembling JAR: " + e.getMessage());
    }
  }

  /**
   * Filters and include only slim classes to the jar.
   * 
   * @param archiver Maver archiver.
   * @param files List of files to be validated for slim inclusion.
   * @param loader Class loader.
   */
  private void keepSlimsOnly(MavenArchiver archiver, File[] files, URLClassLoader loader)
      throws ClassNotFoundException {
    for (File resource : files) {

      if (resource.isDirectory()) {

        keepSlimsOnly(archiver, resource.listFiles(), loader);
      } else if ("class".equals(FilenameUtils.getExtension(resource.getName()))) {

        String path = resource.getParentFile().getAbsolutePath() + "/"
            + FilenameUtils.getBaseName(resource.getName());
        path = path.replace(classesDirectory.getAbsolutePath(), "");
        path = path.startsWith("/") ? path.substring(1) : path;
        String className = path.replaceAll("/", "\\.");

        Class clazz = loader.loadClass(className);
        if (clazz.isAnnotationPresent(Slim.class)) {

          archiver.getArchiver().addFile(resource,
              path + "." + FilenameUtils.getExtension(resource.getName()));
        }
      }
    }
  }

  /**
   * Generates the JAR.
   * 
   * @throws MojoExecutionException in case of an error.
   */
  public void execute() throws MojoExecutionException {
    File jarFile = createArchive();
    projectHelper.attachArtifact(project, type, defaultClassifier, jarFile);
  }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy