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
56
57
58
59 properties.put(Analyzer.BUNDLE_VERSION, info.getVersion());
60
61
62 properties.put(Analyzer.REMOVE_HEADERS, Analyzer.INCLUDE_RESOURCE);
63
64 header(properties, Analyzer.BUNDLE_DESCRIPTION, info.getDescription());
65 header(properties, Analyzer.BUNDLE_NAME, parser.getKey());
66 header(properties, Analyzer.BUNDLE_VENDOR, info.getVendorName());
67 header(properties, Analyzer.BUNDLE_DOCURL, info.getVendorUrl());
68
69
70 StringBuilder classpath = new StringBuilder();
71 classpath.append(".");
72 for (Enumeration<JarEntry> e = context.getPluginJar().entries(); e.hasMoreElements();)
73 {
74 JarEntry entry = e.nextElement();
75 if (entry.getName().startsWith("META-INF/lib/") && entry.getName().endsWith(".jar"))
76 {
77 classpath.append(",").append(entry.getName());
78 }
79 }
80 header(properties, Analyzer.BUNDLE_CLASSPATH, classpath.toString());
81
82
83 properties.putAll(context.getBndInstructions());
84
85
86 properties.put(Analyzer.IMPORT_PACKAGE, addExtraImports(properties.getProperty(Analyzer.IMPORT_PACKAGE), context.getExtraImports()));
87
88
89 if (!properties.containsKey(Analyzer.EXPORT_PACKAGE))
90 {
91 properties.put(Analyzer.EXPORT_PACKAGE, addExtraExports(context.getExtraExports()));
92 }
93 builder.setProperties(properties);
94 }
95
96 builder.calcManifest();
97 Jar jar = builder.build();
98 Manifest mf = jar.getManifest();
99 ByteArrayOutputStream bout = new ByteArrayOutputStream();
100 mf.write(bout);
101 context.getFileOverrides().put("META-INF/MANIFEST.MF", bout.toByteArray());
102 }
103 catch (Exception t)
104 {
105 throw new PluginParseException("Unable to process plugin to generate OSGi manifest", t);
106 }
107 }
108
109 private String addExtraExports(List<String> extraExports)
110 {
111 StringBuilder result = new StringBuilder();
112 for (String exp : extraExports)
113 {
114 result.append(exp).append(",");
115 }
116 if (result.length() > 0)
117 {
118 result.deleteCharAt(result.length() - 1);
119 }
120
121 return result.toString();
122 }
123
124 private boolean isOsgiBundle(Manifest manifest) throws IOException
125 {
126 return manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME) != null;
127 }
128
129 private String addExtraImports(String imports, List<String> extraImports)
130 {
131 StringBuilder referrers = new StringBuilder();
132 for (String imp : extraImports)
133 {
134 referrers.append(imp).append(",");
135 }
136
137 if (imports != null && imports.length() > 0)
138 {
139 imports = referrers + imports;
140 }
141 else
142 {
143 imports = referrers.substring(0, referrers.length() - 1);
144 }
145 return imports;
146 }
147
148 private static void header(Properties properties, String key, Object value)
149 {
150 if (value == null)
151 {
152 return;
153 }
154
155 if (value instanceof Collection && ((Collection) value).isEmpty())
156 {
157 return;
158 }
159
160 properties.put(key, value.toString().replaceAll("[\r\n]", ""));
161 }
162
163 }