1 package com.atlassian.plugin.osgi.util;
2
3 import com.atlassian.plugin.osgi.hostcomponents.HostComponentRegistration;
4 import com.atlassian.plugin.osgi.container.PackageScannerConfiguration;
5 import com.atlassian.plugin.osgi.factory.OsgiPlugin;
6 import com.atlassian.plugin.util.ClassLoaderUtils;
7 import com.atlassian.plugin.util.ClassUtils;
8
9 import java.util.*;
10 import java.util.jar.Manifest;
11 import java.io.*;
12 import java.net.MalformedURLException;
13
14 import org.twdata.pkgscanner.ExportPackage;
15 import org.twdata.pkgscanner.PackageScanner;
16 import static org.twdata.pkgscanner.PackageScanner.jars;
17 import static org.twdata.pkgscanner.PackageScanner.include;
18 import static org.twdata.pkgscanner.PackageScanner.exclude;
19 import static org.twdata.pkgscanner.PackageScanner.packages;
20 import org.osgi.framework.Version;
21 import org.osgi.framework.Constants;
22 import org.osgi.framework.Bundle;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.commons.io.IOUtils;
26 import aQute.lib.osgi.Analyzer;
27 import aQute.lib.osgi.Jar;
28 import aQute.lib.header.OSGiHeader;
29
30 import javax.servlet.ServletContext;
31
32
33
34
35 public class OsgiHeaderUtil
36 {
37 static final String JDK_PACKAGES_PATH = "jdk-packages.txt";
38 static final String JDK6_PACKAGES_PATH = "jdk6-packages.txt";
39 static Log log = LogFactory.getLog(OsgiHeaderUtil.class);
40
41
42
43
44
45
46
47
48
49 public static String findReferredPackages(List<HostComponentRegistration> registrations) throws IOException
50 {
51 return findReferredPackages(registrations, Collections.<String, String>emptyMap());
52 }
53
54
55
56
57
58
59
60
61 public static String findReferredPackages(List<HostComponentRegistration> registrations, Map<String, String> packageVersions) throws IOException
62 {
63 StringBuffer sb = new StringBuffer();
64 Set<String> referredPackages = new HashSet<String>();
65 Set<String> referredClasses = new HashSet<String>();
66 if (registrations == null)
67 {
68 sb.append(",");
69 }
70 else
71 {
72 for (HostComponentRegistration reg : registrations)
73 {
74 Set<Class> classesToScan = new HashSet<Class>();
75
76
77 for (Class inf : reg.getMainInterfaceClasses())
78 ClassUtils.findAllTypes(inf, classesToScan);
79
80 for (Class inf : classesToScan)
81 {
82 String clsName = inf.getName().replace('.','/')+".class";
83 crawlReferenceTree(clsName, referredClasses, referredPackages, 1);
84 }
85 }
86 for (String pkg : referredPackages)
87 {
88 String version = packageVersions.get(pkg);
89 sb.append(pkg);
90 if (version != null) {
91 try {
92 Version.parseVersion(version);
93 sb.append(";version=").append(version);
94 } catch (IllegalArgumentException ex) {
95 log.info("Unable to parse version: "+version);
96 }
97 }
98 sb.append(",");
99 }
100 }
101 return sb.toString();
102 }
103
104
105
106
107
108
109
110
111
112
113 static void crawlReferenceTree(String className, Set<String> scannedClasses, Set<String> packageImports, int level) throws IOException
114 {
115 if (level <= 0)
116 {
117 return;
118 }
119
120 if (className.startsWith("java/"))
121 return;
122
123 if (scannedClasses.contains(className))
124 return;
125 else
126 scannedClasses.add(className);
127
128 if (log.isDebugEnabled())
129 log.debug("Crawling "+className);
130
131 InputStream in = null;
132 try
133 {
134 in = ClassLoaderUtils.getResourceAsStream(className, OsgiHeaderUtil.class);
135
136 if (in == null)
137 {
138 log.error("Cannot find interface "+className);
139 return;
140 }
141 Clazz clz = new Clazz(className, in);
142 packageImports.addAll(clz.getReferred().keySet());
143
144 Set<String> referredClasses = clz.getReferredClasses();
145 for (String ref : referredClasses)
146 crawlReferenceTree(ref, scannedClasses, packageImports, level-1);
147 }
148 finally
149 {
150 IOUtils.closeQuietly(in);
151 }
152
153 }
154
155
156
157
158
159
160
161
162 public static Map<String,Map<String,String>> parseHeader(String header)
163 {
164 return OSGiHeader.parseHeader(header);
165 }
166
167
168
169
170
171
172
173
174 public static String buildHeader(String key, Map<String,String> attrs)
175 {
176 StringBuilder fullPkg = new StringBuilder(key);
177 if (attrs != null && !attrs.isEmpty())
178 {
179 for (Map.Entry<String,String> entry : attrs.entrySet())
180 {
181 fullPkg.append(";");
182 fullPkg.append(entry.getKey());
183 fullPkg.append("=\"");
184 fullPkg.append(entry.getValue());
185 fullPkg.append("\"");
186 }
187 }
188 return fullPkg.toString();
189 }
190
191
192
193
194
195
196
197
198
199
200
201 public static String getPluginKey(Bundle bundle)
202 {
203 return getPluginKey(
204 bundle.getSymbolicName(),
205 bundle.getHeaders().get(OsgiPlugin.ATLASSIAN_PLUGIN_KEY),
206 bundle.getHeaders().get(Constants.BUNDLE_VERSION)
207 );
208 }
209
210
211
212
213
214
215
216
217 public static String getPluginKey(Manifest mf)
218 {
219 return getPluginKey(
220 mf.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME),
221 mf.getMainAttributes().getValue(OsgiPlugin.ATLASSIAN_PLUGIN_KEY),
222 mf.getMainAttributes().getValue(Constants.BUNDLE_VERSION)
223 );
224 }
225
226 private static String getPluginKey(Object bundleName, Object atlKey, Object version)
227 {
228 Object key = atlKey;
229 if (key == null)
230 {
231 key = bundleName + "-" + version;
232 }
233 return key.toString();
234
235 }
236 }