1   package com.atlassian.maven.plugins.amps.osgi;
2   
3   import java.io.File;
4   import java.text.DateFormat;
5   import java.text.SimpleDateFormat;
6   import java.util.Date;
7   import java.util.HashMap;
8   import java.util.Map;
9   
10  import com.atlassian.maven.plugins.amps.AbstractAmpsMojo;
11  
12  import com.google.common.collect.ImmutableMap;
13  
14  import org.apache.maven.plugin.MojoExecutionException;
15  import org.apache.maven.plugin.MojoFailureException;
16  import org.apache.maven.project.MavenProject;
17  import org.jfrog.maven.annomojo.annotations.MojoGoal;
18  import org.jfrog.maven.annomojo.annotations.MojoParameter;
19  
20  import aQute.lib.osgi.Constants;
21  
22  import static com.atlassian.maven.plugins.amps.util.FileUtils.file;
23  
24  @MojoGoal("generate-manifest")
25  public class GenerateManifestMojo extends AbstractAmpsMojo
26  {
27      private static final String BUILD_DATE_ATTRIBUTE = "Atlassian-Build-Date";
28      
29      private static final DateFormat BUILD_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
30      
31      /**
32       * The BND instructions for the bundle.
33       */
34      @MojoParameter
35      private Map<String, String> instructions = new HashMap<String, String>();
36  
37      public void execute() throws MojoExecutionException, MojoFailureException
38      {
39          final MavenProject project = getMavenContext().getProject();
40          
41          // The Atlassian-Build-Date manifest attribute is used by the Atlassian licensing framework to determine
42          // chronological order of bundle versions.
43          final String buildDateStr = String.valueOf(BUILD_DATE_FORMAT.format(new Date()));
44          final Map<String, String> basicAttributes = ImmutableMap.of(BUILD_DATE_ATTRIBUTE, buildDateStr);
45          
46          if (!instructions.isEmpty())
47          {
48              getLog().info("Generating a manifest for this plugin");
49  
50              if (!instructions.containsKey(Constants.EXPORT_PACKAGE))
51              {
52                  instructions.put(Constants.EXPORT_PACKAGE, "");
53              }
54  
55              File metainfLib = file(project.getBuild().getOutputDirectory(), "META-INF", "lib");
56              if (metainfLib.exists())
57              {
58                  StringBuilder sb = new StringBuilder(".");
59                  for (File lib : metainfLib.listFiles())
60                  {
61                      sb.append(",").append("META-INF/lib/" + lib.getName());
62                  }
63                  instructions.put(Constants.BUNDLE_CLASSPATH, sb.toString());
64              }
65              getMavenGoals().generateBundleManifest(instructions, basicAttributes);
66          }
67          else
68          {
69              if (OsgiHelper.isAtlassianPlugin(project))
70              {
71                  getLog().warn("Atlassian plugin detected as the organisation name includes the string 'Atlassian'.  If " +
72                                "this is meant for production, you should add bundle " +
73                                "instructions specifically configuring what packages are imported and exported.  This " +
74                                "helps catch manifest generation bugs during the build rather than upon install.  The " +
75                                "bundle generation configuration can be specified " +
76                                "via the <instructions> element in the maven-" + getPluginInformation().getId()+"-plugin configuration.  For example:\n" +
77                                "    <configuration>\n" +
78                                "        <Import-Package>\n" +
79                                "            com.atlassian.myplugin*,\n" +
80                                "            com.library.optional.*;resolution:=optional,\n" +
81                                "            *\n" +
82                                "        </Import-Package>\n" +
83                                "    </configuration>\n\n" +
84                                "See the Maven bundle plugin (which is used under the covers) for more info: " +
85                                "http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html#ApacheFelixMavenBundlePlugin%28BND%29-Instructions");
86              }
87              else
88              {
89                  getLog().info("No manifest instructions found, adding only non-OSGi manifest attributes");
90              }
91              getMavenGoals().generateMinimalManifest(basicAttributes);
92          }
93      }
94  }