I had modified the Activator of Camel-Script, register some LanguageResolver
according to the ScriptEngineFactory from ScriptEngineManager. everything is
ok.
I don't know why anybody forget to register LanguageResolver in
camel-script.


Activator.java
============
/**
 * 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.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.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;

import org.apache.camel.impl.osgi.tracker.BundleTracker;
import org.apache.camel.impl.osgi.tracker.BundleTrackerCustomizer;
import org.apache.camel.util.IOHelper;
import org.apache.camel.spi.LanguageResolver;
import org.apache.camel.builder.script.ScriptLanguageResolver;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Activator implements BundleActivator, BundleTrackerCustomizer {
    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 Map<Long, List&lt;BundleScriptEngineResolver>> resolvers 
        = new ConcurrentHashMap<Long,
List&lt;BundleScriptEngineResolver>>();
    private Map<Long, List&lt;BundleLanguageResolver>> languageResolvers 
        = new ConcurrentHashMap<Long, List&lt;BundleLanguageResolver>>();

    public static BundleContext getBundleContext() {
        return context;
    }
    
    public void start(BundleContext context) throws Exception {
        Activator.context = context;
        LOG.info("Camel-Script activator starting");
        tracker = new BundleTracker(context, Bundle.ACTIVE, this);
        tracker.open();
        LOG.info("Camel-Script activator started");
    }

    public void stop(BundleContext context) throws Exception {
        LOG.info("Camel-Script activator stopping");
        tracker.close();
        LOG.info("Camel-Script activator stopped");
        Activator.context = null;
    }

    public Object addingBundle(Bundle bundle, BundleEvent event) {
        List<BundleScriptEngineResolver> r = new
ArrayList<BundleScriptEngineResolver>();
        registerScriptEngines(bundle, r);
        for (BundleScriptEngineResolver service : r) {
            service.register();
        }
        resolvers.put(bundle.getBundleId(), r);
        
        List<BundleLanguageResolver> lr = new
ArrayList<BundleLanguageResolver>();
        registerLanguageResolver(bundle, lr);
        
        for (BundleLanguageResolver service : lr) {
            service.register();
        }
        languageResolvers.put(bundle.getBundleId(), lr);
        
        return bundle;
    }

    public void modifiedBundle(Bundle bundle, BundleEvent event, Object
object) {
    }

    public void removedBundle(Bundle bundle, BundleEvent event, Object
object) {
        LOG.debug("Bundle stopped: {}", bundle.getSymbolicName());
        List<BundleScriptEngineResolver> r =
resolvers.remove(bundle.getBundleId());
        if (r != null) {
            for (BundleScriptEngineResolver service : r) {
                service.unregister();
            }
        }
        
        List<BundleLanguageResolver> lr =
                languageResolvers.remove(bundle.getBundleId());
        if (lr != null) {
                for (BundleLanguageResolver service : lr) {
                service.register();
            }
        }
    }

    public static ScriptEngine resolveScriptEngine(String scriptEngineName)
throws InvalidSyntaxException {
        ServiceReference<?>[] refs =
context.getServiceReferences(ScriptEngineResolver.class.getName(), null);
        if (refs == null) {
            LOG.info("No OSGi script engine resolvers available!");
            return null;
        }
        
        LOG.debug("Found " + refs.length + " OSGi ScriptEngineResolver
services");
        
        for (ServiceReference<?> ref : refs) {
            ScriptEngineResolver resolver = (ScriptEngineResolver)
context.getService(ref);
            ScriptEngine engine =
resolver.resolveScriptEngine(scriptEngineName);
            context.ungetService(ref);
            LOG.debug("OSGi resolver " + resolver + " produced " +
scriptEngineName + " engine " + engine);
            if (engine != null) {
                return engine;
            }
        }
        return null;
    }

    protected void registerScriptEngines(Bundle bundle,
List<BundleScriptEngineResolver> resolvers) {
        URL configURL = null;
        for (Enumeration<?> e = bundle.findEntries(META_INF_SERVICES_DIR,
SCRIPT_ENGINE_SERVICE_FILE, false); e != null && e.hasMoreElements();) {
            configURL = (URL) e.nextElement();
        }
        if (configURL != null) {
            LOG.info("Found ScriptEngineFactory in " +
bundle.getSymbolicName());
            resolvers.add(new BundleScriptEngineResolver(bundle,
configURL));
        }
    }

    protected void registerLanguageResolver(
        Bundle bundle, List<BundleLanguageResolver> languageResolvers) {
        ScriptEngineManager manager = new ScriptEngineManager();

        List<ScriptEngineFactory> factories = manager.getEngineFactories();
        for(ScriptEngineFactory factory: factories)
        {
                languageResolvers.add(new BundleLanguageResolver(bundle, 
factory));
        }
    }

    protected static class BundleLanguageResolver
    {
        protected Bundle bundle;
        protected ScriptEngineFactory factory;
        protected ServiceRegistration reg;

        public BundleLanguageResolver(Bundle bundle, ScriptEngineFactory
factory)
        {
                this.bundle = bundle;
                this.factory = factory;
        }

        public void register() {
                try
                {
                        String language = factory.getLanguageName();

                        Hashtable<String, Object> properties =
                                new Hashtable<String, Object>();

                        properties.put("language", language);

                        reg = bundle.getBundleContext().registerService(
                                LanguageResolver.class,
                                new ScriptLanguageResolver(), properties);

                        LOG.info("Register LanguageResolver: " + language);
                } catch(Exception e)
                {
                        LOG.warn("Cannot register LanguageResolver: " +
e.getClass().getName(), e);
                }
        }
        
        public void unregister() {
                reg.unregister();
        }
    }

    public interface ScriptEngineResolver {
        ScriptEngine resolveScriptEngine(String name);
    }
    protected static class BundleScriptEngineResolver implements
ScriptEngineResolver {
        protected final Bundle bundle;
        private ServiceRegistration reg;
        private final URL configFile;

        public BundleScriptEngineResolver(Bundle bundle, URL configFile) {
            this.bundle = bundle;
            this.configFile = configFile;
        }
        public void register() {
            reg =
bundle.getBundleContext().registerService(ScriptEngineResolver.class.getName(), 
                                                            this, null);
        }
        public void unregister() {
            reg.unregister();
        }
        public ScriptEngine resolveScriptEngine(String name) {
            try {
                BufferedReader in = IOHelper.buffered(new
InputStreamReader(configFile.openStream()));
                String className = in.readLine();
                in.close();
                Class<?> cls = bundle.loadClass(className);
                if (!ScriptEngineFactory.class.isAssignableFrom(cls)) {
                    throw new IllegalStateException("Invalid
ScriptEngineFactory: " + cls.getName());
                }
                ScriptEngineFactory factory = (ScriptEngineFactory)
cls.newInstance();
                List<String> names = factory.getNames();
                for (String test : names) {
                    if (test.equals(name)) {
                        ClassLoader old =
Thread.currentThread().getContextClassLoader();
                        ScriptEngine engine;
                        try {
                            // JRuby seems to require the correct TCCL to
call getScriptEngine
                           
Thread.currentThread().setContextClassLoader(factory.getClass().getClassLoader());
                            engine = factory.getScriptEngine();
                        } finally {
                           
Thread.currentThread().setContextClassLoader(old);
                        }
                        LOG.trace("Resolved ScriptEngineFactory: {} for
expected name: {}", engine, name);
                        return engine;
                    }
                }
                LOG.debug("ScriptEngineFactory: {} does not match expected
name: {}", factory.getEngineName(), name);
                return null;
            } catch (Exception e) {
                LOG.warn("Cannot create ScriptEngineFactory: " +
e.getClass().getName(), e);
                return null;
            }
        }

        @Override
        public String toString() {
            return "OSGi script engine resolver for " +
bundle.getSymbolicName();
        }
    }

}








blueprint.xml
===========
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
    xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
    xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0";
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";>

    <camelContext xmlns="http://camel.apache.org/schema/blueprint";>
                <route>
            <from uri="jetty:http://0.0.0.0:9191/test"; />
                        <transform>
                                <language language="ECMAScript">
                                        var value = "123";
                                        var value2 = "321";
                                        
                                        var foo = function() {
                                                return "hello world!";
                                        };
                                        
                                        foo();
                                </language>
                        </transform>
            <to uri="language:javascript: request.body;" />
        </route>
    </camelContext>
</blueprint>




--
View this message in context: 
http://servicemix.396122.n5.nabble.com/help-How-to-use-javascript-with-camel-in-ServiceMix-tp5718477p5718488.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.

Reply via email to