[SMX4-1624] NPE in servicemix spec MailcapCommandMap

git-svn-id: https://svn.apache.org/repos/asf/servicemix/smx4/specs/trunk@1545615 13f79535-47bb-0310-9956-ffa450edef68
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
index ffde31a..fc2643f 100644
--- 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
@@ -19,9 +19,12 @@
 package org.apache.servicemix.specs.activation;
 
 import java.io.BufferedReader;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -68,7 +71,11 @@
                 // ignored
             }
 
-            mailcaps.put(bundle.getBundleId(), new MailCap(bundle, url));
+            try {
+                mailcaps.put(bundle.getBundleId(), new MailCap(bundle, url));
+            } catch (IOException ex) {
+                // ignored
+            }
             rebuildCommandMap();
         }
     }
@@ -77,39 +84,44 @@
     protected void unregister(long bundleId) {
         MailCap mailcap = mailcaps.remove(bundleId);
         if (mailcap != null ){
-            debugPrintln("removing mailcap at " + mailcap.url);
+            debugPrintln("removing mailcap for bundle " + mailcap.bundle.getBundleId());
             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();
+        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+            OsgiMailcapCommandMap commandMap = new OsgiMailcapCommandMap();
+            for (MailCap mailcap : mailcaps.values()) {
+                for (String line : mailcap.lines) {
+                    commandMap.addMailcap(line, mailcap.bundle);
                 }
-            } catch (Exception e) {
-                // Ignore
             }
+            CommandMap.setDefaultCommandMap(commandMap);
+        } finally {
+            Thread.currentThread().setContextClassLoader(tccl);
         }
-        CommandMap.setDefaultCommandMap(commandMap);
     }
 
     private static class MailCap {
         Bundle bundle;
-        URL url;
+        List<String> lines;
 
-        private MailCap(Bundle bundle, URL url) {
+        private MailCap(Bundle bundle, URL url) throws IOException {
             this.bundle = bundle;
-            this.url = url;
+            this.lines = new ArrayList<String>();
+            InputStream is = url.openStream();
+            try {
+                BufferedReader br = new BufferedReader(new InputStreamReader(is));
+                String line;
+                while ((line = br.readLine()) != null) {
+                    lines.add(line);
+                }
+            } finally {
+                is.close();
+            }
         }
     }
 
diff --git a/activator/src/main/java/org/apache/servicemix/specs/activator/Activator.java b/activator/src/main/java/org/apache/servicemix/specs/activator/Activator.java
index 02f5c5f..9d977a5 100644
--- a/activator/src/main/java/org/apache/servicemix/specs/activator/Activator.java
+++ b/activator/src/main/java/org/apache/servicemix/specs/activator/Activator.java
@@ -17,11 +17,14 @@
 package org.apache.servicemix.specs.activator;
 
 import java.io.BufferedReader;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
@@ -92,6 +95,11 @@
     }
 
     public void bundleChanged(BundleEvent event) {
+        synchronized (this) {
+            if (bundleContext == null) {
+                return;
+            }
+        }
         if (event.getType() == BundleEvent.RESOLVED) {
             register(event.getBundle());
         } else if (event.getType() == BundleEvent.UNRESOLVED || event.getType() == BundleEvent.UNINSTALLED) {
@@ -141,7 +149,11 @@
                 // ignored
             }
 
-            mailcaps.put(bundle.getBundleId(), new MailCap(bundle, url));
+            try {
+                mailcaps.put(bundle.getBundleId(), new MailCap(bundle, url));
+            } catch (IOException ex) {
+                // ignored
+            }
             rebuildCommandMap();
         }
     }
@@ -156,7 +168,7 @@
         }
         MailCap mailcap = mailcaps.remove(bundleId);
         if (mailcap != null ){
-            debugPrintln("removing mailcap at " + mailcap.url);
+            debugPrintln("removing mailcap for bundle " + mailcap.bundle.getBundleId());
             rebuildCommandMap();
         }
     }
