Save This Page
Home » openejb-3.1.2-src » org.apache.openejb.spring » [javadoc | source]
    1   /**
    2    *
    3    * Licensed to the Apache Software Foundation (ASF) under one or more
    4    * contributor license agreements.  See the NOTICE file distributed with
    5    * this work for additional information regarding copyright ownership.
    6    * The ASF licenses this file to You under the Apache License, Version 2.0
    7    * (the "License"); you may not use this file except in compliance with
    8    * the License.  You may obtain a copy of the License at
    9    *
   10    *     http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    *  Unless required by applicable law or agreed to in writing, software
   13    *  distributed under the License is distributed on an "AS IS" BASIS,
   14    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15    *  See the License for the specific language governing permissions and
   16    *  limitations under the License.
   17    */
   18   package org.apache.openejb.spring;
   19   
   20   import java.io.Serializable;
   21   import java.util.ArrayList;
   22   import java.util.Arrays;
   23   import java.util.Collection;
   24   import java.util.Date;
   25   import java.util.LinkedHashSet;
   26   import java.util.List;
   27   import java.util.Properties;
   28   import java.util.Set;
   29   import java.util.TreeSet;
   30   import javax.annotation.PostConstruct;
   31   import javax.naming.Context;
   32   import javax.naming.NamingException;
   33   import javax.transaction.TransactionManager;
   34   
   35   import org.apache.openejb.Container;
   36   import org.apache.openejb.DeploymentInfo;
   37   import org.apache.openejb.OpenEJBException;
   38   import org.apache.openejb.assembler.classic.Assembler;
   39   import org.apache.openejb.assembler.classic.ContainerInfo;
   40   import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
   41   import org.apache.openejb.assembler.classic.ResourceInfo;
   42   import org.apache.openejb.assembler.classic.SecurityServiceInfo;
   43   import org.apache.openejb.assembler.classic.ServiceInfo;
   44   import org.apache.openejb.assembler.classic.TransactionServiceInfo;
   45   import org.apache.openejb.assembler.dynamic.PassthroughFactory;
   46   import org.apache.openejb.config.ConfigurationFactory;
   47   import org.apache.openejb.loader.SystemInstance;
   48   import org.apache.openejb.spi.ContainerSystem;
   49   import org.apache.openejb.spi.SecurityService;
   50   import org.apache.openejb.util.LogCategory;
   51   import org.apache.openejb.util.Logger;
   52   import org.apache.openejb.util.OpenEjbVersion;
   53   import org.springframework.beans.BeansException;
   54   import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
   55   import org.springframework.beans.factory.config.BeanPostProcessor;
   56   import org.springframework.context.ApplicationContext;
   57   import org.springframework.context.ApplicationContextAware;
   58   
   59   @Exported
   60   public class OpenEJB implements ApplicationContextAware {
   61       private static Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, "org.apache.openejb.util.resources");
   62   
   63       /**
   64        * Properties added to the OpenEJB SystemInstance on startup.
   65        */
   66       private final Properties properties = new Properties();
   67   
   68       /**
   69        * The TransactionManager to be used by the OpenEJB server, or null for the
   70        * default TransactionManager.
   71        */
   72       private TransactionManager transactionManager;
   73   
   74       /**
   75        * The SecurityService to be used by the OpenEJB server, or null for the
   76        * default SecurityService.
   77        */
   78       private SecurityService securityService;
   79   
   80       /**
   81        * Containers to add to the OpenEJB server.
   82        */
   83       private final Collection<ContainerProvider> containers = new ArrayList<ContainerProvider>();
   84   
   85       /**
   86        * Resources to add to the OpenEJB server.
   87        */
   88       private final Collection<ResourceProvider> resources = new ArrayList<ResourceProvider>();
   89   
   90       /**
   91        * Should the beans in the Spring context be imported into OpenEJB as resources?
   92        */
   93       private boolean importContext = true;
   94   
   95       /**
   96        * Is this bean starting?
   97        */
   98       private boolean starting;
   99   
  100       /**
  101        * While OpenEJB is starting any applications that are deployed are queued up until startup is complete.
  102        */
  103       private final List<AbstractApplication> applicationsToDeploy = new ArrayList<AbstractApplication>();
  104   
  105       /**
  106        * The application context to scan when importing Beans.
  107        */
  108       private ApplicationContext applicationContext;
  109   
  110       /**
  111        * The IDs of the resources we have already imported
  112        */
  113       private final Set<String> importedResourceIds = new TreeSet<String>();
  114   
  115       public ApplicationContext getApplicationContext() {
  116           return applicationContext;
  117       }
  118   
  119       public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  120           this.applicationContext = applicationContext;
  121       }
  122   
  123       public Properties getProperties() {
  124           return properties;
  125       }
  126   
  127       public void setProperties(Properties properties) {
  128           this.properties.clear();
  129           this.properties.putAll(properties);
  130       }
  131   
  132       public TransactionManager getTransactionManager() {
  133           return transactionManager;
  134       }
  135   
  136       public void setTransactionManager(TransactionManager transactionManager) {
  137           this.transactionManager = transactionManager;
  138       }
  139   
  140       public SecurityService getSecurityService() {
  141           return securityService;
  142       }
  143   
  144       public void setSecurityService(SecurityService securityService) {
  145           this.securityService = securityService;
  146       }
  147   
  148       public Collection<ContainerProvider> getContainers() {
  149           return containers;
  150       }
  151   
  152       public void setContainers(Collection<? extends ContainerProvider> containers) {
  153           this.containers.clear();
  154           this.containers.addAll(containers);
  155       }
  156   
  157       public Collection<ResourceProvider> getResources() {
  158           return resources;
  159       }
  160   
  161       public void setResources(Collection<? extends ResourceProvider> resources) {
  162           this.resources.clear();
  163           this.resources.addAll(resources);
  164       }
  165   
  166       public boolean isImportContext() {
  167           return importContext;
  168       }
  169   
  170       public void setImportContext(boolean importContext) {
  171           this.importContext = importContext;
  172       }
  173   
  174       public Context getInitialContext() throws NamingException {
  175           if (!org.apache.openejb.OpenEJB.isInitialized()) {
  176               throw new IllegalStateException("Not started");
  177           }
  178   
  179           Context context = new org.apache.openejb.core.ivm.naming.InitContextFactory().getInitialContext(properties);
  180           return context;
  181       }
  182   
  183       public boolean isStarting() {
  184           return starting;
  185       }
  186   
  187       public boolean isStarted() {
  188           return SystemInstance.get().getComponent(ContainerSystem.class) != null;
  189       }
  190   
  191       @PostConstruct
  192       public void start() throws OpenEJBException {
  193           // Transaction mananager and system instance can only be set once per SystemInstance (one per ClassLoader)
  194           if (isStarted()) {
  195               if (transactionManager != null) {
  196                   throw new OpenEJBException("TransactionManager can not be set because OpenEJB has already been initalized");
  197               }
  198               if (securityService != null) {
  199                   throw new OpenEJBException("SecurityService can not be set because OpenEJB has already been initalized");
  200               }
  201           }
  202   
  203           //
  204           // Is this bean already starting?  This helps avoid anoying spring loop backs.
  205           //
  206           if (starting) {
  207               throw new OpenEJBException("OpenEJB already starting");
  208           }
  209           starting = true;
  210   
  211           //
  212           // System Instance
  213           //
  214           SystemInstance system = SystemInstance.get();
  215           system.getProperties().putAll(properties);
  216   
  217           // do not deploy applications in claspath
  218           system.setProperty("openejb.deployments.classpath", "false");
  219   
  220           // we are in embedded mode
  221           system.setProperty("openejb.embedded", "true");
  222   
  223           //
  224           // Add TransactionManager and SecurityService to OpenEJB
  225           //
  226           ConfigurationFactory configurationFactory = new ConfigurationFactory();
  227           Assembler assembler;
  228           if (isStarted()) {
  229               assembler = SystemInstance.get().getComponent(Assembler.class);
  230           } else {
  231               //
  232               // Startup message
  233               //
  234               OpenEjbVersion versionInfo = OpenEjbVersion.get();
  235   
  236               if (properties.getProperty("openejb.nobanner") == null) {
  237                   System.out.println("Apache OpenEJB " + versionInfo.getVersion() + "    build: " + versionInfo.getDate() + "-" + versionInfo.getTime());
  238                   System.out.println("" + versionInfo.getUrl());
  239               }
  240   
  241               Logger logger2 = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
  242               logger2.info("startup.banner", versionInfo.getUrl(), new Date(), versionInfo.getCopyright(),
  243                       versionInfo.getVersion(), versionInfo.getDate(), versionInfo.getTime());
  244   
  245               logger.info("openejb.home = " + SystemInstance.get().getHome().getDirectory().getAbsolutePath());
  246               logger.info("openejb.base = " + SystemInstance.get().getBase().getDirectory().getAbsolutePath());
  247   
  248               Properties props = new Properties(SystemInstance.get().getProperties());
  249   
  250               if (properties.isEmpty()) {
  251                   logger.debug("startup.noInitializationProperties");
  252               } else {
  253                   props.putAll(properties);
  254               }
  255   
  256               //
  257               // Assembler
  258               //
  259               assembler = new Assembler();
  260               assembler.createProxyFactory(configurationFactory.configureService(ProxyFactoryInfo.class));
  261   
  262               //
  263               // Transaction Manager
  264               //
  265               TransactionManager transactionManager = getTransactionManager();
  266               if (transactionManager == null) {
  267                   transactionManager = getBeanForType(applicationContext, TransactionManager.class);
  268               }
  269               if (transactionManager != null) {
  270                   TransactionServiceInfo info = initPassthrough(new TransactionServiceInfo(), "TransactionManager", transactionManager);
  271                   assembler.createTransactionManager(info);
  272               }
  273   
  274               //
  275               // Security Service
  276               //
  277               SecurityService securityService = getSecurityService();
  278               if (securityService == null) {
  279                   securityService = getBeanForType(applicationContext, SecurityService.class);
  280               }
  281               if (securityService != null) {
  282                   SecurityServiceInfo info = initPassthrough(new SecurityServiceInfo(), "SecurityService", securityService);
  283                   assembler.createSecurityService(info);
  284               }
  285           }
  286   
  287           //
  288           // Resources
  289           //
  290           for (Object resourceProvider : applicationContext.getBeansOfType(ResourceProvider.class).values()) {
  291               resources.add((ResourceProvider) resourceProvider);
  292           }
  293           for (ResourceProvider resourceProvider : getResources()) {
  294               ResourceInfo info = configurationFactory.configureService(resourceProvider.getResourceDefinition(), ResourceInfo.class);
  295               importedResourceIds.add(info.id);
  296               assembler.createResource(info);
  297           }
  298           if (isImportContext() && applicationContext != null) {
  299               for (String beanName : applicationContext.getBeanDefinitionNames()) {
  300                   if (!importedResourceIds.contains(beanName)) {
  301                       Class beanType = applicationContext.getType(beanName);
  302                       Class factoryType = applicationContext.getType("&" + beanName);
  303                       if (isImportableType(beanType, factoryType)) {
  304                           SpringReference factory = new SpringReference(applicationContext, beanName, beanType);
  305   
  306                           ResourceInfo info = initPassthrough(beanName, new ResourceInfo(), "Resource", factory);
  307                           info.types = getTypes(beanType);
  308                           assembler.createResource(info);
  309                       }
  310                   }
  311               }
  312           }
  313   
  314           //
  315           // Containers
  316           //
  317           for (Object containerProvider : applicationContext.getBeansOfType(ContainerProvider.class).values()) {
  318               containers.add((ContainerProvider) containerProvider);
  319           }
  320           for (ContainerProvider containerProvider: getContainers()) {
  321               ContainerInfo info = configurationFactory.createContainerInfo(containerProvider.getContainerDefinition());
  322               assembler.createContainer(info);
  323           }
  324   
  325           //
  326           // Done
  327           //
  328           starting = false;
  329           logger.debug("startup.ready");
  330   
  331           List<AbstractApplication> applicationsToDeploy = new ArrayList<AbstractApplication>(this.applicationsToDeploy);
  332           this.applicationsToDeploy.clear();
  333           for (AbstractApplication application : applicationsToDeploy) {
  334               application.deployApplication();
  335           }
  336       }
  337   
  338       public void deployApplication(AbstractApplication application) throws OpenEJBException {
  339           if (isStarting() || !isStarted()) {
  340               applicationsToDeploy.add(application);
  341           } else {
  342               application.deployApplication();
  343           }
  344       }
  345   
  346       public void printContainerSystem() {
  347           ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
  348           if (logger.isDebugEnabled()) {
  349               //
  350               // Log Containers
  351               //
  352               logger.debug("startup.debugContainers", containerSystem.containers().length);
  353               if (containerSystem.containers().length > 0) {
  354                   logger.debug("startup.debugContainersType");
  355                   for (Container container : containerSystem.containers()) {
  356                       String entry = "   ";
  357                       switch (container.getContainerType()) {
  358                           case BMP_ENTITY:
  359                               entry += "BMP ENTITY  ";
  360                               break;
  361                           case CMP_ENTITY:
  362                               entry += "CMP ENTITY  ";
  363                               break;
  364                           case STATEFUL:
  365                               entry += "STATEFUL    ";
  366                               break;
  367                           case STATELESS:
  368                               entry += "STATELESS   ";
  369                               break;
  370                           case MESSAGE_DRIVEN:
  371                               entry += "MESSAGE     ";
  372                               break;
  373                       }
  374                       entry += container.getContainerID();
  375                       logger.debug("startup.debugEntry", entry);
  376                   }
  377               }
  378   
  379               //
  380               // Log Deployments
  381               //
  382               logger.debug("startup.debugDeployments", containerSystem.deployments().length);
  383               if (containerSystem.deployments().length > 0) {
  384                   logger.debug("startup.debugDeploymentsType");
  385                   for (DeploymentInfo deployment : containerSystem.deployments()) {
  386                       String entry = "   ";
  387                       switch (deployment.getComponentType()) {
  388                           case BMP_ENTITY:
  389                               entry += "BMP_ENTITY  ";
  390                               break;
  391                           case CMP_ENTITY:
  392                               entry += "CMP_ENTITY  ";
  393                               break;
  394                           case STATEFUL:
  395                               entry += "STATEFUL    ";
  396                               break;
  397                           case STATELESS:
  398                               entry += "STATELESS   ";
  399                               break;
  400                           case SINGLETON:
  401                               entry += "SINGLETON   ";
  402                               break;
  403                           case MESSAGE_DRIVEN:
  404                               entry += "MESSAGE     ";
  405                               break;
  406                       }
  407                       entry += deployment.getDeploymentID();
  408                       logger.debug("startup.debugEntry", entry);
  409                   }
  410               }
  411           }
  412       }
  413   
  414       private <T> T getBeanForType(ApplicationContext applicationContext, Class<T> type) throws OpenEJBException {
  415           String[] names = applicationContext.getBeanNamesForType(type);
  416           if (names.length == 0) {
  417               return null;
  418           }
  419           if (names.length > 1) {
  420               throw new OpenEJBException("Multiple " + type.getSimpleName() + " beans in application context: " + Arrays.toString(names));
  421           }
  422   
  423           String name = names[0];
  424           importedResourceIds.add(name);
  425           return (T) applicationContext.getBean(name);
  426       }
  427   
  428       private boolean isImportableType(Class type, Class factoryType) {
  429           return !type.isAnnotationPresent(Exported.class) &&
  430                   !BeanPostProcessor.class.isAssignableFrom(type) &&
  431                   !BeanFactoryPostProcessor.class.isAssignableFrom(type) &&
  432                   (factoryType == null || !factoryType.isAnnotationPresent(Exported.class));
  433       }
  434   
  435       private <T extends ServiceInfo> T initPassthrough(T info, String serviceType, Object instance) {
  436           return initPassthrough("Spring Supplied?" + serviceType, info, serviceType, instance);
  437       }
  438   
  439       private <T extends ServiceInfo> T initPassthrough(String id, T info, String serviceType, Object instance) {
  440           info.id = id;
  441           info.service = serviceType;
  442           info.types = getTypes(instance.getClass());
  443           PassthroughFactory.add(info, instance);
  444           return info;
  445       }
  446   
  447       private List<String> getTypes(Class type) {
  448           LinkedHashSet<String> types = new LinkedHashSet<String>();
  449           addTypes(type, types);
  450           return new ArrayList<String>(types);
  451       }
  452   
  453       private void addTypes(Class clazz, LinkedHashSet<String> types) {
  454           if (clazz == null || Object.class.equals(clazz) || Serializable.class.equals(clazz)) {
  455               return;
  456           }
  457           if (types.add(clazz.getName())) {
  458               addTypes(clazz.getSuperclass(), types);
  459               for (Class intf : clazz.getInterfaces()) {
  460                   addTypes(intf, types);
  461               }
  462           }
  463       }
  464   }

Save This Page
Home » openejb-3.1.2-src » org.apache.openejb.spring » [javadoc | source]