OPEN - issue BATCH-911: Consolidate Samples
http://jira.springframework.org/browse/BATCH-911 Added support for listeners that implement the interface, along with support for class attribute in listener tag.
This commit is contained in:
@@ -16,21 +16,26 @@
|
||||
|
||||
package org.springframework.batch.core.configuration.xml;
|
||||
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.core.JobExecutionListener;
|
||||
import org.springframework.batch.core.listener.JobExecutionListenerAdapter;
|
||||
import org.springframework.batch.core.listener.JobExecutionListenerFactoryBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.config.BeanReference;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} for {@link JobExecutionListener}s
|
||||
@@ -48,9 +53,39 @@ public class JobExecutionListenerParser {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Element> listenerElements = (List<Element>) DomUtils.getChildElementsByTagName(element, "listener");
|
||||
for(Element listenerElement : listenerElements){
|
||||
BeanDefinitionBuilder listenerBuilder = BeanDefinitionBuilder.genericBeanDefinition(JobExecutionListenerAdapter.class);
|
||||
String delegateName = listenerElement.getAttribute("ref");
|
||||
listenerBuilder.addConstructorArgReference(delegateName);
|
||||
BeanDefinitionBuilder listenerBuilder = BeanDefinitionBuilder.genericBeanDefinition(JobExecutionListenerFactoryBean.class);
|
||||
String id = listenerElement.getAttribute("id");
|
||||
String listenerRef = listenerElement.getAttribute("ref");
|
||||
String className = listenerElement.getAttribute("class");
|
||||
if ((StringUtils.hasText(id) || StringUtils.hasText(className))
|
||||
&& StringUtils.hasText(listenerRef)) {
|
||||
NamedNodeMap attributeNodes = listenerElement.getAttributes();
|
||||
StringBuilder attributes = new StringBuilder();
|
||||
for (int i = 0; i < attributeNodes.getLength(); i++) {
|
||||
if (i > 0) {
|
||||
attributes.append(" ");
|
||||
}
|
||||
attributes.append(attributeNodes.item(i));
|
||||
}
|
||||
throw new BeanCreationException("Both 'ref' and 'class' specified; use 'class' with an optional 'id' or just 'ref' for <" +
|
||||
listenerElement.getTagName() + "> element with attributes: " + attributes);
|
||||
}
|
||||
|
||||
if(hasText(listenerRef)){
|
||||
listenerBuilder.addPropertyReference("delegate", listenerRef);
|
||||
}
|
||||
else if(hasText(className)){
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(className, null, null);
|
||||
if (!StringUtils.hasText(id)) {
|
||||
id = parserContext.getReaderContext().generateBeanName(beanDef);
|
||||
}
|
||||
parserContext.getRegistry().registerBeanDefinition(id, beanDef);
|
||||
listenerBuilder.addPropertyReference("delegate", id);
|
||||
}
|
||||
else {
|
||||
throw new BeanCreationException("Neither 'ref' or 'class' specified for <" + listenerElement.getTagName() + "> element");
|
||||
}
|
||||
|
||||
|
||||
String beforeMethod = listenerElement.getAttribute("before-method");
|
||||
if(StringUtils.hasText(beforeMethod)){
|
||||
@@ -62,7 +97,6 @@ public class JobExecutionListenerParser {
|
||||
listenerBuilder.addPropertyValue("afterMethod", afterMethod);
|
||||
}
|
||||
AbstractBeanDefinition beanDef = listenerBuilder.getBeanDefinition();
|
||||
String id = listenerElement.getAttribute("id");
|
||||
if (!StringUtils.hasText(id)) {
|
||||
id = parserContext.getReaderContext().generateBeanName(beanDef);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.listener;
|
||||
|
||||
import org.springframework.batch.core.JobExecutionListener;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link FactoryBean} implementation that accepts a delgate, checking whether
|
||||
* or not it implements the {@link JobExecutionListener} interface, and if so, passes directly
|
||||
* through. However, if it does not implement the interface, {@link JobExecutionListenerAdapter}
|
||||
* is used to
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class JobExecutionListenerFactoryBean implements FactoryBean, InitializingBean{
|
||||
|
||||
private Object delegate;
|
||||
private String beforeMethod;
|
||||
private String afterMethod;
|
||||
|
||||
public void setDelegate(Object delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public void setBeforeMethod(String beforeMethod) {
|
||||
this.beforeMethod = beforeMethod;
|
||||
}
|
||||
|
||||
public void setAfterMethod(String afterMethod) {
|
||||
this.afterMethod = afterMethod;
|
||||
}
|
||||
|
||||
public Object getObject() throws Exception {
|
||||
if(delegate instanceof JobExecutionListener){
|
||||
return delegate;
|
||||
}
|
||||
else{
|
||||
JobExecutionListenerAdapter listenerAdapter = new JobExecutionListenerAdapter(delegate);
|
||||
listenerAdapter.setBeforeMethod(beforeMethod);
|
||||
listenerAdapter.setAfterMethod(afterMethod);
|
||||
listenerAdapter.afterPropertiesSet();
|
||||
return listenerAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Class getObjectType() {
|
||||
return JobExecutionListener.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(delegate, "Delegate listener must not be null");
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionListener;
|
||||
import org.springframework.batch.core.annotation.AfterJob;
|
||||
import org.springframework.batch.core.annotation.BeforeJob;
|
||||
|
||||
@@ -32,12 +33,15 @@ public class JobExecutionListenerAdapterTests {
|
||||
|
||||
private TestClass testClass;
|
||||
private AnnotatedTestClass annotatedTestClass;
|
||||
private InterfaceTestClass interfaceTestClass;
|
||||
private JobExecution jobExecution = new JobExecution(11L);
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp(){
|
||||
testClass = new TestClass();
|
||||
annotatedTestClass = new AnnotatedTestClass();
|
||||
interfaceTestClass = new InterfaceTestClass();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,6 +94,16 @@ public class JobExecutionListenerAdapterTests {
|
||||
assertTrue(annotatedTestClass.afterJobCalled);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithInterface() throws Exception{
|
||||
JobExecutionListenerAdapter adapter = new JobExecutionListenerAdapter(interfaceTestClass);
|
||||
adapter.afterPropertiesSet();
|
||||
adapter.beforeJob(jobExecution);
|
||||
adapter.afterJob(jobExecution);
|
||||
assertTrue(annotatedTestClass.beforeJobCalled);
|
||||
assertTrue(annotatedTestClass.afterJobCalled);
|
||||
}
|
||||
|
||||
private class TestClass{
|
||||
|
||||
boolean beforeJobCalled = false;
|
||||
@@ -116,4 +130,9 @@ public class JobExecutionListenerAdapterTests {
|
||||
super.afterJobCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class InterfaceTestClass extends TestClass implements JobExecutionListener {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.listener;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionListener;
|
||||
import org.springframework.batch.core.annotation.AfterJob;
|
||||
import org.springframework.batch.core.annotation.BeforeJob;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class JobExecutionListnerFactoryBeanTests {
|
||||
|
||||
JobExecutionListenerFactoryBean factoryBean;
|
||||
|
||||
@Before
|
||||
public void setUp(){
|
||||
factoryBean = new JobExecutionListenerFactoryBean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithInterface() throws Exception{
|
||||
JobListenerWithInterface delegate = new JobListenerWithInterface();
|
||||
factoryBean.setDelegate(delegate);
|
||||
assertEquals(delegate,factoryBean.getObject());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAnnotations() throws Exception{
|
||||
AnnotatedTestClass delegate = new AnnotatedTestClass();
|
||||
factoryBean.setDelegate(delegate);
|
||||
JobExecutionListener listener = (JobExecutionListener) factoryBean.getObject();
|
||||
JobExecution jobExecution = new JobExecution(11L);
|
||||
listener.beforeJob(jobExecution);
|
||||
listener.afterJob(jobExecution);
|
||||
assertTrue(delegate.beforeJobCalled);
|
||||
assertTrue(delegate.afterJobCalled);
|
||||
}
|
||||
|
||||
private class JobListenerWithInterface implements JobExecutionListener{
|
||||
|
||||
public void afterJob(JobExecution jobExecution) {
|
||||
}
|
||||
|
||||
public void beforeJob(JobExecution jobExecution) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class AnnotatedTestClass {
|
||||
|
||||
boolean beforeJobCalled = false;
|
||||
boolean afterJobCalled = false;
|
||||
|
||||
@BeforeJob
|
||||
public void before(){
|
||||
beforeJobCalled = true;
|
||||
}
|
||||
|
||||
@AfterJob
|
||||
public void after(){
|
||||
afterJobCalled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
</step>
|
||||
<listeners>
|
||||
<listener after-method="afterJob" ref="testListener"/>
|
||||
<listener after-method="afterJob" class="org.springframework.batch.core.configuration.xml.TestJobListener"/>
|
||||
</listeners>
|
||||
</job>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user