aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From timothyjw...@apache.org
Subject svn commit: r1161653 [2/2] - in /aries/trunk/ejb: ./ ejb-modeller-itest/ ejb-modeller-itest/src/test/java/org/apache/aries/ejb/container/itest/ openejb-extender-itest/ openejb-extender-itest/src/ openejb-extender-itest/src/test/ openejb-extender-itest/...
Date Thu, 25 Aug 2011 17:26:20 GMT
Added: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java?rev=1161653&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java
(added)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java
Thu Aug 25 17:26:19 2011
@@ -0,0 +1,238 @@
+/**
+ *  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.aries.ejb.openejb.extender;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.WeakHashMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.resource.spi.IllegalStateException;
+
+import org.apache.aries.proxy.InvocationListener;
+import org.apache.aries.proxy.ProxyManager;
+import org.apache.aries.proxy.UnableToProxyException;
+import org.apache.aries.util.tracker.SingleServiceTracker;
+import org.apache.aries.util.tracker.SingleServiceTracker.SingleServiceListener;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.util.proxy.InvocationHandler;
+import org.apache.openejb.util.proxy.ProxyFactory;
+import org.osgi.framework.BundleContext;
+
+public class AriesProxyService implements ProxyFactory, SingleServiceListener {
+
+  private static class NoProxySupportException extends RuntimeException { 
+    public NoProxySupportException() {
+      super("No Proxy support is available");
+    }
+  }
+  
+  private static final class InvocationHandlerProxy implements Callable<Object>, InvocationListener
{
+
+    private final InvocationHandler handler;
+    
+    private final Map<Thread, Class<?>> invocations = new ConcurrentHashMap<Thread,
Class<?>>();
+    private final ConcurrentMap<Class<?>, Object> proxys = new ConcurrentHashMap<Class<?>,
Object>();
+
+    public InvocationHandlerProxy(InvocationHandler handler) {
+      this.handler = handler;
+    }
+
+    public InvocationHandler getHandler() {
+      return handler;
+    }
+
+    public void postInvoke(Object arg0, Object arg1, Method arg2, Object arg3)
+        throws Throwable {
+      // No op
+    }
+
+    public void postInvokeExceptionalReturn(Object arg0, Object arg1,
+        Method arg2, Throwable arg3) throws Throwable {
+      //No op
+    }
+
+    public Object preInvoke(Object arg0, Method arg1, Object[] arg2)
+        throws Throwable {
+      invocations.put(Thread.currentThread(), arg1.getDeclaringClass());
+      return null;
+    }
+
+    public Object call() throws Exception {
+      Class<?> c = invocations.remove(Thread.currentThread());
+      if(c == null)
+        throw new IllegalStateException("Unable to establish any context");
+      else if (c.equals(Object.class)) {
+        c = Serializable.class;
+      }
+      
+      Object proxy = proxys.get(c);
+      
+      if(proxy == null) {
+        Object tmp = Proxy.newProxyInstance(c.getClassLoader(), new Class[] {c}, handler);
+        proxy = proxys.putIfAbsent(c, tmp);
+        if(proxy == null)
+          proxy = tmp;
+      }
+      return proxy;
+    }
+    
+  }
+  
+  private static class InnerProxyDelegator implements Callable<Object> {
+
+    private final Object delegate;
+    
+    public InnerProxyDelegator(Object delegate) {
+      this.delegate = delegate;
+    }
+    
+    public Object call() {
+      return delegate;
+    }
+  }
+  
+  private final Map<Class<?>, Object> proxies = Collections.synchronizedMap(
+      new WeakHashMap<Class<?>, Object>());
+  
+  private final SingleServiceTracker<ProxyManager> proxyTracker;
+  
+  private AriesProxyService(BundleContext ctx) {
+    proxyTracker = new SingleServiceTracker<ProxyManager>(ctx, ProxyManager.class,
this);
+    proxyTracker.open();
+  }
+  
+  private final AtomicReference<ProxyManager> manager = 
+    new AtomicReference<ProxyManager>();
+  
+  private static final AtomicReference<AriesProxyService> INSTANCE = 
+    new AtomicReference<AriesProxyService>();
+  
+  private final ProxyManager getManager() {
+    ProxyManager pManager = manager.get();
+    
+    if(pManager == null) {
+      throw new NoProxySupportException();
+    }
+    return pManager;
+  }
+
+  public static AriesProxyService get() {
+    return INSTANCE.get();
+  }
+  
+  public static void init(BundleContext ctx) {
+    AriesProxyService oTM = new AriesProxyService(ctx);
+    if(!!!INSTANCE.compareAndSet(null, oTM))
+      oTM.destroy();
+  }
+  
+  public void destroy() {
+    proxyTracker.close();
+  }
+  
+  public void serviceFound() {
+    update();
+  }
+
+  public void serviceLost() {
+    update();
+  }
+
+  public void serviceReplaced() {
+    update();
+  }
+  
+  private void update() {
+    manager.set(proxyTracker.getService());
+  }
+  
+  
+  
+  public InvocationHandler getInvocationHandler(Object arg0)
+      throws IllegalArgumentException {
+    Callable<Object> unwrapped = getManager().unwrap(arg0);
+    
+    if(unwrapped instanceof InnerProxyDelegator) {
+      unwrapped = getManager().unwrap(((InnerProxyDelegator)unwrapped).call());
+    }
+    
+    if(unwrapped instanceof InvocationHandlerProxy) {
+      return ((InvocationHandlerProxy) unwrapped).getHandler();
+    }
+    return null;
+  }
+
+  public Class getProxyClass(Class iface) throws IllegalArgumentException {
+    if(iface == null || !!!iface.isInterface())
+      throw new IllegalArgumentException("Not an interface " + iface);
+    return newProxyInstance(iface, null).getClass();
+  }
+
+  public Class getProxyClass(Class[] ifaces) throws IllegalArgumentException {
+    if(ifaces == null || ifaces.length == 0)
+      throw new IllegalArgumentException("No interfaces.");
+    
+    for(Class iface : ifaces) {
+      if (!!!iface.isInterface())
+        throw new IllegalArgumentException("Not an interface " + iface + " in " + Arrays.toString(ifaces));
+    }
+    
+    return newProxyInstance(ifaces, null).getClass();
+  }
+
+  public void init(Properties arg0) throws OpenEJBException {
+    //No op
+  }
+
+  public boolean isProxyClass(Class arg0) {
+    return proxies.containsKey(arg0);
+  }
+
+  public Object newProxyInstance(Class iface, InvocationHandler arg1)
+      throws IllegalArgumentException {
+    return newProxyInstance(new Class[] {iface}, arg1);
+  }
+
+  public Object newProxyInstance(Class[] ifaces, InvocationHandler arg1)
+      throws IllegalArgumentException {
+    InvocationHandlerProxy ihProxy = new InvocationHandlerProxy(arg1);
+    List<Class<?>> classes = new ArrayList<Class<?>>();
+    for(Class<?> iface : ifaces)
+      classes.add(iface);
+    try {
+      Object inner = getManager().createDelegatingProxy(null, classes, ihProxy, null);
+      
+      Object proxy = getManager().createDelegatingInterceptingProxy(null, classes, 
+          new InnerProxyDelegator(inner), null, ihProxy);
+      proxies.put(proxy.getClass(), null);
+      return proxy;
+    } catch (UnableToProxyException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+}

Added: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java?rev=1161653&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java
(added)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java
Thu Aug 25 17:26:19 2011
@@ -0,0 +1,405 @@
+/**
+ *  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.aries.ejb.openejb.extender;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.naming.NamingException;
+
+import org.apache.aries.util.AriesFrameworkUtil;
+import org.apache.aries.util.manifest.ManifestHeaderProcessor;
+import org.apache.aries.util.manifest.ManifestHeaderProcessor.NameValuePair;
+import org.apache.aries.util.tracker.RecursiveBundleTracker;
+import org.apache.openejb.AppContext;
+import org.apache.openejb.BeanContext;
+import org.apache.openejb.ContainerType;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
+import org.apache.openejb.assembler.classic.ProxyInterfaceResolver;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.assembler.dynamic.PassthroughFactory;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.ri.sp.PseudoSecurityService;
+import org.apache.openejb.util.OpenEjbVersion;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+
+public class EJBExtender implements BundleActivator, BundleTrackerCustomizer {
+
+  private static final int STARTABLE = Bundle.STARTING | Bundle.ACTIVE;
+  
+  private static final Object PROCESSING_OBJECT = new Object();
+  private static final Object REMOVING_OBJECT = new Object();
+  private static final String NONE = "NONE";
+  private static final String ALL = "ALL";
+  
+  private RecursiveBundleTracker tracker;
+  
+  private final ConcurrentMap<Bundle, RunningApplication> runningApps = 
+       new ConcurrentHashMap<Bundle, RunningApplication>();
+  
+  private final ConcurrentMap<Bundle, Object> processingMap = 
+       new ConcurrentHashMap<Bundle, Object>();
+  
+  public void start(BundleContext context) throws Exception {
+
+    //Internal setup
+    OSGiTransactionManager.init(context);
+    AriesProxyService.init(context);
+    
+    
+    //Setup OpenEJB with our own extensions
+    setupOpenEJB();
+    
+    tracker = new RecursiveBundleTracker(context, Bundle.INSTALLED | Bundle.RESOLVED | 
+        Bundle.STARTING | Bundle.ACTIVE | Bundle.STOPPING, this);
+
+    tracker.open();
+  }
+
+  private void setupOpenEJB() throws OpenEJBException {
+    //Avoid a ClassLoader problem 
+    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+    try {
+      Thread.currentThread().setContextClassLoader(OpenEjbVersion.class.getClassLoader());
+      OpenEjbVersion.get();
+    } finally {
+      Thread.currentThread().setContextClassLoader(cl);
+    }
+    
+    Assembler a = new Assembler();
+    TransactionServiceInfo tsi = new TransactionServiceInfo();
+    tsi.service = "TransactionManager";
+    tsi.id = "OSGi Transaction Manager";
+    PassthroughFactory.add(tsi, OSGiTransactionManager.get());
+    //Avoid another ClassLoader problem
+    try {
+      Thread.currentThread().setContextClassLoader(PassthroughFactory.class.getClassLoader());
+      a.createTransactionManager(tsi);
+    } finally {
+      Thread.currentThread().setContextClassLoader(cl);
+    }
+    
+    SecurityServiceInfo ssi = new SecurityServiceInfo();
+    ssi.service = "SecurityService";
+    ssi.id = "Pseudo Security Service";
+    PassthroughFactory.add(ssi, new PseudoSecurityService());
+    //Avoid another ClassLoader problem
+    try {
+      Thread.currentThread().setContextClassLoader(PassthroughFactory.class.getClassLoader());
+      a.createSecurityService(ssi);
+    } finally {
+      Thread.currentThread().setContextClassLoader(cl);
+    }
+    
+    
+    ProxyFactoryInfo proxyFactoryInfo = new ProxyFactoryInfo();
+    proxyFactoryInfo.id = "Aries ProxyFactory";
+    proxyFactoryInfo.service = "ProxyFactory";
+    proxyFactoryInfo.properties = new Properties();
+    PassthroughFactory.add(proxyFactoryInfo, AriesProxyService.get());
+    try {
+      Thread.currentThread().setContextClassLoader(PassthroughFactory.class.getClassLoader());
+      a.createProxyFactory(proxyFactoryInfo);
+    } finally {
+      Thread.currentThread().setContextClassLoader(cl);
+    }
+  }
+
+  public void stop(BundleContext context) throws Exception {
+    tracker.close();
+    AriesProxyService.get().destroy();
+    OSGiTransactionManager.get().destroy();
+  }
+
+  public Object addingBundle(Bundle bundle, BundleEvent event) {
+    
+    if(mightContainEJBs(bundle)) {
+      if((bundle.getState() & STARTABLE) != 0) {
+        startEJBs(bundle);
+      }
+      return bundle;
+    }
+    return null;
+  }
+
+
+  private boolean mightContainEJBs(Bundle bundle) {
+    Dictionary<String, String> headers = bundle.getHeaders();
+    return (headers.get("Export-EJB") != null) || (headers.get("Web-ContextPath") != null);
+  }
+
+  public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+    if((bundle.getState() & STARTABLE) != 0) {
+      startEJBs(bundle);
+    } else if (bundle.getState() == Bundle.STOPPING) {
+      stopEJBs(bundle);
+    }
+  }
+
+  private void startEJBs(final Bundle bundle) {
+
+    try {
+      //If there is another thread adding or removing then stop here
+      Object o = processingMap.put(bundle, PROCESSING_OBJECT);
+      if(o == REMOVING_OBJECT || o == PROCESSING_OBJECT) {
+        return;
+      }
+      //If already running then avoid
+      if(runningApps.get(bundle) != null)
+        return;
+      
+      EjbModule ejbModule = new EjbModule(AriesFrameworkUtil.getClassLoaderForced(bundle),
+          null, null, null);
+      
+      addAltDDs(ejbModule, bundle);
+      //We build our own because we can't trust anyone to get the classpath right otherwise!
+      ejbModule.setFinder(new OSGiFinder(bundle));
+      
+      ConfigurationFactory configurationFactory = new ConfigurationFactory();
+      
+      EjbJarInfo ejbInfo = null;
+      //Avoid yet another ClassLoading problem
+      ClassLoader cl = Thread.currentThread().getContextClassLoader();
+      try {
+        Thread.currentThread().setContextClassLoader(new ClassLoader(OpenEjbVersion.class.getClassLoader())
{
+          protected Class<?> findClass(String name) throws ClassNotFoundException {
+            for(Bundle b : bundle.getBundleContext().getBundles()) {
+              if(b.getSymbolicName().contains("jaxb-impl"))
+                return b.loadClass(name);
+            
+            }
+            throw new ClassNotFoundException(name);
+          }
+        });
+        
+        ejbInfo = configurationFactory.configureApplication(ejbModule);
+        //Another oddity here
+        ejbInfo.validationInfo = null;
+      } finally {
+        Thread.currentThread().setContextClassLoader(cl);
+      }
+      
+      
+      Assembler assembler = (Assembler) SystemInstance.get().getComponent(Assembler.class);
+      RunningApplication app = null;
+      try {
+        SystemInstance.get().setProperty("openejb.geronimo", "true");
+        cl = Thread.currentThread().getContextClassLoader();
+        try {
+          Thread.currentThread().setContextClassLoader(OpenEjbVersion.class.getClassLoader());
+          app = new RunningApplication(assembler.createApplication(ejbInfo, 
+              new AppClassLoader(ejbModule.getClassLoader())));
+        } finally {
+          Thread.currentThread().setContextClassLoader(cl);
+        }
+      } finally {
+        SystemInstance.get().getProperties().remove("openejb.geronimo");
+      }
+      runningApps.put(bundle, app);
+      
+      app.addRegs(registerEJBs(app.getCtx(), bundle));
+      
+    } catch (OpenEJBException oee) {
+      // TODO Auto-generated catch block
+      oee.printStackTrace();
+    } catch (NamingException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    } finally {
+      if(processingMap.remove(bundle) == REMOVING_OBJECT) {
+        stopEJBs(bundle);
+      }
+    }
+  }
+
+  private void addAltDDs(EjbModule ejbModule, Bundle bundle) {
+    
+    Map<String, Object> altDDs = ejbModule.getAltDDs(); 
+    
+    String folder = (bundle.getHeaders().get("Web-ContextPath") == null) ? 
+        "META-INF" : "WEB-INF";
+    
+    Enumeration<URL> e = bundle.findEntries(folder, "*.xml", false);
+    if(e == null)
+      return;
+    
+    for(URL u : Collections.list(e)) {
+      
+      String urlString = u.toExternalForm();
+      urlString = urlString.substring(urlString.lastIndexOf('/') + 1);
+        
+      altDDs.put(urlString, u);
+    }
+    //Persistence descriptors are handled by Aries JPA
+    altDDs.remove("persistence.xml");
+  }
+
+  private Collection<ServiceRegistration<?>> registerEJBs(AppContext appCtx,
Bundle bundle) {
+    
+    Collection<ServiceRegistration<?>> regs = new ArrayList<ServiceRegistration<?>>();
+    
+    Collection<String> names = new HashSet<String>();
+    
+    Dictionary<String, String> d = bundle.getHeaders();
+    String valueOfExportEJBHeader = d.get("Export-EJB");
+    
+    if((valueOfExportEJBHeader == null)||(valueOfExportEJBHeader.equals(""))){
+      return Collections.emptyList();
+    }
+    
+    List<NameValuePair> contentsOfExportEJBHeader = ManifestHeaderProcessor.parseExportString(valueOfExportEJBHeader);
+    for(NameValuePair nvp:contentsOfExportEJBHeader){
+      names.add(nvp.getName());
+    }
+    
+    if(names.contains(NONE)){
+      return Collections.emptyList();
+    }
+    
+    if(names.contains(ALL)){
+      names = new AllCollection<String>();
+    }
+    
+    //Register our session beans
+    for (BeanContext beanContext : appCtx.getDeployments()) {
+      String ejbName = beanContext.getEjbName();
+      //Skip if not a Singleton or stateless bean
+      ContainerType type = beanContext.getContainer().getContainerType();
+      boolean register = type == ContainerType.SINGLETON || type == ContainerType.STATELESS;
+      
+      //Skip if not allowed name
+      register &= names.contains(ejbName);
+      
+      if(!register) {
+        continue;
+      }
+      
+      if (beanContext.isLocalbean()) {
+
+        BeanContext.BusinessLocalBeanHome home = beanContext.getBusinessLocalBeanHome();
+    
+        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
+        
+        props.put("ejb.name", ejbName);
+        props.put("ejb.type", getCasedType(type));
+        regs.add(bundle.getBundleContext().registerService(beanContext.getBeanClass().getName(),

+            new EJBServiceFactory(home), props));
+      }
+
+  
+      for (Class<?> interfce : beanContext.getBusinessLocalInterfaces()) {
+
+        BeanContext.BusinessLocalHome home = beanContext.getBusinessLocalHome(interfce);
+        
+        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
+        
+        props.put("ejb.name", ejbName);
+        props.put("ejb.type", getCasedType(type));
+        regs.add(bundle.getBundleContext().registerService(interfce.getName(), 
+            new EJBServiceFactory(home), props));
+      }
+      
+      for (Class<?> interfce : beanContext.getBusinessRemoteInterfaces()) {
+
+        List<Class> interfaces = ProxyInterfaceResolver.getInterfaces(beanContext.getBeanClass(),

+            interfce, beanContext.getBusinessRemoteInterfaces());
+        BeanContext.BusinessRemoteHome home = beanContext.getBusinessRemoteHome(interfaces,
interfce);
+        
+        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
+        
+        props.put("sevice.exported.interfaces", interfce.getName());
+        props.put("ejb.name", ejbName);
+        props.put("ejb.type", getCasedType(type));
+        regs.add(bundle.getBundleContext().registerService(interfce.getName(), 
+            new EJBServiceFactory(home), props));
+      }
+    }
+    return regs;
+  }
+
+  private String getCasedType(ContainerType type) {
+    String s = type.toString().substring(0,1).toUpperCase();
+    s += type.toString().substring(1).toLowerCase();
+    return s;
+  }
+
+  private void stopEJBs(Bundle bundle) {
+    if(processingMap.put(bundle, REMOVING_OBJECT) == PROCESSING_OBJECT)
+      return;
+    else {
+      try {
+        RunningApplication app = runningApps.remove(bundle);
+        if(app != null) {
+          for(ServiceRegistration<?> reg : app.getRegs()) {
+            AriesFrameworkUtil.safeUnregisterService(reg);
+          }
+          Assembler assembler = (Assembler) SystemInstance.get().getComponent(Assembler.class);
+          assembler.destroyApplication(app.getCtx());
+        }
+      } catch (OpenEJBException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      } finally {
+        if(processingMap.remove(bundle) == PROCESSING_OBJECT)
+          startEJBs(bundle);
+      }
+    }
+  }
+  
+  public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+    if (bundle.getState() == Bundle.STOPPING) {
+      stopEJBs(bundle);
+    }
+  }
+  
+  private static final class AppClassLoader extends ClassLoader {
+    private AppClassLoader(ClassLoader parentLoader) {
+      super(parentLoader);
+    }
+
+    @Override
+    protected Class<?> findClass(String className)
+        throws ClassNotFoundException {
+      return Class.forName(className, false, OpenEjbVersion.class.getClassLoader());
+    }
+  }
+}

Added: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBServiceFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBServiceFactory.java?rev=1161653&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBServiceFactory.java
(added)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBServiceFactory.java
Thu Aug 25 17:26:19 2011
@@ -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.aries.ejb.openejb.extender;
+
+import java.lang.reflect.Method;
+
+import org.apache.openejb.BeanContext.BusinessLocalBeanHome;
+import org.apache.openejb.BeanContext.BusinessLocalHome;
+import org.apache.openejb.BeanContext.BusinessRemoteHome;
+import org.apache.openejb.core.ivm.BaseEjbProxyHandler;
+import org.apache.openejb.util.proxy.InvocationHandler;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class EJBServiceFactory implements ServiceFactory<Object>{
+
+  private static enum Type {LOCAL, LOCAL_NO_IFACE, REMOTE;}
+  
+  private final BusinessLocalBeanHome localBeanHome;
+  private final BusinessLocalHome localHome;
+  private final BusinessRemoteHome remoteHome;
+  
+  private final Type type;
+  
+  public EJBServiceFactory(BusinessLocalBeanHome home) {
+    this.localBeanHome = home;
+    type = Type.LOCAL_NO_IFACE;
+    this.remoteHome = null;
+    this.localHome = null;
+  }
+
+  public EJBServiceFactory(BusinessLocalHome home) {
+    this.localHome = home;
+    type = Type.LOCAL;
+    this.remoteHome = null;
+    this.localBeanHome = null;
+  }
+
+  public EJBServiceFactory(BusinessRemoteHome home) {
+    this.remoteHome = home;
+    type = Type.REMOTE;
+    this.localHome = null;
+    this.localBeanHome = null;
+  }
+
+  public Object getService(Bundle bundle,
+      ServiceRegistration<Object> registration) {
+    switch(type) {
+      case LOCAL :
+        return localHome.create();
+      case LOCAL_NO_IFACE :
+        return localBeanHome.create();
+      case REMOTE : {
+        InvocationHandler ih = AriesProxyService.get().getInvocationHandler(remoteHome);
+        
+        if(ih instanceof BaseEjbProxyHandler) {
+          ((BaseEjbProxyHandler)ih).setIntraVmCopyMode(false);
+        }
+        return remoteHome.create();
+      }
+      default :
+        throw new IllegalArgumentException("Unknown EJB type " + type);
+    }
+  }
+
+  public void ungetService(Bundle bundle,
+      ServiceRegistration<Object> registration, Object service) {
+  }
+}

Added: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiFinder.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiFinder.java?rev=1161653&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiFinder.java
(added)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiFinder.java
Thu Aug 25 17:26:19 2011
@@ -0,0 +1,57 @@
+/**
+ *  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.aries.ejb.openejb.extender;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.xbean.finder.AbstractFinder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OSGiFinder extends AbstractFinder {
+
+  private final Bundle b;
+
+  private static final Logger logger = LoggerFactory.getLogger(OSGiFinder.class);
+  
+  public OSGiFinder(Bundle bundle) {
+    b = bundle;
+    
+    for(String resource : bundle.adapt(BundleWiring.class).
+        listResources("/", "*.class", BundleWiring.LISTRESOURCES_RECURSE)) {
+      
+      try {
+        readClassDef(getResource(resource).openStream());
+      } catch (IOException e) {
+        logger.warn("Error processing class file " + resource);
+      }
+    }
+  }
+
+  @Override
+  protected URL getResource(String name) {
+    return b.getResource(name);
+  }
+
+  @Override
+  protected Class<?> loadClass(String className) throws ClassNotFoundException {
+    return b.loadClass(className);
+  }
+}

Added: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java?rev=1161653&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java
(added)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java
Thu Aug 25 17:26:19 2011
@@ -0,0 +1,187 @@
+/**
+ *  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.aries.ejb.openejb.extender;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+
+import org.apache.aries.util.tracker.SingleServiceTracker;
+import org.apache.aries.util.tracker.SingleServiceTracker.SingleServiceListener;
+import org.osgi.framework.BundleContext;
+
+public class OSGiTransactionManager implements TransactionManager,
+    TransactionSynchronizationRegistry, SingleServiceListener {
+
+  private static class NoTransactionManagerException extends SystemException { 
+    public NoTransactionManagerException() {
+      super("No Transaction Manager is available");
+    }
+  }
+  
+  private static class NoTransactionSynchronizationRegistryException extends RuntimeException
{ 
+    public NoTransactionSynchronizationRegistryException() {
+      super("No Transaction Synchronization Registry is available");
+    }
+  }
+  
+  private final SingleServiceTracker<TransactionManager> tmTracker;
+  private final SingleServiceTracker<TransactionSynchronizationRegistry> tsrTracker;
+  
+  private final AtomicReference<TransactionManager> tm = 
+    new AtomicReference<TransactionManager>();
+  
+  private final AtomicReference<TransactionSynchronizationRegistry> tsr = 
+    new AtomicReference<TransactionSynchronizationRegistry>();
+  
+  private static final AtomicReference<OSGiTransactionManager> INSTANCE =
+    new AtomicReference<OSGiTransactionManager>();
+  
+  private OSGiTransactionManager(BundleContext ctx) {
+    tmTracker = new SingleServiceTracker<TransactionManager>(ctx, TransactionManager.class,
this);
+    tsrTracker = new SingleServiceTracker<TransactionSynchronizationRegistry>(ctx,

+        TransactionSynchronizationRegistry.class, this);
+    
+    tmTracker.open();
+    tsrTracker.open();
+  }
+  
+  private final TransactionManager getTM() throws SystemException {
+    TransactionManager tManager = tm.get();
+    
+    if(tManager == null) {
+      throw new NoTransactionManagerException();
+    }
+    return tManager;
+  }
+  
+  private final TransactionSynchronizationRegistry getTSR() {
+    TransactionSynchronizationRegistry tSReg = tsr.get();
+    
+    if(tSReg == null) {
+      throw new NoTransactionSynchronizationRegistryException();
+    }
+    return tSReg;
+  }
+  
+  public static OSGiTransactionManager get() {
+    return INSTANCE.get();
+  }
+  
+  public static void init(BundleContext ctx) {
+    OSGiTransactionManager oTM = new OSGiTransactionManager(ctx);
+    if(!!!INSTANCE.compareAndSet(null, oTM))
+      oTM.destroy();
+  }
+  
+  public void destroy() {
+    tmTracker.close();
+    tsrTracker.close();
+  }
+  
+  public void serviceFound() {
+    update();
+  }
+
+  public void serviceLost() {
+    update();
+  }
+
+  public void serviceReplaced() {
+    update();
+  }
+  
+  private void update() {
+    tm.set(tmTracker.getService());
+    tsr.set(tsrTracker.getService());
+  }
+  
+  public void begin() throws NotSupportedException, SystemException {
+    getTM().begin();
+  }
+  
+  public void commit() throws HeuristicMixedException,
+      HeuristicRollbackException, IllegalStateException, RollbackException,
+      SecurityException, SystemException {
+    getTM().commit();
+  }
+  
+  public int getStatus() throws SystemException {
+    return getTM().getStatus();
+  }
+  
+  public Transaction getTransaction() throws SystemException {
+    return getTM().getTransaction();
+  }
+  
+  public void resume(Transaction arg0) throws IllegalStateException,
+      InvalidTransactionException, SystemException {
+    getTM().resume(arg0);
+  }
+  
+  public void rollback() throws IllegalStateException, SecurityException,
+      SystemException {
+    getTM().rollback();
+  }
+  
+  public void setRollbackOnly() throws IllegalStateException {
+    getTSR().setRollbackOnly();
+  }
+  
+  public void setTransactionTimeout(int arg0) throws SystemException {
+    getTM().setTransactionTimeout(arg0);
+  }
+  
+  public Transaction suspend() throws SystemException {
+    return getTM().suspend();
+  }
+  
+  public Object getResource(Object arg0) {
+    return getTSR().getResource(arg0);
+  }
+  
+  public boolean getRollbackOnly() {
+    return getTSR().getRollbackOnly();
+  }
+  
+  public Object getTransactionKey() {
+    return getTSR().getTransactionKey();
+  }
+  
+  public int getTransactionStatus() {
+    return getTSR().getTransactionStatus();
+  }
+  
+  public void putResource(Object arg0, Object arg1) {
+    getTSR().putResource(arg0, arg1);
+  }
+  
+  public void registerInterposedSynchronization(Synchronization arg0) {
+    getTSR().registerInterposedSynchronization(arg0);
+  }
+}
+
+

Added: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java?rev=1161653&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java
(added)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java
Thu Aug 25 17:26:19 2011
@@ -0,0 +1,47 @@
+/**
+ *  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.aries.ejb.openejb.extender;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.openejb.AppContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class RunningApplication {
+
+  private final AppContext ctx;
+  private final Collection<ServiceRegistration<?>> regs = 
+    Collections.synchronizedCollection(new ArrayList<ServiceRegistration<?>>());
+  
+  public RunningApplication(AppContext context) {
+    this.ctx = context;
+  }
+
+  public AppContext getCtx() {
+    return ctx;
+  }
+
+  public Collection<ServiceRegistration<?>> getRegs() {
+    return regs;
+  }
+  
+  public void addRegs(Collection<ServiceRegistration<?>> toAdd) {
+    regs.addAll(toAdd);
+  }
+}

Modified: aries/trunk/ejb/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/pom.xml?rev=1161653&r1=1161652&r2=1161653&view=diff
==============================================================================
--- aries/trunk/ejb/pom.xml (original)
+++ aries/trunk/ejb/pom.xml Thu Aug 25 17:26:19 2011
@@ -33,6 +33,8 @@
     <modules>
         <module>ejb-modeller</module>
         <module>ejb-modeller-itest</module>
+        <module>openejb-extender</module>
+        <module>openejb-extender-itest</module>
     </modules>
 
 </project>



Mime
View raw message