[jboss-cvs] jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring ...

Ales Justin ales.justin at genera-lynx.com
Fri Feb 9 12:37:18 EST 2007


  User: alesj   
  Date: 07/02/09 12:37:18

  Added:       examples/spring/src/org/jboss/seam/ioc/spring      
                        SpringComponent.java SeamScope.java
                        SeamNamespaceHandler.java spring.xsd
                        SeamPostProcessor.java SeamFactoryBean.java
  Log:
  Added youngm's Spring code + my initial MC code (need to write scopes first in MC in order to fully support integration with Seam).
  
  Revision  Changes    Path
  1.1      date: 2007/02/09 17:37:18;  author: alesj;  state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SpringComponent.java
  
  Index: SpringComponent.java
  ===================================================================
  package org.jboss.seam.ioc.spring;
  
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.ioc.IoCComponent;
  import org.springframework.beans.factory.BeanFactory;
  import org.springframework.beans.factory.ObjectFactory;
  
  /**
   * An extension of Component that allows spring to provide the base instance for
   * a seam component.
   *
   * @author youngm
   */
  public class SpringComponent extends IoCComponent
  {
     public static final String DESTRUCTION_CALLBACK_NAME_PREFIX = IoCComponent.class.getName()
           + ".DESTRUCTION_CALLBACK.";
  
     private BeanFactory beanfactory;
  
     private static final ThreadLocal<ObjectFactory> factoryBean = new ThreadLocal<ObjectFactory>();
  
     /**
      * Creates a Spring Seam Component given a beanFactory.
      *
      * @param clazz   class
      * @param name    component name
      * @param scope   component scope
      * @param factory factory
      */
     public SpringComponent(Class clazz, String name, ScopeType scope, BeanFactory factory)
     {
        super(clazz, name, scope);
        this.beanfactory = factory;
     }
  
     public static ObjectFactory getFactoryBean()
     {
        return factoryBean.get();
     }
  
     public static void setFactoryBean(ObjectFactory bean)
     {
        factoryBean.set(bean);
     }
  
     protected String getIoCName()
     {
        return "Spring";
     }
  
     protected Object instantiateIoCBean() throws Exception
     {
        ObjectFactory objectFactory = getFactoryBean();
        if (objectFactory == null)
        {
           return beanfactory.getBean(getName());
        }
        setFactoryBean(null);
        return objectFactory.getObject();
     }
  
     /**
      * Calls the spring destroy callback when seam destroys the component
      *
      * @see org.jboss.seam.Component#callDestroyMethod(Object)
      */
     @Override
     public void callDestroyMethod(Object instance)
     {
        super.callDestroyMethod(instance);
        // Cannot call the callback on a STATELESS bean
        if (getScope() != ScopeType.STATELESS)
        {
           Runnable callback = (Runnable)getScope().getContext().get(DESTRUCTION_CALLBACK_NAME_PREFIX + getName());
           if (callback != null)
           {
              callback.run();
           }
        }
     }
  
     /**
      * Registers a destruction callback with this bean.
      *
      * @param name    bean name
      * @param destroy the destroy to set
      */
     public void registerDestroyCallback(String name, Runnable destroy)
     {
        // Not sure yet how to register a stateless bean's Destruction callback.
        if (getScope() != ScopeType.STATELESS)
        {
           getScope().getContext().set(DESTRUCTION_CALLBACK_NAME_PREFIX + name, destroy);
  		}
  	}
  
  }
  
  
  
  1.1      date: 2007/02/09 17:37:18;  author: alesj;  state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamScope.java
  
  Index: SeamScope.java
  ===================================================================
  package org.jboss.seam.ioc.spring;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.Events;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.springframework.beans.factory.ObjectFactory;
  import org.springframework.beans.factory.config.Scope;
  
  /**
   * Allows for the creation of seam scoped component in spring. Seam scopes are
   * automatically made available if the SeamPostProcessor is declared in the
   * current BeanFactory.
   *
   * @author youngm
   * @see SeamPostProcessor
   */
  public class SeamScope implements Scope
  {
     private static final LogProvider log = Logging.getLogProvider(SeamScope.class);
  
     private ScopeType scope;
  
     public SeamScope(ScopeType scope)
     {
        this.scope = scope;
     }
  
     /**
      * Gets an instance of a Seam component providing the current ObjectFactory
      * if needed.
      *
      * @see org.springframework.beans.factory.config.Scope#get(java.lang.String,
      *org.springframework.beans.factory.ObjectFactory)
      */
     public Object get(String name, ObjectFactory objectFactory)
     {
        try
        {
           SpringComponent.setFactoryBean(objectFactory);
           return Component.getInstance(name, scope);
        }
        finally
        {
           SpringComponent.setFactoryBean(null);
        }
     }
  
     /**
      * Not used yet.
      *
      * @see org.springframework.beans.factory.config.Scope#getConversationId()
      */
     public String getConversationId()
     {
        return null;
     }
  
     /**
      * @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String,
      *java.lang.Runnable)
      */
     public void registerDestructionCallback(String name, Runnable callback)
     {
        ((SpringComponent)Component.forName(name)).registerDestroyCallback(name, callback);
     }
  
     /**
      * On remove destroys the seam component.
      *
      * @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
      */
     public Object remove(String name)
     {
        log.debug("destroying: " + name);
        Component component = Component.forName(name);
        Object bean = scope.getContext().get(name);
        if (component != null)
        {
           if (bean != null) // in a portal environment, this is possible
           {
              if (Events.exists())
                 Events.instance().raiseEvent("org.jboss.seam.preDestroy." + name);
              try
              {
                 if (component.hasDestroyMethod())
                 {
                    component.callComponentMethod(bean, component.getDestroyMethod());
                 }
              }
              catch (Exception e)
              {
                 log.warn("Could not destroy component: " + name, e);
              }
           }
        }
        Contexts.getEventContext().remove(name);
  		return bean;
  	}
  
  }
  
  
  
  1.1      date: 2007/02/09 17:37:18;  author: alesj;  state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamNamespaceHandler.java
  
  Index: SeamNamespaceHandler.java
  ===================================================================
  package org.jboss.seam.ioc.spring;
  
  import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
  import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
  import org.w3c.dom.Element;
  
  /**
   * @author youngm
   */
  public class SeamNamespaceHandler extends NamespaceHandlerSupport
  {
  
     /**
      * @see org.springframework.beans.factory.xml.NamespaceHandler#init()
      */
     public void init()
     {
        registerBeanDefinitionParser("instance", new SeamBeanBeanDefinitionParser());
     }
  
     private static class SeamBeanBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser
     {
  
        protected Class getBeanClass(Element element)
        {
           return SeamFactoryBean.class;
        }
  
  /*		protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
  			String id = super.resolveId(element, definition, parserContext);
  			return id;
  		}*/
     }
  
  }
  
  
  
  1.1      date: 2007/02/09 17:37:18;  author: alesj;  state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/spring.xsd
  
  Index: spring.xsd
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  
  <xsd:schema xmlns="http://jboss.com/products/seam/spring" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:tool="http://www.springframework.org/schema/tool"
              targetNamespace="http://jboss.com/products/seam/spring"
              elementFormDefault="qualified" attributeFormDefault="unqualified">
  
     <xsd:import namespace="http://www.springframework.org/schema/tool"
                 schemaLocation="http://www.springframework.org/schema/tool/spring-tool-2.0.xsd"/>
  
     <xsd:element name="instance">
        <xsd:annotation>
           <xsd:documentation>
              Obtains an instance of a seam
           </xsd:documentation>
  
           <xsd:appinfo>
              <tool:annotation>
                 <tool:exports/>
              </tool:annotation>
           </xsd:appinfo>
        </xsd:annotation>
        <xsd:complexType>
           <xsd:attribute name="id" type="xsd:ID"/>
           <xsd:attribute name="name" type="xsd:string" use="required"/>
           <xsd:attribute name="scope" use="optional">
              <xsd:simpleType>
                 <xsd:restriction base="xsd:string">
                    <xsd:enumeration value="STATELESS"/>
                    <xsd:enumeration value="METHOD"/>
                    <xsd:enumeration value="EVENT"/>
                    <xsd:enumeration value="PAGE"/>
                    <xsd:enumeration value="CONVERSATION"/>
                    <xsd:enumeration value="SESSION"/>
                    <xsd:enumeration value="APPLICATION"/>
                    <xsd:enumeration value="BUSINESS_PROCESS"/>
                 </xsd:restriction>
              </xsd:simpleType>
           </xsd:attribute>
           <xsd:attribute name="create" type="xsd:boolean" use="optional"/>
        </xsd:complexType>
     </xsd:element>
  </xsd:schema>
  
  
  1.1      date: 2007/02/09 17:37:18;  author: alesj;  state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamPostProcessor.java
  
  Index: SeamPostProcessor.java
  ===================================================================
  package org.jboss.seam.ioc.spring;
  
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.contexts.Context;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.contexts.Lifecycle;
  import org.jboss.seam.init.Initialization;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.springframework.beans.BeansException;
  import org.springframework.beans.FatalBeanException;
  import org.springframework.beans.factory.InitializingBean;
  import org.springframework.beans.factory.config.BeanDefinition;
  import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
  import org.springframework.util.ClassUtils;
  
  /**
   * Post processor that makes all of the seam scopes available in spring and
   * takes all of the beans with those scopes and creates Seam Components out of
   * them.
   * <p/>
   * To use simply define this bean in one of your context files.
   *
   * @author youngm
   */
  public class SeamPostProcessor implements BeanFactoryPostProcessor, InitializingBean
  {
     private static final LogProvider log = Logging.getLogProvider(SeamPostProcessor.class);
  
     /**
      * Default seam scope prefix.
      */
     public static final String DEFAULT_SCOPE_PREFIX = "seam.";
  
     private String scopePrefix;
  
     /**
      * Null is not a valid scopePrefix so make it the default is used if null or empty.
      *
      * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
      */
     public void afterPropertiesSet() throws Exception
     {
        if (scopePrefix == null || "".equals(scopePrefix))
        {
           scopePrefix = DEFAULT_SCOPE_PREFIX;
        }
     }
  
     /**
      * Add all of the seam scopes to this beanFactory.
      *
      * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
      */
     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
     {
  
        for (ScopeType scope : ScopeType.values())
        {
           // Don't create a scope for UnSpecified
           if (scope != ScopeType.UNSPECIFIED)
           {
              beanFactory.registerScope(scopePrefix + scope.name(), new SeamScope(scope));
           }
        }
        // Create a mock application context if not available.
        boolean unmockApplication = false;
        if (!Contexts.isApplicationContextActive())
        {
           Lifecycle.mockApplication();
           unmockApplication = true;
        }
        try
        {
           Context applicationContext = Contexts.getApplicationContext();
           // Iterate through all the beans in the factory
           for (String beanName : beanFactory.getBeanDefinitionNames())
           {
              BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
              Class beanClass;
              ScopeType scope;
              if (definition.getScope().startsWith(scopePrefix))
              {
                 scope = ScopeType.valueOf(definition.getScope().replaceFirst(scopePrefix, "").toUpperCase());
              }
              else
              {
                 if (log.isDebugEnabled())
                 {
                    log.debug("No scope could be derived for bean with name: " + beanName);
                 }
                 continue;
              }
              if (scope == ScopeType.UNSPECIFIED)
              {
                 if (log.isDebugEnabled())
                 {
                    log.debug("Discarding bean with scope UNSPECIFIED.  Spring will throw an appropriate error later: " + beanName);
                 }
                 continue;
              }
              // Cannot be a seam component without a class maybe later
              if (definition.getBeanClassName() == null)
              {
                 throw new FatalBeanException("Seam scoped bean must explicitly define a class.");
              }
              else
              {
                 try
                 {
                    beanClass = ClassUtils.forName(definition.getBeanClassName());
                 }
                 catch (ClassNotFoundException e)
                 {
                    throw new FatalBeanException("Error", e);
                 }
              }
              // Add the component to seam
              applicationContext.set(beanName + Initialization.COMPONENT_SUFFIX, new SpringComponent(beanClass, beanName, scope, beanFactory));
           }
        }
        finally
        {
           if (unmockApplication)
           {
              Lifecycle.unmockApplication();
           }
        }
     }
  
     /**
      * @param scopePrefix the prefix to use to identify seam scopes for spring
      *                    beans
      */
     public void setScopePrefix(String scopePrefix)
     {
        this.scopePrefix = scopePrefix;
     }
  }
  
  
  
  1.1      date: 2007/02/09 17:37:18;  author: alesj;  state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamFactoryBean.java
  
  Index: SeamFactoryBean.java
  ===================================================================
  package org.jboss.seam.ioc.spring;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.springframework.beans.factory.InitializingBean;
  import org.springframework.beans.factory.config.AbstractFactoryBean;
  
  /**
   * Provides an instance of a Seam Component in the current context given the name.
   *
   * @author youngm
   */
  public class SeamFactoryBean extends AbstractFactoryBean implements InitializingBean
  {
  
     public SeamFactoryBean()
     {
        setSingleton(false);
     }
  
     private ScopeType scope;
     private String name;
     private Boolean create;
  
     /**
      * Ensure name is not null
      *
      * @see org.springframework.beans.factory.config.AbstractFactoryBean#afterPropertiesSet()
      */
     @Override
     public void afterPropertiesSet() throws Exception
     {
        if (name == null)
        {
           throw new IllegalArgumentException("name must not be null");
        }
        super.afterPropertiesSet();
     }
  
     /**
      * Return the current instance of a Seam component given the current context.
      *
      * @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
      */
     @Override
     protected Object createInstance() throws Exception
     {
        if (scope == null && create == null)
        {
           return Component.getInstance(name);
        }
        else if (scope == null)
        {
           return Component.getInstance(name, create);
        }
        else if (create == null)
        {
           return Component.getInstance(name, scope);
        }
        else
        {
           return Component.getInstance(name, scope, create);
        }
     }
  
     /**
      * Return the type of the component if it is available.
      *
      * @see org.springframework.beans.factory.config.AbstractFactoryBean#getObjectType()
      */
     @Override
     public Class getObjectType()
     {
        Component component = Component.forName(name);
        if (component == null)
        {
           return null;
        }
        return component.getBeanClass();
     }
  
     /**
      * The seam component name
      *
      * @param name the name to set
      */
     public void setName(String name)
     {
        this.name = name;
     }
  
     /**
      * The seam component scope (optional)
      *
      * @param scope the scope to set
      */
     public void setScope(ScopeType scope)
     {
        this.scope = scope;
     }
  
     /**
      * Weather to create an instance of the component if one doesn't already exist in this context.
      *
      * @param create the create to set
      */
     public void setCreate(Boolean create) {
  		this.create = create;
  	}
  }
  
  
  



More information about the jboss-cvs-commits mailing list