<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:bpm="http://www.mulesource.org/schema/mule/bpm/2.2"
    xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
    xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.2"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
       http://www.mulesource.org/schema/mule/bpm/2.2 http://www.mulesource.org/schema/mule/bpm/2.2/mule-bpm.xsd
       http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd
       http://www.mulesource.org/schema/mule/jms/2.2 http://www.mulesource.org/schema/mule/jms/2.2/mule-jms.xsd">

    <bpm:connector name="jBpmConnector" bpms-ref="jbpm" />

    <vm:connector name="syncVm" />

    <vm:connector name="asyncVm" queueEvents="true" />

    <!-- We could use JMS instead of VM to make the example more realistic.
        <jms:activemq-connector name="jmsConnector" />
    -->

    <!-- Customer loan requests to the Loan Broker -->
    <vm:endpoint name="CustomerRequests" path="customer.requests" connector-ref="syncVm" />
    <!-- Requests to the credit agency -->
    <vm:endpoint name="CreditAgency" path="credit.agency" connector-ref="syncVm" />
    <!-- Customer credit profiles from the credit agency -->
    <vm:endpoint name="CreditProfiles" path="credit.profiles" connector-ref="syncVm" />
    <!-- Final loan quote to the customer -->
    <vm:endpoint name="CustomerResponses" path="customer.responses" connector-ref="asyncVm" />
    <!-- Bigger banks handle bigger loans.  -->
    <vm:endpoint name="BigBank" path="big.bank" connector-ref="syncVm" />
    <vm:endpoint name="MediumBank" path="medium.bank" connector-ref="syncVm" />
    <vm:endpoint name="SmallBank" path="small.bank" connector-ref="syncVm" />

    <model name="loan-broker">

        <!-- ***************************************************
            Process Engine
            *************************************************** -->

        <!-- Messages sent to the process engine -->
        <service name="ToBPMS">
            <inbound>
                <!-- Incoming message = CustomerRequest -->
                <inbound-endpoint ref="CustomerRequests" />
                <!-- Incoming message = CreditProfile -->
                <inbound-endpoint ref="CreditProfiles" />
            </inbound>
            <component class="org.mule.example.loanbroker.DefaultLoanBroker" />
            <outbound>
                <filtering-router>
                    <bpm:outbound-endpoint process="LoanBroker" />
                </filtering-router>
            </outbound>
        </service>

        <!-- Messages generated from the process engine -->
        <service name="FromBPMS">
            <inbound>
                <bpm:inbound-endpoint process="LoanBroker" />
            </inbound>
            <component class="org.mule.example.loanbroker.DefaultLoanBroker" />
            <outbound>
                <bpm:outbound-router>
                    <!-- Outgoing message = Customer -->
                    <outbound-endpoint ref="CreditAgency" />

                    <!-- Outgoing message = LoanQuote -->
                    <outbound-endpoint ref="CustomerResponses" />

                    <!-- Outgoing message = LoanQuoteRequest -->
                    <outbound-endpoint ref="BigBank" synchronous="true">
                        <property key="method" value="getLoanQuote"/>
                    </outbound-endpoint>
                    <outbound-endpoint ref="MediumBank" synchronous="true">
                        <property key="method" value="getLoanQuote"/>
                    </outbound-endpoint>
                    <outbound-endpoint ref="SmallBank" synchronous="true">
                        <property key="method" value="getLoanQuote"/>
                    </outbound-endpoint>
                </bpm:outbound-router>
            </outbound>
        </service>


        <!-- ***************************************************
            Services
            *************************************************** -->
        <!-- The credit agency service will get the credit profile for a customer -->
        <service name="ACreditAgency">
            <inbound>
                <inbound-endpoint ref="CreditAgency" />
            </inbound>
            <component class="org.mule.example.loanbroker.credit.DefaultCreditAgency" />
            <outbound>
                <filtering-router>
                    <outbound-endpoint ref="CreditProfiles" />
                </filtering-router>
            </outbound>
        </service>

        <!-- These are mock bank services that represent remote bank loan services -->
        <service name="ABigBank">
            <inbound>
                <inbound-endpoint ref="BigBank" />
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank" />
        </service>
        <service name="AMediumBank">
            <inbound>
                <inbound-endpoint ref="MediumBank" />
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank" />
        </service>
        <service name="ASmallBank">
            <inbound>
                <inbound-endpoint ref="SmallBank" />
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank" />
        </service>
    </model>

    <!-- ***************************************************
         BPMS Configuration
         *************************************************** -->
    <context:property-placeholder location="derby.properties"/>

    <!-- BPMS object for Mule's BPM Connector -->
    <spring:bean id="jbpm" class="org.mule.transport.bpm.jbpm.Jbpm" destroy-method="destroy">
        <spring:property name="jbpmConfiguration">
            <spring:ref local="jbpmConfig" />
        </spring:property>
    </spring:bean>

    <!-- jBPM Configuration -->
    <spring:bean id="jbpmConfig"
        class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
        <spring:property name="sessionFactory">
            <spring:ref local="jbpmSessionFactory" />
        </spring:property>
        <spring:property name="configuration">
            <spring:value>jbpm.cfg.xml</spring:value>
        </spring:property>
        <spring:property name="processDefinitions">
            <spring:list>
                <spring:bean id="loanBroker"
                    class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean">
                    <spring:property name="definitionLocation">
                        <spring:value>loan-broker-process.xml</spring:value>
                    </spring:property>
                </spring:bean>
            </spring:list>
        </spring:property>
        <spring:property name="createSchema">
            <spring:value>false</spring:value>
        </spring:property>
    </spring:bean>


    <!-- JBPM Hibernate SessionFactory -->
    <spring:bean id="jbpmSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <spring:property name="dataSource">
            <spring:ref local="jbpmDataSource" />
        </spring:property>
        <spring:property name="mappingLocations">
            <spring:value>classpath*:/org/jbpm/**/*.hbm.xml</spring:value>
        </spring:property>
        <spring:property name="typeDefinitions">
            <spring:ref local="jbpmTypes" />
        </spring:property>
        <spring:property name="hibernateProperties">
            <spring:props>
                <spring:prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</spring:prop>
                <spring:prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</spring:prop>
                <!-- Create/update the database tables automatically when the JVM starts up -->
                <spring:prop key="hibernate.hbm2ddl.auto">update</spring:prop>
            </spring:props>
        </spring:property>
    </spring:bean>

    <!-- JBPM Datasource -->
    <spring:bean id="jbpmDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <spring:property name="driverClassName">
            <spring:value>org.apache.derby.jdbc.EmbeddedDriver</spring:value>
           </spring:property>
        <spring:property name="url">
            <spring:value>${database.connection}</spring:value>
        </spring:property>
    </spring:bean>

    <!-- JBPM data types -->
    <spring:bean id="jbpmTypes" class="org.springframework.orm.hibernate3.TypeDefinitionBean">
        <spring:property name="typeName">
            <spring:value>string_max</spring:value>
        </spring:property>
        <spring:property name="typeClass">
            <spring:value>org.jbpm.db.hibernate.StringMax</spring:value>
        </spring:property>
    </spring:bean>

</mule>
