You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2015/03/26 09:44:50 UTC

[06/11] camel git commit: CAMEL-8546: fix script language resolvers

CAMEL-8546: fix script language resolvers


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/7058dfb0
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/7058dfb0
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/7058dfb0

Branch: refs/heads/camel-2.15.x
Commit: 7058dfb0c03234a3127b4b3a73201c08c4e6a0c5
Parents: ff7a853
Author: bart <ba...@anova.be>
Authored: Wed Mar 25 16:59:57 2015 +0100
Committer: Willem Jiang <wi...@gmail.com>
Committed: Thu Mar 26 16:42:22 2015 +0800

----------------------------------------------------------------------
 .../org/apache/camel/script/osgi/Activator.java | 90 ++++++++++++++++----
 1 file changed, 73 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/7058dfb0/components/camel-script/src/main/java/org/apache/camel/script/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/components/camel-script/src/main/java/org/apache/camel/script/osgi/Activator.java b/components/camel-script/src/main/java/org/apache/camel/script/osgi/Activator.java
index 3dd1c73..76f02a5 100644
--- a/components/camel-script/src/main/java/org/apache/camel/script/osgi/Activator.java
+++ b/components/camel-script/src/main/java/org/apache/camel/script/osgi/Activator.java
@@ -19,10 +19,7 @@ package org.apache.camel.script.osgi;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 import javax.script.ScriptEngine;
@@ -30,27 +27,23 @@ import javax.script.ScriptEngineFactory;
 
 import org.apache.camel.impl.osgi.tracker.BundleTracker;
 import org.apache.camel.impl.osgi.tracker.BundleTrackerCustomizer;
+import org.apache.camel.spi.LanguageResolver;
 import org.apache.camel.util.IOHelper;
 
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.*;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Activator implements BundleActivator, BundleTrackerCustomizer {
+public class Activator implements BundleActivator, BundleTrackerCustomizer, ServiceListener {
     public static final String META_INF_SERVICES_DIR = "META-INF/services";
     public static final String SCRIPT_ENGINE_SERVICE_FILE = "javax.script.ScriptEngineFactory";
 
     private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
     private static BundleContext context;
     private BundleTracker tracker;
-    
+    private ServiceRegistration<LanguageResolver> registration;
+
     private Map<Long, List<BundleScriptEngineResolver>> resolvers 
         = new ConcurrentHashMap<Long, List<BundleScriptEngineResolver>>();
 
@@ -63,12 +56,17 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer {
         LOG.info("Camel-Script activator starting");
         tracker = new BundleTracker(context, Bundle.ACTIVE, this);
         tracker.open();
+        context.addServiceListener(this, "(&(resolver=default)(objectClass=org.apache.camel.spi.LanguageResolver))");
         LOG.info("Camel-Script activator started");
     }
 
     public void stop(BundleContext context) throws Exception {
         LOG.info("Camel-Script activator stopping");
         tracker.close();
+        context.removeServiceListener(this);
+        if (registration != null) {
+            registration.unregister();
+        }
         LOG.info("Camel-Script activator stopped");
         Activator.context = null;
     }
@@ -80,6 +78,7 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer {
             service.register();
         }
         resolvers.put(bundle.getBundleId(), r);
+        updateAvailableScriptLanguages();
         return bundle;
     }
 
@@ -90,12 +89,46 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer {
         LOG.debug("Bundle stopped: {}", bundle.getSymbolicName());
         List<BundleScriptEngineResolver> r = resolvers.remove(bundle.getBundleId());
         if (r != null) {
+            updateAvailableScriptLanguages();
             for (BundleScriptEngineResolver service : r) {
                 service.unregister();
             }
         }
     }
 
+    private String[] getAvailableScriptNames(){
+        List<String> names = new ArrayList<String>();
+        for (List<BundleScriptEngineResolver> list : resolvers.values()) {
+            for (BundleScriptEngineResolver r : list) {
+                names.addAll(r.getScriptNames());
+            }
+        }
+        return names.toArray(new String[]{});
+    }
+
+    private void updateAvailableScriptLanguages() {
+        if (registration != null) {
+            registration.unregister();
+            registration = null;
+        }
+        ServiceReference<LanguageResolver> ref = null;
+        try {
+            Collection<ServiceReference<LanguageResolver>> references = context.getServiceReferences(LanguageResolver.class, "(resolver=default)");
+            if (references.size() == 1) {
+                ref = references.iterator().next();
+                LanguageResolver resolver = context.getService(ref);
+
+                Dictionary props = new Hashtable();
+                props.put("language", getAvailableScriptNames());
+                registration = context.registerService(LanguageResolver.class, resolver, props);
+            }
+        } catch (InvalidSyntaxException e) {
+            LOG.error("Invalid syntax for LanguageResolver service reference filter.");
+        } finally {
+            context.ungetService(ref);
+        }
+    }
+
     public static ScriptEngine resolveScriptEngine(String scriptEngineName) throws InvalidSyntaxException {
         ServiceReference<?>[] refs = context.getServiceReferences(ScriptEngineResolver.class.getName(), null);
         if (refs == null) {
@@ -126,7 +159,12 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer {
             LOG.info("Found ScriptEngineFactory in " + bundle.getSymbolicName());
             resolvers.add(new BundleScriptEngineResolver(bundle, configURL));
         }
-    } 
+    }
+
+    @Override
+    public void serviceChanged(ServiceEvent event) {
+        updateAvailableScriptLanguages();
+    }
 
     public interface ScriptEngineResolver {
         ScriptEngine resolveScriptEngine(String name);
@@ -150,7 +188,16 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer {
             reg.unregister();
         }
 
-        public ScriptEngine resolveScriptEngine(String name) {
+        private List<String> getScriptNames() {
+            return getScriptNames(getFactory());
+        }
+
+        private List<String> getScriptNames(ScriptEngineFactory factory){
+            List<String> names = factory.getNames();
+            return names;
+        }
+
+        private ScriptEngineFactory getFactory() {
             try {
                 BufferedReader in = IOHelper.buffered(new InputStreamReader(configFile.openStream()));
                 String className = in.readLine();
@@ -159,8 +206,17 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer {
                 if (!ScriptEngineFactory.class.isAssignableFrom(cls)) {
                     throw new IllegalStateException("Invalid ScriptEngineFactory: " + cls.getName());
                 }
-                ScriptEngineFactory factory = (ScriptEngineFactory) cls.newInstance();
-                List<String> names = factory.getNames();
+                return (ScriptEngineFactory) cls.newInstance();
+            }catch (Exception e){
+                //do something
+                return null;
+            }
+        }
+
+        public ScriptEngine resolveScriptEngine(String name) {
+            try {
+                ScriptEngineFactory factory = getFactory();
+                List<String> names = getScriptNames(factory);
                 for (String test : names) {
                     if (test.equals(name)) {
                         ClassLoader old = Thread.currentThread().getContextClassLoader();