<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="eventRaisingActivitiProcessListener" class="com.armedia.acm.activiti.AcmProcessEventHandler">
        <property name="runtimeService" ref="activitiRuntimeService"/>
        <property name="historyService" ref="activitiHistoryService"/>
    </bean>

    <bean id="eventRaisingActivitiTaskListener" class="com.armedia.acm.activiti.AcmUserTaskEventHandler">
        <property name="runtimeService" ref="activitiRuntimeService"/>
    </bean>

    <bean id="acmActivitiListener_processStart" class="com.armedia.acm.activiti.AcmActivitiListener">
        <property name="event" value="start"/>
        <property name="implementationType" value="expression"/>
        <property name="implementation" value="eventRaisingActivitiProcessListener.handleProcessEvent(execution.eventName, execution)"/>
    </bean>
    <bean id="acmActivitiListener_processEnd" class="com.armedia.acm.activiti.AcmActivitiListener">
        <property name="event" value="end"/>
        <property name="implementationType" value="expression"/>
        <property name="implementation" value="eventRaisingActivitiProcessListener.handleProcessEvent(execution.eventName, execution)"/>
    </bean>

    <bean id="acmActivitiListener_taskCreate" class="com.armedia.acm.activiti.AcmActivitiListener">
        <property name="event" value="create"/>
        <property name="implementationType" value="expression"/>
        <property name="implementation" value="eventRaisingActivitiTaskListener.handleTaskEvent(task.eventName, task)"/>
    </bean>

    <bean id="acmActivitiListener_taskSave" class="com.armedia.acm.activiti.AcmActivitiListener">
        <property name="event" value="save"/>
        <property name="implementationType" value="expression"/>
        <property name="implementation" value="eventRaisingActivitiTaskListener.handleTaskEvent(task.eventName, task)"/>
    </bean>

    <bean id="acmActivitiListener_taskAssignment" class="com.armedia.acm.activiti.AcmActivitiListener">
        <property name="event" value="assignment"/>
        <property name="implementationType" value="expression"/>
        <property name="implementation" value="eventRaisingActivitiTaskListener.handleTaskEvent(task.eventName, task)"/>
    </bean>

    <bean id="acmActivitiListener_taskComplete" class="com.armedia.acm.activiti.AcmActivitiListener">
        <property name="event" value="complete"/>
        <property name="implementationType" value="expression"/>
        <property name="implementation" value="eventRaisingActivitiTaskListener.handleTaskEvent(task.eventName, task)"/>
    </bean>

    <bean id="acmActivitiListener_taskDelete" class="com.armedia.acm.activiti.AcmActivitiListener">
        <property name="event" value="delete"/>
        <property name="implementationType" value="expression"/>
        <property name="implementation" value="eventRaisingActivitiTaskListener.handleTaskEvent(task.eventName, task)"/>
    </bean>

    <bean id="acmActivitiProcessHandler" class="com.armedia.acm.activiti.ActivitiProcessParseHandler">
        <property name="listenersToAdd">
            <list>
                <ref bean="acmActivitiListener_processStart"/>
                <ref bean="acmActivitiListener_processEnd"/>
            </list>
        </property>
    </bean>

    <bean id="acmActivitiUserTaskHandler" class="com.armedia.acm.activiti.ActivitiUserTaskParseHandler">
        <property name="listenersToAdd">
            <list>
                <ref bean="acmActivitiListener_taskCreate"/>
                <ref bean="acmActivitiListener_taskAssignment"/>
                <ref bean="acmActivitiListener_taskComplete"/>
                <ref bean="acmActivitiListener_taskDelete"/>
                <ref bean="acmActivitiListener_taskSave"/>
            </list>
        </property>
    </bean>

    <bean id="commandConfigFactory" class="org.activiti.engine.impl.interceptor.CommandConfig"/>

    <!-- this bean will tell Activiti to run schema (i.e., DDL) commands within a transaction -->
    <bean id="schemaCommandConfig" factory-bean="commandConfigFactory" factory-method="transactionRequired"/>

    <bean id="acmActivitiEventListener" class="com.armedia.acm.activiti.AcmActivitiEventBridge"/>
    <bean id="acmActivitiEntityEventListener" class="com.armedia.acm.activiti.AcmActivitiEntityEventBridge"/>

    <bean id="activitiTaskScheduler" class="com.armedia.acm.activiti.services.ActivitiTaskScheduler"/>
    <bean id="activitiJobExecutor" class="org.activiti.spring.SpringJobExecutor">
        <property name="taskExecutor" ref="activitiTaskScheduler"/>
    </bean>

    <bean id="activityClassPathBpmnDeployer" class="com.armedia.acm.activiti.services.ActivityClassPathBpmnDeployer">
        <property name="acmBpmnService" ref="processDefinitionManagementService"/>
        <property name="resourcePattern" ref="activitiResourceExpression"/>
        <property name="resolver" ref="activitiPathMatchingResolver"/>
    </bean>

    <bean id="activitiProcessEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration" depends-on="liquibase">
        <property name="dataSource" ref="acmDataSource"/>
        <property name="transactionManager" ref="transactionManager"/>
        <property name="databaseSchemaUpdate" value="true"/>
        <property name="schemaCommandConfig" ref="schemaCommandConfig"/>
        <property name="transactionsExternallyManaged" value="true"/>
        <property name="databaseType" value="#{dataSourceConfig.activitiDbType}"/>
        <property name="preBpmnParseHandlers">
            <list>
                <ref bean="acmActivitiProcessHandler"/>
                <ref bean="acmActivitiUserTaskHandler"/>
            </list>
        </property>
        <property name="eventListeners">
            <list>
                <ref bean="acmActivitiEventListener"/>
                <ref bean="acmActivitiEntityEventListener"/>
            </list>
        </property>
        <property name="jobExecutorActivate" value="#{activitiConfig.jobExecutorActivate}"/>
        <property name="jobExecutor" ref="activitiJobExecutor"/>
    </bean>

    <bean id="activitiProcessEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="activitiProcessEngineConfiguration"/>
    </bean>

    <bean id="activitiRepositoryService" factory-bean="activitiProcessEngine" factory-method="getRepositoryService"/>
    <bean id="activitiRuntimeService" factory-bean="activitiProcessEngine" factory-method="getRuntimeService"/>
    <bean id="activitiTaskService" factory-bean="activitiProcessEngine" factory-method="getTaskService"/>
    <bean id="activitiHistoryService" factory-bean="activitiProcessEngine" factory-method="getHistoryService"/>
    <bean id="activitiManagementService" factory-bean="activitiProcessEngine" factory-method="getManagementService"/>

    <bean id="activitiResourceExpression" class="java.lang.String">
        <constructor-arg value="#{activitiConfig.activitiWorkflowFilePattern}"/>
    </bean>

    <bean id="activitiPathMatchingResolver" class="org.springframework.core.io.support.PathMatchingResourcePatternResolver"/>

    <bean id="processDefinitionManagementService" class="com.armedia.acm.activiti.services.AcmBpmnServiceImpl">
        <property name="activitiRepositoryService" ref="activitiRepositoryService"/>
        <property name="acmBpmnDao" ref="acmProcessDefinitionDao"/>
        <property name="activitiRuntimeService" ref="activitiRuntimeService"/>
    </bean>

    <bean id="acmProcessDefinitionDao" class="com.armedia.acm.activiti.services.dao.AcmBpmnDao"/>

    <bean id="activitiConfig" class="com.armedia.acm.activiti.model.ActivitiConfig" scope="refresh">
        <aop:scoped-proxy/>
    </bean>
</beans>