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