<?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:jpa="http://www.springframework.org/schema/integration/jpa"
	   xmlns:util="http://www.springframework.org/schema/util"
	   xmlns:int="http://www.springframework.org/schema/integration"
	   xmlns:sd-jpa="http://www.springframework.org/schema/data/jpa"
	   xsi:schemaLocation=
			   "http://www.springframework.org/schema/beans          https://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/integration     https://www.springframework.org/schema/integration/spring-integration.xsd
	http://www.springframework.org/schema/integration/jpa https://www.springframework.org/schema/integration/jpa/spring-integration-jpa.xsd
	http://www.springframework.org/schema/data/jpa        https://www.springframework.org/schema/data/jpa/spring-jpa.xsd
	http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd
	http://www.springframework.org/schema/data/jpa   https://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

	<sd-jpa:repositories base-package="org.springframework.integration.jpa.outbound"/>

	<int:service-activator input-channel="jpaInputChannel" ref="studentRepository" method="findByGender"/>

	<import resource="BaseJpaPollingChannelAdapterTests-context.xml"/>

	<int:poller default="true" fixed-rate="2000"/>

	<int:gateway default-reply-channel="studentReplyChannel"
			service-interface="org.springframework.integration.jpa.outbound.StudentService" default-reply-timeout="3000">
		<int:method name="deleteStudent"            request-channel="deleteStudentChannel" />
		<int:method name="deleteStudents"            request-channel="deleteStudentChannel" />
		<int:method name="getStudent"               request-channel="getStudentChannel"    />
		<int:method name="getStudentWithException"  request-channel="getStudentEndpointWithExceptionChannel"/>
		<int:method name="getStudentWithParameters" request-channel="getStudentWithParametersChannel"/>
		<int:method name="getAllStudents"           request-channel="getAllStudentsChannel" />
		<int:method name="persistStudent"           request-channel="persistStudentChannel" />
		<int:method name="persistStudentUsingMerge" request-channel="persistStudentUsingMergeChannel" />
		<int:method name="getStudent2"              request-channel="retrievingGatewayInsideChain" />
		<int:method name="persistStudent2"          request-channel="updatingGatewayInsideChain" />
		<int:method name="getAllStudentsFromGivenRecord" request-channel="getStudentsFromGivenRecordChannel"/>
		<int:method name="getStudents" request-channel="getStudentsWithMaxNumberOfRecordsChannel"/>
		<int:method name="getStudentsUsingJpaRepository" request-channel="jpaInputChannel"/>
	</int:gateway>

	<int:channel id="studentReplyChannel"/>

	<int:channel id="deleteStudentChannel"/>
	<int:channel id="getStudentChannel"/>
	<int:channel id="getStudentWithParametersChannel"/>
	<int:channel id="getAllStudentsChannel"/>
	<int:channel id="persistStudentChannel"/>
	<int:channel id="persistStudentUsingMergeChannel"/>
	<int:channel id="getStudentEndpointWithExceptionChannel"/>
	<int:channel id="retrievingGatewayInsideChain"/>
	<int:channel id="updatingGatewayInsideChain"/>
	<int:channel id="getStudentsFromGivenRecordChannel"/>
	<int:channel id="getStudentsWithMaxNumberOfRecordsChannel"/>

	<bean id="deleteStudentEndpoint"
				class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="deleteStudentChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="entityClass"        value="org.springframework.integration.jpa.test.entity.StudentDomain"/>
						<property name="persistMode" value="DELETE"/>
					</bean>
				</constructor-arg>
				<property name="gatewayType"   value="UPDATING"/>
				<property name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>

	<bean id="getStudentEndpoint"
		  class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="getStudentChannel"/>
		<constructor-arg name="handler">
		<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="entityClass"        value="org.springframework.integration.jpa.test.entity.StudentDomain"/>
						<property name="jpaQuery"           value="from Student s where s.id = :id"/>
						<property name="expectSingleResult" value="true"/>
						<property name="jpaParameters" >
					<util:list>
						<bean class="org.springframework.integration.jpa.support.JpaParameter">
							<property name="name"       value="id"/>
							<property name="expression" value="payload"/>
						</bean>
					</util:list>
						</property>
					</bean>
				</constructor-arg>
				<property        name="gatewayType"   value="RETRIEVING"/>
				<property        name="outputChannel" ref="studentReplyChannel"/>
		</bean>
		</constructor-arg>
	</bean>

	<bean id="getStudentEndpointWithException"
		  class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="getStudentEndpointWithExceptionChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="entityClass"        value="org.springframework.integration.jpa.test.entity.StudentDomain"/>
						<property name="jpaQuery"           value="from Student s"/>
						<property name="expectSingleResult" value="true"/>

						<property name="jpaParameters" >
							<util:list>
								<bean class="org.springframework.integration.jpa.support.JpaParameter">
									<property name="name"       value="id"/>
									<property name="expression" value="payload"/>
								</bean>
							</util:list>
						</property>
					</bean>
				</constructor-arg>
				<property        name="gatewayType"   value="RETRIEVING"/>
				<property        name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>

	<bean id="getAllStudentsEndpoint"
		class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="getAllStudentsChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="entityClass" value="org.springframework.integration.jpa.test.entity.StudentDomain"/>
					</bean>
				</constructor-arg>
				<property        name="gatewayType"   value="RETRIEVING"/>
				<property        name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>

	<bean id="persitStudentEndpoint"
		class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="persistStudentChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="entityClass" value="org.springframework.integration.jpa.test.entity.StudentDomain"/>
					</bean>
				</constructor-arg>
				<property        name="gatewayType"   value="UPDATING"/>
				<property        name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>

	<bean id="persitStudentUsingMergeEndpoint"
		class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="persistStudentUsingMergeChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="entityClass" value="org.springframework.integration.jpa.test.entity.StudentDomain"/>
						<property name="persistMode" value="MERGE"/>
					</bean>
				</constructor-arg>
				<property name="gatewayType"   value="UPDATING"/>
				<property name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>

	<bean id="getStudentWithParametersEndpoint"
		class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="getStudentWithParametersChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="entityClass"        value="org.springframework.integration.jpa.test.entity.StudentDomain"/>
						<property name="jpaQuery"           value="from Student s where s.firstName = ?1 and s.lastName = ?2"/>
						<property name="expectSingleResult" value="true"/>
						<property name="jpaParameters" >
							<util:list>
								<bean class="org.springframework.integration.jpa.support.JpaParameter">
									<property name="expression" value="payload"/>
								</bean>
								<bean class="org.springframework.integration.jpa.support.JpaParameter">
									<property name="value" value="Last Two"/>
								</bean>
							</util:list>
						</property>
					</bean>
				</constructor-arg>
				<property        name="gatewayType"   value="RETRIEVING"/>
				<property        name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>

	<bean id="getStudentsFromGivenFromRecord"
		class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="getStudentsFromGivenRecordChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="jpaQuery"           value="select s from Student s"/>
						<property name="expectSingleResult" value="false"/>
						<property		 name="firstResultExpression"
						    value="#{new org.springframework.expression.spel.standard.SpelExpressionParser().parseExpression('payload')}"/>
					</bean>
				</constructor-arg>
				<property        name="gatewayType"   value="RETRIEVING"/>
				<property        name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>

	<bean id="getStudentsWithMaxNumberOfRecords"
		class="org.springframework.integration.endpoint.EventDrivenConsumer">
		<constructor-arg name="inputChannel" ref="getStudentsWithMaxNumberOfRecordsChannel"/>
		<constructor-arg name="handler">
			<bean class="org.springframework.integration.jpa.outbound.JpaOutboundGateway">
				<constructor-arg name="jpaExecutor">
					<bean class="org.springframework.integration.jpa.core.JpaExecutor">
						<constructor-arg name="entityManager" ref="entityManager"/>
						<property name="jpaQuery"           value="select s from Student s"/>
						<property name="expectSingleResult" value="false"/>
						<property name="firstResultExpression"
						    value="#{new org.springframework.expression.spel.standard.SpelExpressionParser().parseExpression('payload')}"/>
						<property name="maxResultsExpression"
						    value="#{new org.springframework.expression.spel.standard.SpelExpressionParser().parseExpression('payload')}"/>
					</bean>
				</constructor-arg>
				<property        name="gatewayType"   value="RETRIEVING"/>
				<property        name="outputChannel" ref="studentReplyChannel"/>
			</bean>
		</constructor-arg>
	</bean>


	<int:chain input-channel="retrievingGatewayInsideChain" output-channel="studentReplyChannel">
		<jpa:retrieving-outbound-gateway entity-manager="entityManager"
										 expect-single-result="true"
										 entity-class="org.springframework.integration.jpa.test.entity.StudentDomain"
										 jpa-query="from Student s where s.id = :id">
			<jpa:parameter name="id" expression="payload"/>
		</jpa:retrieving-outbound-gateway>
	</int:chain>

	<int:chain input-channel="updatingGatewayInsideChain" output-channel="studentReplyChannel">
		<jpa:updating-outbound-gateway entity-manager="entityManager"
									   entity-class="org.springframework.integration.jpa.test.entity.StudentDomain"/>
	</int:chain>

</beans>
