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 28 import org.osgi.framework.Bundle; 29 import org.osgi.framework.BundleActivator; 30 import org.osgi.framework.BundleContext; 31 import org.osgi.framework.BundleException; 32 33 import java.lang.reflect.Method; 34 import java.lang.reflect.Modifier; 35 import 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 AA()60 public AA() {} 61 setA(Undefined undefined)62 @Inject public void setA(Undefined undefined) {} 63 setB(Undefined undefined)64 @Inject protected void setB(Undefined undefined) {} 65 setC(Undefined undefined)66 @Inject void setC(Undefined undefined) {} 67 setD(Undefined undefined)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 AB()82 public AB() {} 83 setA(Undefined undefined)84 @Inject public void setA(Undefined undefined) {} 85 setB(Undefined undefined)86 @Inject protected void setB(Undefined undefined) {} 87 setC(Undefined undefined)88 @Inject void setC(Undefined undefined) {} 89 setD(Undefined undefined)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 AC()104 public AC() {} 105 setA(Undefined undefined)106 @Inject public void setA(Undefined undefined) {} 107 setB(Undefined undefined)108 @Inject protected void setB(Undefined undefined) {} 109 setC(Undefined undefined)110 @Inject void setC(Undefined undefined) {} 111 setD(Undefined undefined)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 AD()126 public AD() {} 127 setA(Undefined undefined)128 @Inject public void setA(Undefined undefined) {} 129 setB(Undefined undefined)130 @Inject protected void setB(Undefined undefined) {} 131 setC(Undefined undefined)132 @Inject void setC(Undefined undefined) {} 133 setD(Undefined undefined)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 BA()148 protected BA() {} 149 setA(Undefined undefined)150 @Inject public void setA(Undefined undefined) {} 151 setB(Undefined undefined)152 @Inject protected void setB(Undefined undefined) {} 153 setC(Undefined undefined)154 @Inject void setC(Undefined undefined) {} 155 setD(Undefined undefined)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 BB()170 protected BB() {} 171 setA(Undefined undefined)172 @Inject public void setA(Undefined undefined) {} 173 setB(Undefined undefined)174 @Inject protected void setB(Undefined undefined) {} 175 setC(Undefined undefined)176 @Inject void setC(Undefined undefined) {} 177 setD(Undefined undefined)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 BC()192 protected BC() {} 193 setA(Undefined undefined)194 @Inject public void setA(Undefined undefined) {} 195 setB(Undefined undefined)196 @Inject protected void setB(Undefined undefined) {} 197 setC(Undefined undefined)198 @Inject void setC(Undefined undefined) {} 199 setD(Undefined undefined)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 BD()214 protected BD() {} 215 setA(Undefined undefined)216 @Inject public void setA(Undefined undefined) {} 217 setB(Undefined undefined)218 @Inject protected void setB(Undefined undefined) {} 219 setC(Undefined undefined)220 @Inject void setC(Undefined undefined) {} 221 setD(Undefined undefined)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 CA()236 CA() {} 237 setA(Undefined undefined)238 @Inject public void setA(Undefined undefined) {} 239 setB(Undefined undefined)240 @Inject protected void setB(Undefined undefined) {} 241 setC(Undefined undefined)242 @Inject void setC(Undefined undefined) {} 243 setD(Undefined undefined)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 CB()258 CB() {} 259 setA(Undefined undefined)260 @Inject public void setA(Undefined undefined) {} 261 setB(Undefined undefined)262 @Inject protected void setB(Undefined undefined) {} 263 setC(Undefined undefined)264 @Inject void setC(Undefined undefined) {} 265 setD(Undefined undefined)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 CC()280 CC() {} 281 setA(Undefined undefined)282 @Inject public void setA(Undefined undefined) {} 283 setB(Undefined undefined)284 @Inject protected void setB(Undefined undefined) {} 285 setC(Undefined undefined)286 @Inject void setC(Undefined undefined) {} 287 setD(Undefined undefined)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 CD()302 CD() {} 303 setA(Undefined undefined)304 @Inject public void setA(Undefined undefined) {} 305 setB(Undefined undefined)306 @Inject protected void setB(Undefined undefined) {} 307 setC(Undefined undefined)308 @Inject void setC(Undefined undefined) {} 309 setD(Undefined undefined)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 DA()324 @Inject private DA() {} 325 setA(Undefined undefined)326 @Inject public void setA(Undefined undefined) {} 327 setB(Undefined undefined)328 @Inject protected void setB(Undefined undefined) {} 329 setC(Undefined undefined)330 @Inject void setC(Undefined undefined) {} 331 setD(Undefined undefined)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 DB()346 @Inject private DB() {} 347 setA(Undefined undefined)348 @Inject public void setA(Undefined undefined) {} 349 setB(Undefined undefined)350 @Inject protected void setB(Undefined undefined) {} 351 setC(Undefined undefined)352 @Inject void setC(Undefined undefined) {} 353 setD(Undefined undefined)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 DC()368 @Inject private DC() {} 369 setA(Undefined undefined)370 @Inject public void setA(Undefined undefined) {} 371 setB(Undefined undefined)372 @Inject protected void setB(Undefined undefined) {} 373 setC(Undefined undefined)374 @Inject void setC(Undefined undefined) {} 375 setD(Undefined undefined)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 DD()390 private DD() {} 391 setA(Undefined undefined)392 @Inject public void setA(Undefined undefined) {} 393 setB(Undefined undefined)394 @Inject protected void setB(Undefined undefined) {} 395 setC(Undefined undefined)396 @Inject void setC(Undefined undefined) {} 397 setD(Undefined undefined)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 TestModule(Bundle bundle)421 TestModule(Bundle bundle) { 422 this.bundle = bundle; 423 } 424 configure()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 { configure()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 start(BundleContext context)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 stop(BundleContext context)510 public void stop(BundleContext context) {} 511 } 512