/**
* Created on Feb 21, 2006
*
* $Id: LocalJbpmConfigurationFactoryBean.java,v 1.5 2007/03/01 12:28:40 costin Exp $
* $Revision: 1.5 $
*/
package org.springmodules.workflow.jbpm31;
import java.io.InputStream;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.configuration.ObjectFactory;
import org.jbpm.configuration.ObjectFactoryParser;
import org.jbpm.graph.def.ProcessDefinition;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.core.io.Resource;
import org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean;
/**
* FactoryBean which allows customized creation of JbpmConfiguration objects
* which are binded to the lifecycle of the bean factory container. A
* BeanFactory aware ObjectFactory can be used by the resulting object for
* retrieving beans from the application context, delegating to the default
* implementation for unresolved names. It is possible to use an already defined
* Hibernate SessionFactory by injecting an approapriate HibernateTemplate - if
* defined, the underlying session factory will be used by jBPM Persistence
* Service.
*
* If set to true, createSchema and dropSchema will be executed on factory
* initialization and destruction, using the contextName property which, by
* default, is equivalent with JbpmContext.DEFAULT_JBPM_CONTEXT_NAME.
*
*
* @see org.jbpm.configuration.ObjectFactory
* @author Costin Leau
*
*/
public class LocalJbpmConfigurationFactoryBean implements InitializingBean, DisposableBean, FactoryBean,
BeanFactoryAware, BeanNameAware {
private static final Log logger = LogFactory.getLog(LocalJbpmConfigurationFactoryBean.class);
private JbpmConfiguration jbpmConfiguration;
private ObjectFactory objectFactory;
private Resource configuration;
private boolean createSchema;
private boolean dropSchema;
private boolean hasPersistenceService;
private String contextName = JbpmContext.DEFAULT_JBPM_CONTEXT_NAME;
private Resource[] processDefinitionsResources;
private ProcessDefinition[] processDefinitions;
private SessionFactory sessionFactory;
/**
* FactoryLocator
*/
private JbpmFactoryLocator factoryLocator = new JbpmFactoryLocator();
private BeanFactoryReference reference;
private String factoryKey = JbpmFactoryLocator.class.getName();
/**
* @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
*/
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
factoryLocator.setBeanFactory(beanFactory);
reference = factoryLocator.useBeanFactory(factoryKey);
}
/**
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
*/
public void setBeanName(String name) {
factoryLocator.setBeanName(name);
this.factoryKey = name;
}
/**
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
// trigger locator cleanup
reference.release();
if (dropSchema && hasPersistenceService) {
logger.info("dropping schema");
jbpmConfiguration.dropSchema(contextName);
}
}
/**
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
if (configuration == null && objectFactory == null)
throw new IllegalArgumentException("configuration or objectFactory property need to be not null");
ObjectFactory jbpmObjectFactory;
// 1. create the configuration from the file
if (configuration != null) {
logger.info("creating JbpmConfiguration from resource " + configuration.getDescription());
InputStream stream = configuration.getInputStream();
jbpmObjectFactory = ObjectFactoryParser.parseInputStream(stream);
stream.close();
}
else
jbpmObjectFactory = objectFactory;
jbpmConfiguration = new JbpmConfiguration(jbpmObjectFactory);
JbpmContext context = null;
try {
// 2. inject the HB session factory if it is the case
context = jbpmConfiguration.createJbpmContext(contextName);
if (sessionFactory != null) {
logger.info("using given Hibernate session factory");
context.setSessionFactory(sessionFactory);
}
// 3. execute persistence operations
hasPersistenceService = JbpmUtils.hasPersistenceService(jbpmConfiguration, contextName);
if (hasPersistenceService) {
logger.info("persistence service available...");
if (createSchema) {
logger.info("creating schema");
jbpmConfiguration.createSchema(contextName);
}
if (processDefinitions != null || processDefinitionsResources != null) {
if (processDefinitions != null) {
String toString = Arrays.asList(processDefinitions).toString();
logger.info("deploying process definitions:" + toString);
// deploy the ProcessDefinitions
for (int i = 0; i < processDefinitions.length; i++) {
context.deployProcessDefinition(processDefinitions[i]);
}
}
if (processDefinitionsResources != null) {
ProcessDefinitionFactoryBean factory = new ProcessDefinitionFactoryBean();
String toString = Arrays.asList(processDefinitionsResources).toString();
logger.info("deploying process definitions (from resources):" + toString);
for (int i = 0; i < processDefinitionsResources.length; i++) {
factory.setDefinitionLocation(processDefinitionsResources[i]);
factory.afterPropertiesSet();
context.deployProcessDefinition((ProcessDefinition) factory.getObject());
}
}
}
}
else {
logger
.info("persistence unavailable not available - schema create/drop and process definition deployment disabled");
}
}
finally {
if (context != null)
context.close();
}
}
/**
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
public Object getObject() throws Exception {
return jbpmConfiguration;
}
/**
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class getObjectType() {
return JbpmConfiguration.class;
}
/**
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
}
/**
* @return Returns the configuration.
*/
public Resource getConfiguration() {
return configuration;
}
/**
* @param configuration The configuration to set.
*/
public void setConfiguration(Resource configuration) {
this.configuration = configuration;
}
/**
* @return Returns the objectFactory.
*/
public ObjectFactory getObjectFactory() {
return objectFactory;
}
/**
* @param objectFactory The objectFactory to set.
*/
public void setObjectFactory(ObjectFactory objectFactory) {
this.objectFactory = objectFactory;
}
/**
* @return Returns the contextName.
*/
public String getContextName() {
return contextName;
}
/**
* @param contextName The contextName to set.
*/
public void setContextName(String contextName) {
this.contextName = contextName;
}
/**
* @return Returns the createSchema.
*/
public boolean isCreateSchema() {
return createSchema;
}
/**
* @param createSchema The createSchema to set.
*/
public void setCreateSchema(boolean createSchema) {
this.createSchema = createSchema;
}
/**
* @return Returns the dropSchema.
*/
public boolean isDropSchema() {
return dropSchema;
}
/**
* @param dropSchema The dropSchema to set.
*/
public void setDropSchema(boolean dropSchema) {
this.dropSchema = dropSchema;
}
/**
* @return Returns the processDefinitions.
*/
public ProcessDefinition[] getProcessDefinitions() {
return processDefinitions;
}
/**
* @param processDefinitions The processDefinitions to set.
*/
public void setProcessDefinitions(ProcessDefinition[] processDefinitions) {
this.processDefinitions = processDefinitions;
}
/**
* @return Returns the sessionFactory.
*/
public SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* @param sessionFactory The sessionFactory to set.
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* @return Returns the processDefinitionsResources.
*/
public Resource[] getProcessDefinitionsResources() {
return processDefinitionsResources;
}
/**
* Used for loading the process definition from resources when the
* configuration is created. This method is an alternative to
* ProcesssDefinitionFactoryBean since when dealing with sub processes
* (inside the definitions), jBPM requires a JbpmContext to be active on its
* internal static stack.
*
* @param processDefinitionsResources The processDefinitionsResources to
* set.
*/
public void setProcessDefinitionsResources(Resource[] processDefinitionsResources) {
this.processDefinitionsResources = processDefinitionsResources;
}
/**
* @return Returns the factoryLocator.
*/
protected JbpmFactoryLocator getFactoryLocator() {
return factoryLocator;
}
}