/** * 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.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.naming.Context; import javax.naming.NamingException; import javax.persistence.EntityManagerFactory; import org.apache.aries.jpa.container.PersistenceUnitConstants; import org.apache.aries.jpa.container.context.PersistenceContextProvider; import org.apache.aries.util.AriesFrameworkUtil; import org.apache.aries.util.manifest.ManifestHeaderProcessor; import org.apache.aries.util.manifest.ManifestHeaderProcessor.NameValuePair; import org.apache.openejb.AppContext; import org.apache.openejb.BeanContext; import org.apache.openejb.ContainerType; import org.apache.openejb.assembler.classic.EnterpriseBeanInfo; import org.apache.openejb.assembler.classic.PersistenceContextReferenceInfo; import org.apache.openejb.assembler.classic.PersistenceUnitReferenceInfo; import org.apache.openejb.assembler.classic.ProxyInterfaceResolver; import org.apache.openejb.assembler.classic.ReferenceLocationInfo; import org.apache.openejb.jee.EnterpriseBean; import org.apache.openejb.persistence.JtaEntityManager; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; public class RunningApplication implements ServiceTrackerCustomizer { private static final String NONE = "NONE"; private final AppContext ctx; private final Bundle bundle; private final Collection<ServiceRegistration<?>> regs = new ArrayList<ServiceRegistration<?>>(); private ServiceTracker tracker; private final ConcurrentMap<String, ConcurrentMap<Context, PersistenceUnitReferenceInfo>> unitRegistrations = new ConcurrentHashMap<String, ConcurrentMap<Context, PersistenceUnitReferenceInfo>>(); private final ConcurrentMap<String, ConcurrentMap<Context, PersistenceContextReferenceInfo>> contextRegistrations = new ConcurrentHashMap<String, ConcurrentMap<Context, PersistenceContextReferenceInfo>>(); public RunningApplication(AppContext context, Bundle bundle, List<EnterpriseBeanInfo> enterpriseBeans) { this.ctx = context; this.bundle = bundle; for(EnterpriseBeanInfo bean : enterpriseBeans) { for(PersistenceUnitReferenceInfo pui : bean.jndiEnc.persistenceUnitRefs) { ConcurrentMap<Context, PersistenceUnitReferenceInfo> map = unitRegistrations. get(pui.persistenceUnitName); if(map == null) { map = new ConcurrentHashMap<Context, PersistenceUnitReferenceInfo>(); unitRegistrations.put(pui.persistenceUnitName, map); } for(BeanContext eb : ctx.getBeanContexts()) { if(eb.getEjbName().equals(bean.ejbName)){ map.put(eb.getJndiContext(), pui); continue; } } } for(PersistenceContextReferenceInfo pci : bean.jndiEnc.persistenceContextRefs) { ConcurrentMap<Context, PersistenceContextReferenceInfo> map = contextRegistrations. get(pci.persistenceUnitName); if(map == null) { map = new ConcurrentHashMap<Context, PersistenceContextReferenceInfo>(); contextRegistrations.put(pci.persistenceUnitName, map); } for(BeanContext eb : ctx.getBeanContexts()) { if(eb.getEjbName().equals(bean.ejbName)){ map.put(eb.getJndiContext(), pci); continue; } } } } } public AppContext getCtx() { return ctx; } public void init() { tracker = new ServiceTracker(bundle.getBundleContext(), EntityManagerFactory.class.getName(), this); tracker.open(); registerEJBs(); } public void destroy() { tracker.close(); for(ServiceRegistration<?> reg : regs) { AriesFrameworkUtil.safeUnregisterService(reg); } } private void registerEJBs() { Collection<String> names = new HashSet<String>(); Dictionary<String, String> d = bundle.getHeaders(); String valueOfExportEJBHeader = d.get("Export-EJB"); if((valueOfExportEJBHeader == null)){ return; } if(names.contains(NONE)){ return; } List<NameValuePair> contentsOfExportEJBHeader = ManifestHeaderProcessor.parseExportString(valueOfExportEJBHeader); for(NameValuePair nvp:contentsOfExportEJBHeader){ names.add(nvp.getName()); } if(valueOfExportEJBHeader.trim().equals("")){ names = new AllCollection<String>(); } //Register our session beans for (BeanContext beanContext : ctx.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)); } } } private String getCasedType(ContainerType type) { String s = type.toString().substring(0,1).toUpperCase(); s += type.toString().substring(1).toLowerCase(); return s; } public Object addingService(ServiceReference reference) { if(isTrue(reference, PersistenceUnitConstants.CONTAINER_MANAGED_PERSISTENCE_UNIT) && !!!isTrue(reference, PersistenceContextProvider.PROXY_FACTORY_EMF_ATTRIBUTE)) { Map<Context, PersistenceUnitReferenceInfo> pUnitRefs = unitRegistrations. get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME)); Map<Context, PersistenceContextReferenceInfo> pCtxRefs = contextRegistrations. get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME)); if(pUnitRefs == null) { pUnitRefs = new HashMap<Context, PersistenceUnitReferenceInfo>(); } if(pCtxRefs == null) { pCtxRefs = new HashMap<Context, PersistenceContextReferenceInfo>(); } if(pUnitRefs.size() > 0 || pCtxRefs.size() > 0) { EntityManagerFactory emf = (EntityManagerFactory)bundle.getBundleContext().getService(reference); for(Entry<Context, PersistenceUnitReferenceInfo> e : pUnitRefs.entrySet()) { try { e.getKey().bind(e.getValue().referenceName, emf); } catch (NamingException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } } for(Entry<Context, PersistenceContextReferenceInfo> e : pCtxRefs.entrySet()) { PersistenceContextReferenceInfo pci = e.getValue(); try { e.getKey().bind(pci.referenceName, new JtaEntityManager((String)reference.getProperty( PersistenceUnitConstants.OSGI_UNIT_NAME), AriesPersistenceContextIntegration.get(), emf, pci.properties, pci.extended)); } catch (NamingException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } } return emf; } } return null; } private boolean isTrue(ServiceReference reference, String key) { return Boolean.parseBoolean(String.valueOf(reference.getProperty(key))); } public void modifiedService(ServiceReference reference, Object service) { //No op } public void removedService(ServiceReference reference, Object service) { Map<Context, PersistenceUnitReferenceInfo> pUnitRefs = unitRegistrations. get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME)); Map<Context, PersistenceContextReferenceInfo> pCtxRefs = contextRegistrations. get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME)); if(pUnitRefs == null) { pUnitRefs = new HashMap<Context, PersistenceUnitReferenceInfo>(); } if(pCtxRefs == null) { pCtxRefs = new HashMap<Context, PersistenceContextReferenceInfo>(); } if(pUnitRefs.size() > 0 || pCtxRefs.size() > 0) { for(Entry<Context, PersistenceUnitReferenceInfo> e : pUnitRefs.entrySet()) { try { e.getKey().unbind(e.getValue().referenceName); } catch (NamingException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } } for(Entry<Context, PersistenceContextReferenceInfo> e : pCtxRefs.entrySet()) { PersistenceContextReferenceInfo pci = e.getValue(); try { e.getKey().unbind(pci.referenceName); } catch (NamingException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } } } } }