/core/test/com/googlecode/guice/bundle/OSGiTestActivator.java
Java | 511 lines | 281 code | 192 blank | 38 comment | 8 complexity | 34714b9af2d4079d03698575a54f8dd8 MD5 | raw file
1/**
2 * Copyright (C) 2009 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.googlecode.guice.bundle;
18
19import static com.google.inject.name.Names.named;
20
21import com.google.inject.AbstractModule;
22import com.google.inject.Guice;
23import com.google.inject.Inject;
24import com.google.inject.Injector;
25import com.google.inject.Key;
26import com.google.inject.matcher.AbstractMatcher;
27
28import org.osgi.framework.Bundle;
29import org.osgi.framework.BundleActivator;
30import org.osgi.framework.BundleContext;
31import org.osgi.framework.BundleException;
32
33import java.lang.reflect.Method;
34import java.lang.reflect.Modifier;
35import java.util.Random;
36
37/**
38 * Test Guice from inside an OSGi bundle activator.
39 *
40 * @author mcculls@gmail.com (Stuart McCulloch)
41 */
42@SuppressWarnings("unused") public class OSGiTestActivator
43 implements BundleActivator {
44
45 // varying visibilities to test our code-generation support
46
47 public static class Undefined {}
48
49 public interface A {}
50
51 protected interface B {}
52
53 interface C {}
54
55 private interface D {}
56
57 public static class AA
58 implements A {
59
60 public AA() {}
61
62 @Inject public void setA(Undefined undefined) {}
63
64 @Inject protected void setB(Undefined undefined) {}
65
66 @Inject void setC(Undefined undefined) {}
67
68 @Inject private void setD(Undefined undefined) {}
69
70 @Inject public Undefined a;
71
72 @Inject protected Undefined b;
73
74 @Inject Undefined c;
75
76 @Inject private Undefined d;
77 }
78
79 protected static class AB
80 implements A {
81
82 public AB() {}
83
84 @Inject public void setA(Undefined undefined) {}
85
86 @Inject protected void setB(Undefined undefined) {}
87
88 @Inject void setC(Undefined undefined) {}
89
90 @Inject private void setD(Undefined undefined) {}
91
92 @Inject public Undefined a;
93
94 @Inject protected Undefined b;
95
96 @Inject Undefined c;
97
98 @Inject private Undefined d;
99 }
100
101 static class AC
102 implements A {
103
104 public AC() {}
105
106 @Inject public void setA(Undefined undefined) {}
107
108 @Inject protected void setB(Undefined undefined) {}
109
110 @Inject void setC(Undefined undefined) {}
111
112 @Inject private void setD(Undefined undefined) {}
113
114 @Inject public Undefined a;
115
116 @Inject protected Undefined b;
117
118 @Inject Undefined c;
119
120 @Inject private Undefined d;
121 }
122
123 private static class AD
124 implements A {
125
126 public AD() {}
127
128 @Inject public void setA(Undefined undefined) {}
129
130 @Inject protected void setB(Undefined undefined) {}
131
132 @Inject void setC(Undefined undefined) {}
133
134 @Inject private void setD(Undefined undefined) {}
135
136 @Inject public Undefined a;
137
138 @Inject protected Undefined b;
139
140 @Inject Undefined c;
141
142 @Inject private Undefined d;
143 }
144
145 public static class BA
146 implements B {
147
148 protected BA() {}
149
150 @Inject public void setA(Undefined undefined) {}
151
152 @Inject protected void setB(Undefined undefined) {}
153
154 @Inject void setC(Undefined undefined) {}
155
156 @Inject private void setD(Undefined undefined) {}
157
158 @Inject public Undefined a;
159
160 @Inject protected Undefined b;
161
162 @Inject Undefined c;
163
164 @Inject private Undefined d;
165 }
166
167 protected static class BB
168 implements B {
169
170 protected BB() {}
171
172 @Inject public void setA(Undefined undefined) {}
173
174 @Inject protected void setB(Undefined undefined) {}
175
176 @Inject void setC(Undefined undefined) {}
177
178 @Inject private void setD(Undefined undefined) {}
179
180 @Inject public Undefined a;
181
182 @Inject protected Undefined b;
183
184 @Inject Undefined c;
185
186 @Inject private Undefined d;
187 }
188
189 static class BC
190 implements B {
191
192 protected BC() {}
193
194 @Inject public void setA(Undefined undefined) {}
195
196 @Inject protected void setB(Undefined undefined) {}
197
198 @Inject void setC(Undefined undefined) {}
199
200 @Inject private void setD(Undefined undefined) {}
201
202 @Inject public Undefined a;
203
204 @Inject protected Undefined b;
205
206 @Inject Undefined c;
207
208 @Inject private Undefined d;
209 }
210
211 private static class BD
212 implements B {
213
214 protected BD() {}
215
216 @Inject public void setA(Undefined undefined) {}
217
218 @Inject protected void setB(Undefined undefined) {}
219
220 @Inject void setC(Undefined undefined) {}
221
222 @Inject private void setD(Undefined undefined) {}
223
224 @Inject public Undefined a;
225
226 @Inject protected Undefined b;
227
228 @Inject Undefined c;
229
230 @Inject private Undefined d;
231 }
232
233 public static class CA
234 implements C {
235
236 CA() {}
237
238 @Inject public void setA(Undefined undefined) {}
239
240 @Inject protected void setB(Undefined undefined) {}
241
242 @Inject void setC(Undefined undefined) {}
243
244 @Inject private void setD(Undefined undefined) {}
245
246 @Inject public Undefined a;
247
248 @Inject protected Undefined b;
249
250 @Inject Undefined c;
251
252 @Inject private Undefined d;
253 }
254
255 protected static class CB
256 implements C {
257
258 CB() {}
259
260 @Inject public void setA(Undefined undefined) {}
261
262 @Inject protected void setB(Undefined undefined) {}
263
264 @Inject void setC(Undefined undefined) {}
265
266 @Inject private void setD(Undefined undefined) {}
267
268 @Inject public Undefined a;
269
270 @Inject protected Undefined b;
271
272 @Inject Undefined c;
273
274 @Inject private Undefined d;
275 }
276
277 static class CC
278 implements C {
279
280 CC() {}
281
282 @Inject public void setA(Undefined undefined) {}
283
284 @Inject protected void setB(Undefined undefined) {}
285
286 @Inject void setC(Undefined undefined) {}
287
288 @Inject private void setD(Undefined undefined) {}
289
290 @Inject public Undefined a;
291
292 @Inject protected Undefined b;
293
294 @Inject Undefined c;
295
296 @Inject private Undefined d;
297 }
298
299 private static class CD
300 implements C {
301
302 CD() {}
303
304 @Inject public void setA(Undefined undefined) {}
305
306 @Inject protected void setB(Undefined undefined) {}
307
308 @Inject void setC(Undefined undefined) {}
309
310 @Inject private void setD(Undefined undefined) {}
311
312 @Inject public Undefined a;
313
314 @Inject protected Undefined b;
315
316 @Inject Undefined c;
317
318 @Inject private Undefined d;
319 }
320
321 public static class DA
322 implements D {
323
324 @Inject private DA() {}
325
326 @Inject public void setA(Undefined undefined) {}
327
328 @Inject protected void setB(Undefined undefined) {}
329
330 @Inject void setC(Undefined undefined) {}
331
332 @Inject private void setD(Undefined undefined) {}
333
334 @Inject public Undefined a;
335
336 @Inject protected Undefined b;
337
338 @Inject Undefined c;
339
340 @Inject private Undefined d;
341 }
342
343 protected static class DB
344 implements D {
345
346 @Inject private DB() {}
347
348 @Inject public void setA(Undefined undefined) {}
349
350 @Inject protected void setB(Undefined undefined) {}
351
352 @Inject void setC(Undefined undefined) {}
353
354 @Inject private void setD(Undefined undefined) {}
355
356 @Inject public Undefined a;
357
358 @Inject protected Undefined b;
359
360 @Inject Undefined c;
361
362 @Inject private Undefined d;
363 }
364
365 static class DC
366 implements D {
367
368 @Inject private DC() {}
369
370 @Inject public void setA(Undefined undefined) {}
371
372 @Inject protected void setB(Undefined undefined) {}
373
374 @Inject void setC(Undefined undefined) {}
375
376 @Inject private void setD(Undefined undefined) {}
377
378 @Inject public Undefined a;
379
380 @Inject protected Undefined b;
381
382 @Inject Undefined c;
383
384 @Inject private Undefined d;
385 }
386
387 private static class DD
388 implements D {
389
390 private DD() {}
391
392 @Inject public void setA(Undefined undefined) {}
393
394 @Inject protected void setB(Undefined undefined) {}
395
396 @Inject void setC(Undefined undefined) {}
397
398 @Inject private void setD(Undefined undefined) {}
399
400 @Inject public Undefined a;
401
402 @Inject protected Undefined b;
403
404 @Inject Undefined c;
405
406 @Inject private Undefined d;
407 }
408
409 enum Visibility {
410 PUBLIC, PROTECTED, PACKAGE_PRIVATE, PRIVATE
411 }
412
413 static final Class<?>[] TEST_CLAZZES = {A.class, B.class, C.class, D.class};
414
415 // registers all the class combinations
416 static class TestModule
417 extends AbstractModule {
418
419 final Bundle bundle;
420
421 TestModule(Bundle bundle) {
422 this.bundle = bundle;
423 }
424
425 @Override @SuppressWarnings("unchecked") protected void configure() {
426 for (Class<?> api : TEST_CLAZZES) {
427 for (Visibility visibility : Visibility.values()) {
428 try {
429
430 // this registers: A + PUBLIC -> AA, A + PROTECTED -> AB, etc...
431 String suffix = TEST_CLAZZES[visibility.ordinal()].getSimpleName();
432 Class imp = bundle.loadClass(api.getName() + suffix);
433 bind(api).annotatedWith(named(visibility.name())).to(imp);
434
435 } catch (ClassNotFoundException e) {
436 throw new RuntimeException("Unable to load test class", e);
437 }
438 }
439 }
440 }
441 }
442
443/*if[AOP]*/
444 // applies method-interception to classes with enough visibility
445 static class InterceptorModule
446 extends AbstractModule {
447 @Override protected void configure() {
448 bindInterceptor(new AbstractMatcher<Class<?>>() {
449 public boolean matches(Class<?> clazz) {
450 try {
451
452 // the class and constructor must be visible
453 int clazzModifiers = clazz.getModifiers();
454 int ctorModifiers = clazz.getConstructor().getModifiers();
455 return (clazzModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0
456 && (ctorModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;
457
458 } catch (NoSuchMethodException e) {
459 return false;
460 }
461 }
462 }, new AbstractMatcher<Method>() {
463 public boolean matches(Method method) {
464
465 // the intercepted method must also be visible
466 int methodModifiers = method.getModifiers();
467 return (methodModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;
468
469 }
470 }, new org.aopalliance.intercept.MethodInterceptor() {
471 public Object invoke(org.aopalliance.intercept.MethodInvocation mi)
472 throws Throwable {
473
474 return mi.proceed();
475 }
476 });
477 }
478 }
479/*end[AOP]*/
480
481 // called from OSGi when bundle starts
482 public void start(BundleContext context)
483 throws BundleException {
484
485 final Bundle bundle = context.getBundle();
486
487 Injector injector = Guice.createInjector(new TestModule(bundle));
488/*if[AOP]*/
489 Injector aopInjector = Guice.createInjector(new TestModule(bundle), new InterceptorModule());
490/*end[AOP]*/
491
492 // test code-generation support
493 for (Class<?> api : TEST_CLAZZES) {
494 for (Visibility vis : Visibility.values()) {
495 injector.getInstance(Key.get(api, named(vis.name())));
496/*if[AOP]*/
497 aopInjector.getInstance(Key.get(api, named(vis.name())));
498/*end[AOP]*/
499 }
500 }
501
502 // test injection of system class (issue 343)
503 injector.getInstance(Random.class);
504/*if[AOP]*/
505 aopInjector.getInstance(Random.class);
506/*end[AOP]*/
507 }
508
509 // called from OSGi when bundle stops
510 public void stop(BundleContext context) {}
511}