@@ -176,16 +188,26 @@
         public Class call() throws Exception {
             try {
                 debugPrintln("loading factory for key: " + factoryId);
-                
+
                 if (clazz == null){
                     synchronized (this) {
                         if (clazz == null){
                             debugPrintln("creating factory for key: " + factoryId);
                             BufferedReader br = new BufferedReader(new InputStreamReader(u.openStream(), "UTF-8"));
-                            String factoryClassName = br.readLine();
-                            br.close();
-                            debugPrintln("factory implementation: " + factoryClassName);
-                            clazz = bundle.loadClass(factoryClassName);
+                            try {
+                                String factoryClassName = br.readLine();
+                                while (factoryClassName != null) {
+                                    factoryClassName = factoryClassName.trim();
+                                    if (factoryClassName.charAt(0) != '#') {
+                                        debugPrintln("factory implementation: " + factoryClassName);
+                                        clazz = bundle.loadClass(factoryClassName);
+                                        return clazz;
+                                    }
+                                    factoryClassName = br.readLine();
+                                }
+                            } finally {
+                                br.close();
+                            }
                         }
                     }
                 }
@@ -198,46 +220,6 @@
                 throw e;
             }
         }
-        
-        
-        private class MimeFactoryLoader implements Callable<Class> {
-            private final String mimeType;
-            private final URL u;
-            private final Bundle bundle;
-            private volatile Class<?> clazz;
-
-            public MimeFactoryLoader(String mimeType, URL u, Bundle bundle) {
-                this.mimeType = mimeType;
-                this.u = u;
-                this.bundle = bundle;
-            }
-
-            public Class call() throws Exception {
-                try {
-                    debugPrintln("loading factory for key: " + mimeType);
-                    
-                    if (clazz == null){
-                        synchronized (this) {
-                            if (clazz == null){
-                                debugPrintln("creating factory for key: " + factoryId);
-                                BufferedReader br = new BufferedReader(new InputStreamReader(u.openStream(), "UTF-8"));
-                                String factoryClassName = br.readLine();
-                                br.close();
-                                debugPrintln("factory implementation: " + factoryClassName);
-                                clazz = bundle.loadClass(factoryClassName);
-                            }
-                        }
-                    }
-                    return clazz;
-                } catch (Exception e) {
-                    debugPrintln("exception caught while creating factory: " + e);
-                    throw e;
-                } catch (Error e) {
-                    debugPrintln("error caught while creating factory: " + e);
-                    throw e;
-                }
-            }
-        }
 
         @Override
         public String toString() {
@@ -258,26 +240,15 @@
             }
         }
     }
-    
+
     private void rebuildCommandMap() {
         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
         try {
             Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
             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
+                for (String line : mailcap.lines) {
+                    commandMap.addMailcap(line, mailcap.bundle);
                 }
             }
             CommandMap.setDefaultCommandMap(commandMap);
@@ -285,14 +256,24 @@
             Thread.currentThread().setContextClassLoader(tccl);
         }
     }
-    
+
     private static class MailCap {
         Bundle bundle;
-        URL url;
+        List<String> lines;
 
-        private MailCap(Bundle bundle, URL url) {
+        private MailCap(Bundle bundle, URL url) throws IOException {
             this.bundle = bundle;
-            this.url = url;
+            this.lines = new ArrayList<String>();
+            InputStream is = url.openStream();
+            try {
+                BufferedReader br = new BufferedReader(new InputStreamReader(is));
+                String line;
+                while ((line = br.readLine()) != null) {
+                    lines.add(line);
+                }
+            } finally {
+                is.close();
+            }
         }
     }
 }
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 5a7867d..42f864d 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
@@ -84,6 +84,11 @@
     }
 
     public void bundleChanged(BundleEvent event) {
+        synchronized (this) {
+            if (bundleContext == null) {
+                return;
+            }
+        }
         if (event.getType() == BundleEvent.RESOLVED) {
             register(event.getBundle());
         } else if (event.getType() == BundleEvent.UNRESOLVED || event.getType() == BundleEvent.UNINSTALLED) {