Author: davidb
Date: Tue Nov 18 16:27:47 2014
New Revision: 1640381

URL: http://svn.apache.org/r1640381
Log:
FELIX-4579 Support Framework Extension Bundle Activators

Unit test included.

Modified:
    
felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
    
felix/trunk/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java

Modified: 
felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java?rev=1640381&r1=1640380&r2=1640381&view=diff
==============================================================================
--- 
felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
 (original)
+++ 
felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
 Tue Nov 18 16:27:47 2014
@@ -19,14 +19,15 @@
 package org.apache.felix.framework;
 
 import java.io.IOException;
-import java.net.InetAddress;
 import java.io.InputStream;
+import java.net.InetAddress;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLStreamHandler;
 import java.security.AllPermission;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -36,12 +37,13 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.NoSuchElementException;
 import java.util.Set;
+
+import org.apache.felix.framework.cache.Content;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.ImmutableList;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
-import org.apache.felix.framework.cache.Content;
 import org.apache.felix.framework.util.manifestparser.R4Library;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleWireImpl;
@@ -249,30 +251,30 @@ class ExtensionManager extends URLStream
                String osVersion = 
(String)m_configMap.get(FelixConstants.FRAMEWORK_OS_VERSION);
                String userLang = 
(String)m_configMap.get(FelixConstants.FRAMEWORK_LANGUAGE);
                Map<String, Object> attributes = new HashMap<String, Object>();
-               
-               if( osArchitecture != null ) 
+
+               if( osArchitecture != null )
                {
                        
attributes.put(NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE, osArchitecture);
                }
-               
+
                if( osName != null)
                {
                        
attributes.put(NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE, osName);
                }
-               
+
                if( osVersion != null)
                {
                        
attributes.put(NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE, new 
Version(osVersion));
                }
-               
-               if( userLang != null) 
+
+               if( userLang != null)
                {
                        
attributes.put(NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE, userLang);
                }
-               
+
                return new BundleCapabilityImpl(getRevision(), 
NativeNamespace.NATIVE_NAMESPACE, Collections.<String, String> emptyMap(), 
attributes);
        }
-       
+
     private static List<BundleCapability> 
aliasSymbolicName(List<BundleCapability> caps)
     {
         if (caps == null)
@@ -463,9 +465,10 @@ class ExtensionManager extends URLStream
      */
     void startExtensionBundle(Felix felix, BundleImpl bundle)
     {
-        String activatorClass = (String)
-            ((BundleRevisionImpl) bundle.adapt(BundleRevision.class))
-                .getHeaders().get(FelixConstants.FELIX_EXTENSION_ACTIVATOR);
+        Dictionary<?,?> headers = bundle.getHeaders();
+        String activatorClass = (String) 
headers.get(Constants.EXTENSION_BUNDLE_ACTIVATOR);
+        if (activatorClass == null)
+            activatorClass = (String) 
headers.get(FelixConstants.FELIX_EXTENSION_ACTIVATOR);
 
         if (activatorClass != null)
         {
@@ -491,7 +494,7 @@ class ExtensionManager extends URLStream
             catch (Throwable ex)
             {
                 m_logger.log(bundle, Logger.LOG_WARNING,
-                    "Unable to start Felix Extension Activator", ex);
+                    "Unable to start Extension Activator", ex);
             }
         }
     }

Modified: 
felix/trunk/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java?rev=1640381&r1=1640380&r2=1640381&view=diff
==============================================================================
--- 
felix/trunk/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
 (original)
+++ 
felix/trunk/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
 Tue Nov 18 16:27:47 2014
