Fix activation spec in osgi, it now auto-discover META-INF/mailcap files in bundles and populate the MailcapCommandMap accordingly

git-svn-id: https://svn.apache.org/repos/asf/servicemix/smx4/specs/trunk@752899 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/activation-api-1.1/pom.xml b/activation-api-1.1/pom.xml
index d2c5c77..fd0f67a 100644
--- a/activation-api-1.1/pom.xml
+++ b/activation-api-1.1/pom.xml
@@ -37,13 +37,19 @@
         <dependency>
             <groupId>org.apache.servicemix.specs</groupId>
             <artifactId>org.apache.servicemix.specs.locator</artifactId>
-            <version>1.1.1</version>
+            <version>${pom.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-activation_1.1_spec</artifactId>
             <version>1.0.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>1.2.0</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -63,9 +69,15 @@
                     <instructions>
                         <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
                         <Export-Package>javax.activation*;version=1.1;-split-package:=merge-first</Export-Package>
-                        <Import-Package>*</Import-Package>
-                        <Private-Package>org.apache.servicemix.specs.locator;-split-package:=merge-first</Private-Package>
-                        <Bundle-Activator>org.apache.servicemix.specs.locator.Activator</Bundle-Activator>
+                        <Import-Package>
+                            *,
+                            !org.apache.servicemix.specs.activation
+                        </Import-Package>
+                        <Private-Package>
+                            org.apache.servicemix.specs.locator;-split-package:=merge-first,
+                            org.apache.servicemix.specs.activation;-split-package:=merge-first
+                        </Private-Package>
+                        <Bundle-Activator>org.apache.servicemix.specs.activation.Activator</Bundle-Activator>
                         <Implementation-Title>Apache ServiceMix</Implementation-Title>
                         <Implementation-Version>${project.version}</Implementation-Version>
                     </instructions>
diff --git a/activation-api-1.1/src/main/java/javax/activation/MailcapCommandMap.java b/activation-api-1.1/src/main/java/javax/activation/MailcapCommandMap.java
index 5eb5dab..ef6fd50 100644
--- a/activation-api-1.1/src/main/java/javax/activation/MailcapCommandMap.java
+++ b/activation-api-1.1/src/main/java/javax/activation/MailcapCommandMap.java
@@ -260,7 +260,7 @@
      * @param commands A List containing the command information.
      * @param fallback The target list identifier.
      */
-    private void addCommands(String mimeType, List commands, boolean fallback) {
+    protected void addCommands(String mimeType, List commands, boolean fallback) {
         // add this to the mimeType set
         mimeTypes.put(mimeType, mimeType);
         // the target list changes based on the type of entry.
@@ -291,7 +291,7 @@
      * @param mimeType The MIME type the command is associated with.
      * @param command  The command information.
      */
-    private void addCommand(Map commandList, String mimeType, CommandInfo command) {
+    protected void addCommand(Map commandList, String mimeType, CommandInfo command) {
 
         Map commands = (Map) commandList.get(mimeType);
         if (commands == null) {
@@ -456,22 +456,6 @@
     }
 
     public synchronized DataContentHandler createDataContentHandler(String mimeType) {
-    	
-    	//If we are deployed into an OSGi environment, leverage it
-    	String osgiMimeType = mimeType;
-    	if (mimeType.indexOf("/") >= 0) {
-    		osgiMimeType = mimeType.replace('/', '_');
-    	}
-        Class dchClass = org.apache.servicemix.specs.locator.OsgiLocator.locate(osgiMimeType);
-        if (dchClass != null) {
-			try {
-				return (DataContentHandler) dchClass.newInstance();
-			} catch (InstantiationException e) {
-				
-			} catch (IllegalAccessException e) {
-				
-			}
-		}
 
         CommandInfo info = getCommand(mimeType, "content-handler");
         if (info == null) {
diff --git a/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/Activator.java b/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/Activator.java
new file mode 100644
index 0000000..008b67b
--- /dev/null
+++ b/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/Activator.java
@@ -0,0 +1,102 @@
+/*
+ * 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.servicemix.specs.activation;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.activation.CommandMap;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * A bundle activator for activation framework
+ */
+public class Activator extends org.apache.servicemix.specs.locator.Activator {
+
+    private Map<Long, MailCap> mailcaps = new ConcurrentHashMap<Long, MailCap>();
+
+    @Override
+    public void start(BundleContext bundleContext) throws Exception {
+        super.start(bundleContext);
+    }
+
+    @Override
+    public void stop(BundleContext bundleContext) throws Exception {
+        super.stop(bundleContext);
+        CommandMap.setDefaultCommandMap(null);
+    }
+
+    @Override
+    protected void register(Bundle bundle) {
+        debugPrintln("checking bundle " + bundle.getBundleId());
+        URL url = bundle.getResource("/META-INF/mailcap");
+        if (url != null) {
+            debugPrintln("found mailcap at " + url);
+            mailcaps.put(bundle.getBundleId(), new MailCap(bundle, url));
+            rebuildCommandMap();
+        }
+    }
+
+    @Override
+    protected void unregister(long bundleId) {
+        MailCap mailcap = mailcaps.remove(bundleId);
+        if (mailcap != null ){
+            debugPrintln("removing mailcap at " + mailcap.url);
+            rebuildCommandMap();
+        }
+    }
+
+    private void rebuildCommandMap() {
+        OsgiMailcapCommandMap commandMap = new OsgiMailcapCommandMap();
+        for (MailCap mailcap : mailcaps.values()) {
+            try {
+                InputStream is = mailcap.url.openStream();
+                try {
+                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
+                    String line;
+                    while ((line = br.readLine()) != null) {
+                        commandMap.addMailcap(line, mailcap.bundle);
+                    }
+                } finally {
+                    is.close();
+                }
+            } catch (Exception e) {
+                // Ignore
+            }
+        }
+        CommandMap.setDefaultCommandMap(commandMap);
+    }
+
+    private static class MailCap {
+        Bundle bundle;
+        URL url;
+
+        private MailCap(Bundle bundle, URL url) {
+            this.bundle = bundle;
+            this.url = url;
+        }
+    }
+
+}
diff --git a/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/OsgiMailcapCommandMap.java b/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/OsgiMailcapCommandMap.java
new file mode 100644
index 0000000..a914247
--- /dev/null
+++ b/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/OsgiMailcapCommandMap.java
@@ -0,0 +1,84 @@
+/*
+ * 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.servicemix.specs.activation;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.activation.MailcapCommandMap;
+import javax.activation.CommandInfo;
+import javax.activation.DataContentHandler;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * An OSGi enabled MailcapCommandMap
+ */
+public class OsgiMailcapCommandMap extends MailcapCommandMap {
+
+    private Bundle currentBundle;
+    private Map<CommandInfo, Bundle> bundles = new HashMap<CommandInfo, Bundle>();
+
+    public void addMailcap(String line, Bundle bundle) {
+        currentBundle = bundle;
+        addMailcap(line);
+    }
+
+    protected void addCommand(Map commandList, String mimeType, CommandInfo command) {
+        super.addCommand(commandList, mimeType, command);
+        if (currentBundle != null) {
+            bundles.put(command, currentBundle);
+        }
+    }
+
+    @Override
+    public DataContentHandler createDataContentHandler(String mimeType) {
+        CommandInfo info = getCommand(mimeType, "content-handler");
+        if (info == null) {
+            return null;
+        }
+
+        Bundle bundle = bundles.get(info);
+        if (bundle != null) {
+            try {
+                return (DataContentHandler) bundle.loadClass(info.getCommandClass()).newInstance();
+            } catch (ClassNotFoundException e) {
+                return null;
+            } catch (IllegalAccessException e) {
+                return null;
+            } catch (InstantiationException e) {
+                return null;
+            }
+        }
+
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if (cl == null) {
+            cl = getClass().getClassLoader();
+        }
+        try {
+            return (DataContentHandler) cl.loadClass(info.getCommandClass()).newInstance();
+        } catch (ClassNotFoundException e) {
+            return null;
+        } catch (IllegalAccessException e) {
+            return null;
+        } catch (InstantiationException e) {
+            return null;
+        }
+    }
+}
diff --git a/javamail-api-1.4/pom.xml b/javamail-api-1.4/pom.xml
index 681913a..e6c19e6 100644
--- a/javamail-api-1.4/pom.xml
+++ b/javamail-api-1.4/pom.xml
@@ -37,12 +37,12 @@
         <dependency>
             <groupId>org.apache.servicemix.specs</groupId>
             <artifactId>org.apache.servicemix.specs.locator</artifactId>
-            <version>1.1.1</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-javamail_1.4_spec</artifactId>
-            <version>1.5</version>
+            <version>1.6</version>
         </dependency>
     </dependencies>
 
@@ -54,7 +54,7 @@
                 <configuration>
                     <instructions>
                         <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
-                        <Export-Package>javax.mail*;version=1.4;-split-package:=merge-first,org.apache.geronimo.mail.util</Export-Package>
+                        <Export-Package>javax.mail*;version=1.4;-split-package:=merge-first,org.apache.geronimo.mail*;version=1.6;-split-package:=merge-first</Export-Package>
                         <Import-Package>*</Import-Package>
                         <Private-Package>org.apache.servicemix.specs.locator;-split-package:=merge-first</Private-Package>
                         <Bundle-Activator>org.apache.servicemix.specs.locator.Activator</Bundle-Activator>
diff --git a/locator/src/main/java/org/apache/servicemix/specs/locator/Activator.java b/locator/src/main/java/org/apache/servicemix/specs/locator/Activator.java
index a774a14..3c4efa6 100644
--- a/locator/src/main/java/org/apache/servicemix/specs/locator/Activator.java
+++ b/locator/src/main/java/org/apache/servicemix/specs/locator/Activator.java
@@ -52,7 +52,7 @@
      *
      * @param msg <code>String</code> to print to <code>stderr</code>.
      */
-    private void debugPrintln(String msg) {
+    protected void debugPrintln(String msg) {
         if (debug) {
             System.err.println("Spec(" + bundleContext.getBundle().getBundleId() + "): " + msg);
         }