1   package com.atlassian.maven.plugins.amps.osgi;
2   
3   import aQute.lib.osgi.Constants;
4   import com.atlassian.maven.plugins.amps.AbstractAmpsMojo;
5   import static com.atlassian.maven.plugins.amps.util.FileUtils.file;
6   import org.apache.commons.io.IOUtils;
7   import org.apache.maven.plugin.MojoExecutionException;
8   import org.apache.maven.plugin.MojoFailureException;
9   import org.jfrog.maven.annomojo.annotations.MojoGoal;
10  import org.jfrog.maven.annomojo.annotations.MojoParameter;
11  
12  import java.io.File;
13  import java.io.FileInputStream;
14  import java.io.IOException;
15  import java.io.InputStream;
16  import java.util.jar.Manifest;
17  
18  @MojoGoal ("validate-manifest")
19  public class ValidateManifestMojo extends AbstractAmpsMojo
20  {
21      /**
22       * Whether to skip validation or not
23       */
24      @MojoParameter (expression = "${manifest.validation.skip}")
25      protected boolean skipManifestValidation = false;
26  
27      public void execute() throws MojoExecutionException, MojoFailureException
28      {
29          final File mfile = file(getMavenContext().getProject().getBuild().getOutputDirectory(), "META-INF", "MANIFEST.MF");
30  
31          // Only valid if the manifest exists
32          if (!skipManifestValidation && mfile.exists())
33          {
34              getLog().info("Manifest found, validating...");
35              InputStream mfin = null;
36              try
37              {
38                  checkManifestEndsWithNewLine(mfile);
39  
40                  mfin = new FileInputStream(mfile);
41                  Manifest mf = new Manifest(mfin);
42                  PackageImportVersionValidator validator = new PackageImportVersionValidator(getMavenContext().getProject(),
43                          getMavenContext().getLog(), getPluginInformation().getId());
44                  validator.validate(mf.getMainAttributes().getValue(Constants.IMPORT_PACKAGE));
45              }
46              catch (IOException e)
47              {
48                  throw new MojoExecutionException("Unable to read manifest", e);
49              }
50              finally
51              {
52                  IOUtils.closeQuietly(mfin);
53              }
54              getLog().info("Manifest validated");
55          }
56          else
57          {
58              getLog().info("No manifest found or validation skip flag specified, skipping validation");
59          }
60      }
61  
62      private void checkManifestEndsWithNewLine(final File mfile)
63              throws IOException, MojoExecutionException, MojoFailureException
64      {
65          InputStream is = null;
66          try
67          {
68              is = new FileInputStream(mfile);
69              final long bytesToSkip = mfile.length() - 1;
70              long bytesSkipped = is.skip(bytesToSkip);
71              if (bytesSkipped != bytesToSkip)
72              {
73                  throw new MojoExecutionException("Could not skip " + bytesToSkip + " bytes reading " + mfile.getAbsolutePath());
74              }
75              else if (is.read() != '\n')
76              {
77                  throw new MojoFailureException("Manifests must end with a new line. " + mfile.getAbsolutePath() + " doesn't.");
78              }
79          }
80          finally
81          {
82              IOUtils.closeQuietly(is);
83          }
84      }
85  }