Invoke bundle hooks in privileged block. (FELIX-3032)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1153143 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 1e6f6c3..0d6e7fa 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -2832,10 +2832,10 @@
                     org.osgi.framework.hooks.bundle.FindHook fh = getService(this, hook);
                     if (fh != null)
                     {
-// TODO: OSGi R4.3 - Call all hooks in privileged block.
                         try
                         {
-                            fh.find(origin.getBundleContext(), bundles);
+                            m_secureAction.invokeBundleFindHook(
+                                fh, origin.getBundleContext(), bundles);
                         }
                         catch (Throwable th)
                         {
@@ -2918,10 +2918,9 @@
                 org.osgi.framework.hooks.bundle.FindHook fh = getService(this, hook);
                 if (fh != null)
                 {
-// TODO: OSGi R4.3 - Call all hooks in privileged block.
                     try
                     {
-                        fh.find(bc, bundles);
+                        m_secureAction.invokeBundleFindHook(fh, bc, bundles);
                     }
                     catch (Throwable th)
                     {
@@ -2987,10 +2986,9 @@
                 org.osgi.framework.hooks.bundle.FindHook fh = getService(this, hook);
                 if (fh != null)
                 {
-// TODO: OSGi R4.3 - Call all hooks in privileged block.
                     try
                     {
-                        fh.find(bc, bundles);
+                        m_secureAction.invokeBundleFindHook(fh, bc, bundles);
                     }
                     catch (Throwable th)
                     {
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
index b806210..4ed8ccc 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
@@ -22,11 +22,14 @@
 import java.lang.reflect.*;
 import java.net.*;
 import java.security.*;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Hashtable;
+import org.osgi.framework.Bundle;
 
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
 
 /**
  * <p>
@@ -137,7 +140,7 @@
             return ClassLoader.getSystemClassLoader();
         }
     }
-    
+
     public ClassLoader getClassLoader(Class clazz)
     {
         if (System.getSecurityManager() != null)
@@ -1009,7 +1012,7 @@
 
     private static void _flush(Class targetClazz, Object lock) throws Exception
     {
-        synchronized (lock) 
+        synchronized (lock)
         {
             Field[] fields = targetClazz.getDeclaredFields();
             // reset cache
@@ -1040,6 +1043,54 @@
         }
     }
 
+    public void invokeBundleFindHook(
+        org.osgi.framework.hooks.bundle.FindHook fh,
+        BundleContext bc, Collection<Bundle> bundles)
+        throws Exception
+    {
+        if (System.getSecurityManager() != null)
+        {
+            Actions actions = (Actions) m_actions.get();
+            actions.set(Actions.INVOKE_BUNDLE_FIND_HOOK, fh, bc, bundles);
+            try
+            {
+                AccessController.doPrivileged(actions, m_acc);
+            }
+            catch (PrivilegedActionException e)
+            {
+                throw e.getException();
+            }
+        }
+        else
+        {
+            fh.find(bc, bundles);
+        }
+    }
+
+    public void invokeBundleEventHook(
+        org.osgi.framework.hooks.bundle.EventHook eh,
+        BundleEvent event, Collection<BundleContext> contexts)
+        throws Exception
+    {
+        if (System.getSecurityManager() != null)
+        {
+            Actions actions = (Actions) m_actions.get();
+            actions.set(Actions.INVOKE_BUNDLE_EVENT_HOOK, eh, contexts);
+            try
+            {
+                AccessController.doPrivileged(actions, m_acc);
+            }
+            catch (PrivilegedActionException e)
+            {
+                throw e.getException();
+            }
+        }
+        else
+        {
+            eh.event(event, contexts);
+        }
+    }
+
     private static class Actions implements PrivilegedExceptionAction
     {
         public static final int INITIALIZE_CONTEXT_ACTION = 0;
@@ -1082,6 +1133,8 @@
         public static final int SYSTEM_EXIT_ACTION = 37;
         public static final int FLUSH_FIELD_ACTION = 38;
         public static final int GET_CLASS_LOADER_ACTION = 39;
+        public static final int INVOKE_BUNDLE_FIND_HOOK = 40;
+        public static final int INVOKE_BUNDLE_EVENT_HOOK = 41;
 
         private int m_action = -1;
         private Object m_arg1 = null;
@@ -1255,6 +1308,14 @@
                     return null;
                 case GET_CLASS_LOADER_ACTION:
                     return ((Class) arg1).getClassLoader();
+                case INVOKE_BUNDLE_FIND_HOOK:
+                    ((org.osgi.framework.hooks.bundle.FindHook) arg1).find(
+                        (BundleContext) arg2, (Collection<Bundle>) arg3);
+                    return null;
+                case INVOKE_BUNDLE_EVENT_HOOK:
+                    ((org.osgi.framework.hooks.bundle.EventHook) arg1).event(
+                        (BundleEvent) arg2, (Collection<BundleContext>) arg3);
+                    return null;
             }
 
             return null;