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} 512