1 package com.atlassian.plugin.osgi.factory.transform.stage;
2
3 import aQute.lib.osgi.Analyzer;
4 import aQute.lib.osgi.Builder;
5 import aQute.lib.osgi.Jar;
6 import com.atlassian.plugin.PluginInformation;
7 import com.atlassian.plugin.PluginParseException;
8 import com.atlassian.plugin.osgi.factory.transform.PluginTransformationException;
9 import com.atlassian.plugin.osgi.factory.transform.TransformContext;
10 import com.atlassian.plugin.osgi.factory.transform.TransformStage;
11 import com.atlassian.plugin.parsers.XmlDescriptorParser;
12 import org.osgi.framework.Constants;
13
14 import java.io.ByteArrayOutputStream;
15 import java.io.IOException;
16 import java.util.Collection;
17 import java.util.Enumeration;
18 import java.util.List;
19 import java.util.Properties;
20 import java.util.jar.JarEntry;
21 import java.util.jar.Manifest;
22
23
24
25
26
27
28 public class GenerateManifestStage implements TransformStage
29 {
30 public void execute(TransformContext context) throws PluginTransformationException
31 {
32 Builder builder = new Builder();
33 try
34 {
35 builder.setJar(context.getPluginFile());
36
37
38 if (isOsgiBundle(builder.getJar().getManifest()))
39 {
40 String imports = addExtraImports(builder.getJar().getManifest().getMainAttributes().getValue(Constants.IMPORT_PACKAGE), context.getExtraImports());
41 builder.setProperty(Constants.IMPORT_PACKAGE, imports);
42 builder.mergeManifest(builder.getJar().getManifest());
43 }
44 else
45 {
46 XmlDescriptorParser parser = new XmlDescriptorParser(context.getDescriptorDocument());
47 PluginInformation info = parser.getPluginInformation();
48
49 Properties properties = new Properties();
50
51
52 properties.put("Spring-Context", "*;timeout:=60");
53 properties.put(Analyzer.BUNDLE_SYMBOLICNAME, parser.getKey());
54 properties.put(Analyzer.IMPORT_PACKAGE, "*;resolution:=optional");
55 properties.put(Analyzer.EXPORT_PACKAGE, "*");
56 properties.put(Analyzer.BUNDLE_VERSION, info.getVersion());
57
58
59 properties.put(Analyzer.REMOVE_HEADERS, Analyzer.INCLUDE_RESOURCE);
60
61 header(properties, Analyzer.BUNDLE_DESCRIPTION, info.getDescription());
62 header(properties, Analyzer.BUNDLE_NAME, parser.getKey());
63 header(properties, Analyzer.BUNDLE_VENDOR, info.getVendorName());
64 header(properties, Analyzer.BUNDLE_DOCURL, info.getVendorUrl());
65
66
67 StringBuilder classpath = new StringBuilder();
68 classpath.append(".");
69 for (Enumeration<JarEntry> e = context.getPluginJar().entries(); e.hasMoreElements();)
70 {
71 JarEntry entry = e.nextElement();
72 if (entry.getName().startsWith("META-INF/lib/") && entry.getName().endsWith(".jar"))
73 {
74 classpath.append(",").append(entry.getName());
75 }
76 }
77 header(properties, Analyzer.BUNDLE_CLASSPATH, classpath.toString());
78
79
80 properties.putAll(context.getBndInstructions());
81
82
83 properties.put(Analyzer.IMPORT_PACKAGE, addExtraImports(properties.getProperty(Analyzer.IMPORT_PACKAGE), context.getExtraImports()));
84 builder.setProperties(properties);
85 }
86
87 builder.calcManifest();
88 Jar jar = builder.build();
89 Manifest mf = jar.getManifest();
90 ByteArrayOutputStream bout = new ByteArrayOutputStream();
91 mf.write(bout);
92 context.getFileOverrides().put("META-INF/MANIFEST.MF", bout.toByteArray());
93 }
94 catch (Exception t)
95 {
96 throw new PluginParseException("Unable to process plugin to generate OSGi manifest", t);
97 }
98 }
99
100 private boolean isOsgiBundle(Manifest manifest) throws IOException
101 {
102 return manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME) != null;
103 }
104
105 private String addExtraImports(String imports, List<String> extraImports)
106 {
107 StringBuilder referrers = new StringBuilder();
108 for (String imp : extraImports)
109 {
110 referrers.append(imp).append(",");
111 }
112
113 if (imports != null && imports.length() > 0)
114 {
115 imports = referrers + imports;
116 }
117 else
118 {
119 imports = referrers.substring(0, referrers.length() - 1);
120 }
121 return imports;
122 }
123
124 private static void header(Properties properties, String key, Object value)
125 {
126 if (value == null)
127 {
128 return;
129 }
130
131 if (value instanceof Collection && ((Collection) value).isEmpty())
132 {
133 return;
134 }
135
136 properties.put(key, value.toString().replaceAll("[\r\n]", ""));
137 }
138
139 }