/*
 * Copyright (c) 2006, KNOPFLERFISH project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials
 *   provided with the distribution.
 *
 * - Neither the name of the KNOPFLERFISH project nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.knopflerfish.bundle.component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;



public class Backdoor {
  
  public static BundleContext getBundleContext(Bundle bundle) {
    try {
      Class klass = bundle.getClass();
      Field field = klass.getDeclaredField("bundleContext");
      field.setAccessible(true);
      return (BundleContext) field.get(bundle);
    } catch (Exception e) {
      Activator.log.error("getBundleContext failed", e);
      return null;
    }
  }

  public static ClassLoader getClassLoader(Bundle bundle) {
    try {
      Class klass = bundle.getClass();
      Method method = klass.getDeclaredMethod("getClassLoader", new Class[]{});
      method.setAccessible(true);
      return (ClassLoader)method.invoke(bundle, new Object[]{});
      
    } catch (Exception e) {
      Activator.log.error("getClassLoader failed", e);
      return null;
    }
  }
  
  
}

@@ -1810,121 +1810,1078 @@
 %0A  %0A
-  public static BundleContext getBundleContext(Bundle bundle) %7B%0A    try %7B%0A      Class klass = bundle.getClass();%0A
+%0A  /**%0A   * Try to get the BundleContext from a Bundle instance using%0A   * various known backdoors (we don't really rely on R4.1 yet)%0A   */%0A  public static BundleContext getBundleContext(Bundle b) %7B%0A    Class clazz = b.getClass();%0A    try %7B      %0A      // getBundleContext() is an R4.1 method, but try to grab it %0A      // using reflection and punch a hole in the method modifiers. %0A      // Should work on recent KF and recent Felix.%0A      Method m =  clazz.getMethod(%22getBundleContext%22, new Class%5B%5D %7B %7D);%0A      %0A      m.setAccessible(true);%0A      return (BundleContext)m.invoke(b, new Object%5B%5D %7B %7D);%0A    %7D catch (Exception e) %7B%0A      Activator.log.debug(%22Failed to call Bundle.getBundleContext()%22, e);%0A%0A      // Try some known private fields. %0A      String%5B%5D fieldNames = new String%5B%5D %7B%0A        %22bundleContext%22, // available in KF%0A        %22context%22,       // available in Equinox and Concierge%0A      %7D;%0A      for(int i = 0; i %3C fieldNames.length; i++) %7B%0A        try %7B%0A          Activator.log.debug(%22Try field %22 + clazz.getName() + %22.%22 + fieldNames%5Bi%5D);%0A          %0A    
     
@@ -2892,29 +2892,29 @@
 eld field = 
-klass
+clazz
 .getDeclared
@@ -2923,32 +2923,34 @@
 eld(
-%22bundleContext%22);%0A
+fieldNames%5Bi%5D);%0A   
       
+ 
 fiel
@@ -2964,32 +2964,36 @@
 cessible(true);%0A
+    
       return (Bu
@@ -3004,17 +3004,16 @@
 Context)
- 
 field.ge
@@ -3019,16 +3019,15 @@
 et(b
-undle);%0A
+);%0A    
     
@@ -3038,32 +3038,33 @@
 tch (Exception e
+2
 ) %7B%0A      Activa
@@ -3049,32 +3049,36 @@
 ion e2) %7B%0A      
+    
 Activator.log.er
@@ -3075,26 +3075,146 @@
 tor.log.
-error(%22
+info(%22Failed: field %22 + clazz.getName() + %22.%22 + fieldNames%5Bi%5D, e2);%0A        %7D%0A      %7D%0A    %7D%0A    Activator.log.warn(%22Failed to 
 get
+ 
 BundleCo
@@ -3220,30 +3220,81 @@
 ontext f
-ailed%22, e
+rom bundle #%22 + b.getBundleId() + %22, class=%22 + clazz.getName()
 );%0A
-  
     retu
@@ -3298,30 +3298,24 @@
 eturn null;%0A
-    %7D%0A
   %7D%0A%0A  publi

use better getBundleContext backdoor