Package ccw.util.osgi

Source Code of ccw.util.osgi.ClojureOSGi

package ccw.util.osgi;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;

import org.osgi.framework.Bundle;

import ccw.CCWPlugin;
import ccw.TraceOptions;
import clojure.lang.Compiler;
import clojure.lang.IPersistentMap;
import clojure.lang.RT;
import clojure.lang.Symbol;
import clojure.lang.Var;

public class ClojureOSGi {
  private static volatile boolean initialized;
  private synchronized static void initialize() {
    if (initialized) return;
   
    CCWPlugin plugin = CCWPlugin.getDefault();
    if (plugin == null) {
      System.out.println("======= ClojureOSGi.initialize will fail because ccw.core plugin not activated yet");
      System.out.flush();
    }
    ClassLoader loader = new BundleClassLoader(plugin.getBundle());
    ClassLoader saved = Thread.currentThread().getContextClassLoader();
    try {
      Thread.currentThread().setContextClassLoader(loader);
      Class.forName("clojure.lang.RT", true, loader); // very important, uses the right classloader
      CCWPlugin.getTracer().trace(TraceOptions.CLOJURE_OSGI, "namespace clojure.core loaded");
      initialized = true;
    } catch (Exception e) {
      throw new RuntimeException(
          "Exception while loading namespace clojure.core", e);
    } finally {
      Thread.currentThread().setContextClassLoader(saved);
    }
   
  }
  public synchronized static Object withBundle(Bundle aBundle, RunnableWithException aCode)
      throws RuntimeException {
    return withBundle(aBundle, aCode, null);
  }
 
  public synchronized static Object withBundle(Bundle aBundle, RunnableWithException aCode, List<URL> additionalURLs)
      throws RuntimeException {
   
    initialize();
   
    ClassLoader bundleLoader = new BundleClassLoader(aBundle);
    final URL[] urls = (additionalURLs == null) ? new URL[] {} : additionalURLs.toArray(new URL[additionalURLs.size()]);
    URLClassLoader loader = new URLClassLoader(urls, bundleLoader);
    IPersistentMap bindings = RT.map(Compiler.LOADER, loader);

    boolean pushed = true;

    ClassLoader saved = Thread.currentThread().getContextClassLoader();

    try {
      Thread.currentThread().setContextClassLoader(loader);

      try {
        Var.pushThreadBindings(bindings);
      } catch (RuntimeException aEx) {
        pushed = false;
        throw aEx;
      }

      return aCode.run();
     
    } catch (Exception e) {
      String msg = "Exception while executing code from bundle "
          + aBundle.getSymbolicName();
      CCWPlugin.getTracer().trace(TraceOptions.CLOJURE_OSGI, e,
          msg);
      throw new RuntimeException(msg, e);
    } finally {
      if (pushed)
        Var.popThreadBindings();

      Thread.currentThread().setContextClassLoader(saved);
    }
  }

  public synchronized static void require(final Bundle bundle, final String namespace) {
    ClojureOSGi.withBundle(bundle, new RunnableWithException() {
      @Override
      public Object run() throws Exception {
        try {
          RT.var("clojure.core", "require").invoke(Symbol.intern(namespace));
          CCWPlugin.getTracer().trace(TraceOptions.CLOJURE_OSGI, "Namespace " + namespace + " loaded from bundle " + bundle.getSymbolicName());
          return null;
        } catch (Exception e) {
          String msg = "Exception loading namespace " + namespace + " from bundle " + bundle.getSymbolicName();
          CCWPlugin.getTracer().trace(TraceOptions.CLOJURE_OSGI, e, msg);
          throw new RuntimeException(msg, e);
        }
      }
    });
  }
}
TOP

Related Classes of ccw.util.osgi.ClojureOSGi

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.