Coverage Report - org.geotoolkit.maven.jar.Collector
 
Classes in this File Line Coverage Branch Coverage Complexity
Collector
0 %
0/64
0 %
0/54
6,667
 
 1  
 /*
 2  
  *    Geotoolkit - An Open Source Java GIS Tookit
 3  
  *    http://www.geotoolkit.org
 4  
  *
 5  
  *    (C) 2005-2012, Open Source Geospatial Foundation (OSGeo)
 6  
  *    (C) 2009-2012, Geomatys
 7  
  *
 8  
  *    This library is free software; you can redistribute it and/or
 9  
  *    modify it under the terms of the GNU Lesser General Public
 10  
  *    License as published by the Free Software Foundation;
 11  
  *    version 2.1 of the License.
 12  
  *
 13  
  *    This library is distributed in the hope that it will be useful,
 14  
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  
  *    Lesser General Public License for more details.
 17  
  */
 18  
 package org.geotoolkit.maven.jar;
 19  
 
 20  
 import java.io.File;
 21  
 import java.io.FileFilter;
 22  
 import java.io.FileInputStream;
 23  
 import java.io.FileOutputStream;
 24  
 import java.io.IOException;
 25  
 import java.util.Set;
 26  
 
 27  
 import org.apache.maven.plugin.AbstractMojo;
 28  
 import org.apache.maven.plugin.MojoExecutionException;
 29  
 import org.apache.maven.project.MavenProject;
 30  
 import org.apache.maven.artifact.Artifact;
 31  
 
 32  
 
 33  
 /**
 34  
  * Copies <code>.jar</code> files in a single directory. Dependencies are copied as well,
 35  
  * except if already presents.
 36  
  *
 37  
  * @author Martin Desruisseaux (IRD, Geomatys)
 38  
  * @version 3.20
 39  
  *
 40  
  * @since 2.2
 41  
  *
 42  
  * @goal collect
 43  
  * @phase package
 44  
  * @requiresDependencyResolution runtime
 45  
  */
 46  0
 public class Collector extends AbstractMojo implements FileFilter {
 47  
     /**
 48  
      * The sub directory to create inside the "target" directory.
 49  
      */
 50  
     static final String SUB_DIRECTORY = "binaries";
 51  
 
 52  
     /**
 53  
      * The directory where JARs are to be copied. It should
 54  
      * be the "target" directory of the parent {@code pom.xml}.
 55  
      */
 56  
     private String collectDirectory;
 57  
 
 58  
     /**
 59  
      * Directory containing the generated JAR.
 60  
      *
 61  
      * @parameter expression="${project.build.directory}"
 62  
      * @required
 63  
      */
 64  
     private String outputDirectory;
 65  
 
 66  
     /**
 67  
      * Name of the generated JAR.
 68  
      *
 69  
      * @parameter expression="${project.build.finalName}"
 70  
      * @required
 71  
      */
 72  
     private String jarName;
 73  
 
 74  
     /**
 75  
      * The Maven project running this plugin.
 76  
      *
 77  
      * @parameter expression="${project}"
 78  
      * @required
 79  
      */
 80  
     private MavenProject project;
 81  
 
 82  
     /**
 83  
      * Copies the {@code .jar} files to the collect directory.
 84  
      *
 85  
      * @throws MojoExecutionException if the plugin execution failed.
 86  
      */
 87  
     @Override
 88  
     public void execute() throws MojoExecutionException {
 89  
         /*
 90  
          * Gets the parent "target" directory.
 91  
          */
 92  0
         MavenProject parent = project;
 93  0
         while (parent.hasParent()) {
 94  0
             parent = parent.getParent();
 95  
         }
 96  0
         collectDirectory = parent.getBuild().getDirectory();
 97  0
         if (collectDirectory.startsWith("${")) {
 98  0
             getLog().warn("Unresolved directory: " + collectDirectory);
 99  0
             return;
 100  
         }
 101  
         /*
 102  
          * Now collects the JARs.
 103  
          */
 104  
         try {
 105  0
             collect();
 106  0
         } catch (IOException e) {
 107  0
             throw new MojoExecutionException("Error collecting the JAR file.", e);
 108  0
         }
 109  0
     }
 110  
 
 111  
     /**
 112  
      * Implementation of the {@link #execute()} method.
 113  
      */
 114  
     private void collect() throws MojoExecutionException, IOException {
 115  
         /*
 116  
          * Make sure that we are collecting the JAR file from a module which produced
 117  
          * such file. Some modules use pom packaging, which do not produce any JAR file.
 118  
          */
 119  0
         final File jarFile = getProjectFile();
 120  0
         if (jarFile == null) {
 121  0
             return;
 122  
         }
 123  
         /*
 124  
          * Get the "target" directory of the parent pom.xml and make sure it exists.
 125  
          */
 126  0
         File collect = new File(collectDirectory);
 127  0
         if (!collect.exists()) {
 128  0
             if (!collect.mkdir()) {
 129  0
                 throw new MojoExecutionException("Failed to create target directory.");
 130  
             }
 131  
         }
 132  0
         if (collect.getCanonicalFile().equals(jarFile.getParentFile().getCanonicalFile())) {
 133  
             /*
 134  
              * The parent's directory is the same one than this module's directory.
 135  
              * In other words, this plugin is not executed from the parent POM. Do
 136  
              * not copy anything, since this is not the place where we want to
 137  
              * collect the JAR files.
 138  
              */
 139  0
             return;
 140  
         }
 141  
         /*
 142  
          * Creates a "binaries" subdirectory inside the "target" directory, then copy the
 143  
          * JAR file compiled by Maven. If an JAR file already existed, it will be deleted.
 144  
          */
 145  0
         collect = new File(collect, SUB_DIRECTORY);
 146  0
         if (!collect.exists()) {
 147  0
             if (!collect.mkdir()) {
 148  0
                 throw new MojoExecutionException("Failed to create binaries directory.");
 149  
             }
 150  
         }
 151  0
         File copy = new File(collect, jarFile.getName());
 152  0
         copy.delete();
 153  0
         copyFileToDirectory(jarFile, copy);
 154  
         /*
 155  
          * Copies the dependencies.
 156  
          */
 157  0
         final Set<Artifact> dependencies = project.getArtifacts();
 158  0
         if (dependencies != null) {
 159  0
             for (final Artifact artifact : dependencies) {
 160  0
                 final String scope = artifact.getScope();
 161  0
                 if (scope != null &&  // Maven 2.0.6 bug?
 162  
                    (scope.equalsIgnoreCase(Artifact.SCOPE_COMPILE) ||
 163  
                     scope.equalsIgnoreCase(Artifact.SCOPE_RUNTIME)))
 164  
                 {
 165  0
                     final File file = artifact.getFile();
 166  0
                     if (file != null) { // I'm not sure why the file is sometime null...
 167  0
                         copy = new File(collect, getFinalName(file, artifact));
 168  0
                         if (!copy.exists()) {
 169  
                             /*
 170  
                              * Copies the dependency only if it was not already copied. Note that
 171  
                              * the module's JAR was copied unconditionally above (because it may
 172  
                              * be the result of a new compilation).
 173  
                              */
 174  0
                             copyFileToDirectory(file, copy);
 175  
                         }
 176  
                     }
 177  
                 }
 178  0
             }
 179  
         }
 180  0
     }
 181  
 
 182  
     /**
 183  
      * Filters the content of the "target" directory in order to keep only the project
 184  
      * build result. We scan the directory because the final name may be different than
 185  
      * the {@link #jarName} declaration, because a classifier may have been added to the
 186  
      * name.
 187  
      * <p>
 188  
      * <b>Complain:</b> Why the hell peoples use the {@code ".jar"} file extension for what
 189  
      * should be plain source and javadoc {@code ".zip"} files?
 190  
      */
 191  
     @Override
 192  
     public boolean accept(final File pathname) {
 193  0
         final String name = pathname.getName();
 194  0
         return name.startsWith(jarName) && name.endsWith(".jar") &&
 195  
                 !name.endsWith("-sources.jar") && !name.endsWith("-javadoc.jar") && pathname.isFile();
 196  
     }
 197  
 
 198  
     /**
 199  
      * Returns the JAR file, or {@code null} if none.
 200  
      * In case of doubt, conservatively returns {@code null}.
 201  
      */
 202  
     private File getProjectFile() {
 203  0
         final File[] files = new File(outputDirectory).listFiles(this);
 204  0
         if (files != null && files.length == 1) {
 205  0
             return files[0];
 206  
         }
 207  0
         return null;
 208  
     }
 209  
 
 210  
     /**
 211  
      * Returns the name of the given file. If the given file is a snapshot, then the
 212  
      * {@code "SNAPSHOT"} will be replaced by the timestamp if possible.
 213  
      *
 214  
      * @param  file     The file from which to get the filename.
 215  
      * @param  artifact The artifact that produced the given file.
 216  
      * @return The filename to use.
 217  
      *
 218  
      * @since 3.18
 219  
      */
 220  
     private static String getFinalName(final File file, final Artifact artifact) {
 221  0
         String filename = file.getName();
 222  0
         final String baseVersion = artifact.getBaseVersion();
 223  0
         if (baseVersion != null) {
 224  0
             final int pos = filename.lastIndexOf(baseVersion);
 225  0
             if (pos >= 0) {
 226  0
                 final String version = artifact.getVersion();
 227  0
                 if (version != null && !baseVersion.equals(version)) {
 228  0
                     filename = filename.substring(0, pos) + version + filename.substring(pos + baseVersion.length());
 229  
                 }
 230  
             }
 231  
         }
 232  0
         return filename;
 233  
     }
 234  
 
 235  
     /**
 236  
      * Copies the given file to the given target file.
 237  
      *
 238  
      * @param file The source file to read.
 239  
      * @param copy The destination file to create.
 240  
      */
 241  
     private static void copyFileToDirectory(final File file, final File copy) throws IOException {
 242  0
         final FileInputStream in = new FileInputStream(file);
 243  0
         final FileOutputStream out = new FileOutputStream(copy);
 244  0
         final byte[] buffer = new byte[4096];
 245  
         int c;
 246  0
         while ((c = in.read(buffer)) >= 0) {
 247  0
             out.write(buffer, 0, c);
 248  
         }
 249  0
         out.close();
 250  0
         in.close();
 251  0
     }
 252  
 }