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