@@ -1,81 +1,189 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework;
-
-import static org.junit.Assert.*;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.felix.framework.util.FelixConstants;
-import org.junit.Test;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.NativeNamespace;
-import org.osgi.framework.wiring.BundleCapability;
-
-/**
- * 
- * Test Classes for the ExtentionManager
- *
- */
-public class ExtensionManagerTest {
-
-       /**
-        * 
-        * 
-        * Ensure Native Bundle Capabilities are properly formed based on
-        * Framework properties.
-        * 
-        */
-       @Test
-       public void testBuildNativeCapabilities() {
-               Logger logger = new Logger();
-               Map<String, String> configMap = new HashMap<String, String>();
-               configMap.put(FelixConstants.FELIX_VERSION_PROPERTY, "1.0");
-               configMap.put(FelixConstants.FRAMEWORK_LANGUAGE, "en");
-               configMap.put(FelixConstants.FRAMEWORK_PROCESSOR, "x86_64");
-               configMap.put(FelixConstants.FRAMEWORK_OS_NAME, "windows8");
-               configMap.put(FelixConstants.FRAMEWORK_OS_VERSION, "6.3");
-               ExtensionManager extensionManager = new ExtensionManager(logger,
-                               configMap, null);
-               BundleCapability nativeBundleCapability = extensionManager
-                               .buildNativeCapabilites();
-               assertEquals(
-                               "Native Language should be same as framework 
Language",
-                               "en",
-                               nativeBundleCapability.getAttributes().get(
-                                               
NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE));
-               assertEquals(
-                               "Native Processor should be same as framework 
Processor",
-                               "x86_64",
-                               nativeBundleCapability.getAttributes().get(
-                                               
NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE));
-               assertEquals(
-                               "Native OS Name should be the same as the 
framework os name",
-                               "windows8",
-                               nativeBundleCapability.getAttributes().get(
-                                               
NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE));
-               assertEquals(
-                               "Native OS Version should be the same as the 
framework OS Version",
-                               new Version("6.3"),
-                               nativeBundleCapability.getAttributes().get(
-                                               
NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE));
-       }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import org.apache.felix.framework.util.FelixConstants;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.namespace.NativeNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+
+/**
+ *
+ * Test Classes for the ExtentionManager
+ *
+ */
+public class ExtensionManagerTest {
+    private int counter;
+    private File testDir;
+
+    @Before
+    public void setUp() throws Exception {
+        String path = "/" + getClass().getName().replace('.', '/') + ".class";
+        String url = getClass().getResource(path).getFile();
+        String baseDir = url.substring(0, url.length() - path.length());
+        String rndStr = Long.toString(System.nanoTime(), Character.MAX_RADIX);
+        rndStr = rndStr.substring(rndStr.length() - 6, rndStr.length() - 1);
+        testDir = new File(baseDir, getClass().getSimpleName() + "_" + rndStr);
+    }
+
+    /**
+     *
+     *
+     * Ensure Native Bundle Capabilities are properly formed based on
+     * Framework properties.
+     *
+     */
+    @Test
+    public void testBuildNativeCapabilities() {
+        Logger logger = new Logger();
+        Map<String, String> configMap = new HashMap<String, String>();
+        configMap.put(FelixConstants.FELIX_VERSION_PROPERTY, "1.0");
+        configMap.put(FelixConstants.FRAMEWORK_LANGUAGE, "en");
+        configMap.put(FelixConstants.FRAMEWORK_PROCESSOR, "x86_64");
+        configMap.put(FelixConstants.FRAMEWORK_OS_NAME, "windows8");
+        configMap.put(FelixConstants.FRAMEWORK_OS_VERSION, "6.3");
+        ExtensionManager extensionManager = new ExtensionManager(logger,
+                configMap, null);
+        BundleCapability nativeBundleCapability = extensionManager
+                .buildNativeCapabilites();
+        assertEquals(
+                "Native Language should be same as framework Language",
+                "en",
+                nativeBundleCapability.getAttributes().get(
+                        NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE));
+        assertEquals(
+                "Native Processor should be same as framework Processor",
+                "x86_64",
+                nativeBundleCapability.getAttributes().get(
+                        NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE));
+        assertEquals(
+                "Native OS Name should be the same as the framework os name",
+                "windows8",
+                nativeBundleCapability.getAttributes().get(
+                        NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE));
+        assertEquals(
+                "Native OS Version should be the same as the framework OS 
Version",
+                new Version("6.3"),
+                nativeBundleCapability.getAttributes().get(
+                        NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE));
+    }
+
+    @Test
+    public void testExtensionBundleActivator() throws Exception {
+        File cacheDir = new File(testDir, "cache");
+        cacheDir.mkdirs();
+        String cache = cacheDir.getAbsolutePath();
+
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("felix.cache.profiledir", cache);
+        params.put("felix.cache.dir", cache);
+        params.put(Constants.FRAMEWORK_STORAGE, cache);
+
+        Framework framework = new Felix(params);
+        framework.init();
+        framework.start();
+
+        try {
+            File ebf = createExtensionBundle();
+
+            assertEquals("Precondition", 0, activatorCalls.length());
+            framework.getBundleContext().installBundle(
+                    ebf.toURI().toURL().toExternalForm());
+
+            assertEquals("start", activatorCalls.toString());
+        } finally {
+            framework.stop();
+        }
+
+        framework.waitForStop(10000);
+        assertEquals("startstop", activatorCalls.toString());
+    }
+
+    private File createExtensionBundle() throws IOException {
+        File f = File.createTempFile("felix-bundle" + counter++, ".jar", 
testDir);
+
+        Manifest mf = new Manifest();
+        mf.getMainAttributes().putValue("Manifest-Version", "1.0");
+        mf.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME, 
"extension-bundle");
+        mf.getMainAttributes().putValue(Constants.BUNDLE_VERSION, "3.2.1");
+        mf.getMainAttributes().putValue(Constants.FRAGMENT_HOST, 
"system.bundle;extension:=framework");
+        mf.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
+        mf.getMainAttributes().putValue(Constants.EXTENSION_BUNDLE_ACTIVATOR, 
TestActivator.class.getName());
+        JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+
+        String path = TestActivator.class.getName().replace('.', '/') + 
".class";
+        os.putNextEntry(new ZipEntry(path));
+
+        InputStream is = 
TestActivator.class.getClassLoader().getResourceAsStream(path);
+        pumpStreams(is, os);
+
+        is.close();
+        os.close();
+        return f;
+    }
+
+    static void pumpStreams(InputStream is, OutputStream os) throws 
IOException {
+        byte[] bytes = new byte[16384];
+
+        int length = 0;
+        int offset = 0;
+
+        while ((length = is.read(bytes, offset, bytes.length - offset)) != -1) 
{
+            offset += length;
+
+            if (offset == bytes.length) {
+                os.write(bytes, 0, bytes.length);
+                offset = 0;
+            }
+        }
+        if (offset != 0) {
+            os.write(bytes, 0, offset);
+        }
+    }
+
+    private static StringBuilder activatorCalls = new StringBuilder();
+    public static class TestActivator implements BundleActivator {
+        public void start(BundleContext context) throws Exception {
+            activatorCalls.append("start");
+        }
+
+        public void stop(BundleContext context) throws Exception {
+            activatorCalls.append("stop");
+        }
+    }
+}


Reply via email to