1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jetty.osgi.boot.utils.internal;
14
15 import java.util.ArrayList;
16 import java.util.LinkedHashMap;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.StringTokenizer;
20
21 import org.osgi.framework.Bundle;
22 import org.osgi.framework.BundleActivator;
23 import org.osgi.framework.BundleContext;
24 import org.osgi.framework.InvalidSyntaxException;
25 import org.osgi.framework.ServiceEvent;
26 import org.osgi.framework.ServiceListener;
27 import org.osgi.framework.ServiceReference;
28 import org.osgi.service.packageadmin.PackageAdmin;
29 import org.osgi.service.startlevel.StartLevel;
30
31
32
33
34
35 public class PackageAdminServiceTracker implements ServiceListener
36 {
37 private BundleContext _context;
38
39 private List<BundleActivator> _activatedFragments = new ArrayList<BundleActivator>();
40 private boolean _fragmentsWereActivated = false;
41
42 private StartLevel _startLevel;
43 private int _maxStartLevel = 6;
44 public static PackageAdminServiceTracker INSTANCE = null;
45
46 public PackageAdminServiceTracker(BundleContext context)
47 {
48 INSTANCE = this;
49 _context = context;
50 if (!setup())
51 {
52 try
53 {
54 _context.addServiceListener(this,"(objectclass=" + PackageAdmin.class.getName() + ")");
55 }
56 catch (InvalidSyntaxException e)
57 {
58 e.printStackTrace();
59 }
60 }
61 }
62
63
64
65
66 private boolean setup()
67 {
68 ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
69 _fragmentsWereActivated = sr != null;
70 if (sr != null)
71 invokeFragmentActivators(sr);
72
73 sr = _context.getServiceReference(StartLevel.class.getName());
74 if (sr != null)
75 {
76 _startLevel = (StartLevel)_context.getService(sr);
77 try
78 {
79 _maxStartLevel = Integer.parseInt(System.getProperty("osgi.startLevel","6"));
80 }
81 catch (Exception e)
82 {
83
84 _maxStartLevel = 6;
85 }
86 }
87 return _fragmentsWereActivated;
88 }
89
90
91
92
93
94
95
96
97
98
99 public void serviceChanged(ServiceEvent event)
100 {
101 if (event.getType() == ServiceEvent.REGISTERED)
102 {
103 invokeFragmentActivators(event.getServiceReference());
104 }
105 }
106
107
108
109
110
111
112
113
114 public Bundle[] getFragments(Bundle bundle)
115 {
116 ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
117 if (sr == null)
118 {
119 return null;
120 }
121 PackageAdmin admin = (PackageAdmin)_context.getService(sr);
122 return admin.getFragments(bundle);
123 }
124
125
126
127
128
129
130
131
132
133 public Bundle[] getFragmentsAndRequiredBundles(Bundle bundle)
134 {
135 ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
136 if (sr == null)
137 {
138 return null;
139 }
140 PackageAdmin admin = (PackageAdmin)_context.getService(sr);
141 LinkedHashMap<String,Bundle> deps = new LinkedHashMap<String,Bundle>();
142 collectFragmentsAndRequiredBundles(bundle, admin, deps, false);
143 return deps.values().toArray(new Bundle[deps.size()]);
144 }
145
146
147
148
149
150
151
152 protected void collectFragmentsAndRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
153 {
154 Bundle[] fragments = admin.getFragments(bundle);
155 if (fragments != null)
156 {
157
158
159 for (Bundle f : fragments)
160 {
161 if (!deps.keySet().contains(f.getSymbolicName()))
162 {
163 deps.put(f.getSymbolicName(), f);
164 collectRequiredBundles(f, admin, deps, onlyReexport);
165 }
166 }
167 }
168 collectRequiredBundles(bundle, admin, deps, onlyReexport);
169 }
170
171
172
173
174
175
176
177
178
179 protected void collectRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
180 {
181 String requiredBundleHeader = (String)bundle.getHeaders().get("Require-Bundle");
182 if (requiredBundleHeader == null)
183 {
184 return;
185 }
186 StringTokenizer tokenizer = new StringTokenizer(requiredBundleHeader, ",");
187 while (tokenizer.hasMoreTokens())
188 {
189 String tok = tokenizer.nextToken().trim();
190 StringTokenizer tokenizer2 = new StringTokenizer(tok, ";");
191 String symbolicName = tokenizer2.nextToken().trim();
192 if (deps.keySet().contains(symbolicName))
193 {
194
195 continue;
196 }
197 String versionRange = null;
198 boolean reexport = false;
199 while (tokenizer2.hasMoreTokens())
200 {
201 String next = tokenizer2.nextToken().trim();
202 if (next.startsWith("bundle-version="))
203 {
204 if (next.startsWith("bundle-version=\"") || next.startsWith("bundle-version='"))
205 {
206 versionRange = next.substring("bundle-version=\"".length(), next.length()-1);
207 }
208 else
209 {
210 versionRange = next.substring("bundle-version=".length());
211 }
212 }
213 else if (next.equals("visibility:=reexport"))
214 {
215 reexport = true;
216 }
217 }
218 if (!reexport && onlyReexport)
219 {
220 return;
221 }
222 Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange);
223 if (reqBundles != null && reqBundles.length != 0)
224 {
225 Bundle reqBundle = null;
226 for (Bundle b : reqBundles)
227 {
228 if (b.getState() == Bundle.ACTIVE || b.getState() == Bundle.STARTING)
229 {
230 reqBundle = b;
231 break;
232 }
233 }
234 if (reqBundle == null)
235 {
236
237
238 reqBundle = reqBundles[0];
239 }
240 deps.put(reqBundle.getSymbolicName(),reqBundle);
241 collectFragmentsAndRequiredBundles(reqBundle, admin, deps, true);
242 }
243 }
244 }
245
246
247 private void invokeFragmentActivators(ServiceReference sr)
248 {
249 PackageAdmin admin = (PackageAdmin)_context.getService(sr);
250 Bundle[] fragments = admin.getFragments(_context.getBundle());
251 if (fragments == null)
252 {
253 return;
254 }
255 for (Bundle frag : fragments)
256 {
257
258 try
259 {
260 String fragmentActivator = frag.getSymbolicName() + ".FragmentActivator";
261 Class<?> c = Class.forName(fragmentActivator);
262 if (c != null)
263 {
264 BundleActivator bActivator = (BundleActivator)c.newInstance();
265 bActivator.start(_context);
266 _activatedFragments.add(bActivator);
267 }
268 }
269 catch (NullPointerException e)
270 {
271
272 }
273 catch (InstantiationException e)
274 {
275
276 }
277 catch (IllegalAccessException e)
278 {
279
280 }
281 catch (ClassNotFoundException e)
282 {
283
284 }
285 catch (Exception e)
286 {
287 e.printStackTrace();
288 }
289 }
290 }
291
292 public void stop()
293 {
294 INSTANCE = null;
295 for (BundleActivator fragAct : _activatedFragments)
296 {
297 try
298 {
299 fragAct.stop(_context);
300 }
301 catch (Exception e)
302 {
303 e.printStackTrace();
304 }
305 }
306 }
307
308
309
310
311 public boolean frameworkHasCompletedAutostarts()
312 {
313 return _startLevel == null ? true : _startLevel.getStartLevel() >= _maxStartLevel;
314 }
315
316 }
317