RESOLVED - BATCH-1144: Create top-level element <job-listener/>

This commit is contained in:
dhgarrette
2009-03-13 06:33:50 +00:00
parent 4de7d5ec2d
commit 1204ec62fc
5 changed files with 114 additions and 48 deletions

View File

@@ -34,6 +34,7 @@ public class CoreNamespaceHandler extends NamespaceHandlerSupport {
this.registerBeanDefinitionParser("step", new TopLevelStepParser());
this.registerBeanDefinitionParser("tasklet", new TopLevelTaskletElementParser());
this.registerBeanDefinitionParser("job-repository", new JobRepositoryParser());
this.registerBeanDefinitionParser("job-listener", new TopLevelJobListenerParser());
this.registerBeanDefinitionParser("step-listener", new TopLevelStepListenerParser());
}
}

View File

@@ -0,0 +1,29 @@
package org.springframework.batch.core.configuration.xml;
import org.springframework.batch.core.listener.AbstractListenerFactoryBean;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
/**
* Parse &lt;job-listener/&gt; elements in the batch namespace.
*
* @author Dan Garrette
* @since 2.0
*/
public class TopLevelJobListenerParser extends AbstractSingleBeanDefinitionParser {
private JobExecutionListenerParser jobListenerParser = new JobExecutionListenerParser();
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
jobListenerParser.doParse(element, parserContext, builder);
}
@Override
protected Class<? extends AbstractListenerFactoryBean> getBeanClass(Element element) {
return jobListenerParser.getBeanClass();
}
}

View File

@@ -75,6 +75,20 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="job-listener">
<xsd:annotation>
<xsd:documentation>
A reference to a JobExecutionListener or a POJO
(with before-job-method / after-job-method).
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="jobExecutionListenerType"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="step-listener">
<xsd:annotation>
<xsd:documentation>
@@ -260,36 +274,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="listener" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:ID" />
<xsd:attribute name="ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
A reference to a JobExecutionListener or a POJO
(with before-job-method / after-job-method).
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="class" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
A class name used to create a listener from the default constructor.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.Class" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="before-job-method" type="xsd:string" />
<xsd:attribute name="after-job-method" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="listener" type="jobExecutionListenerType" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="mergeAttribute"/>
</xsd:complexType>
@@ -329,7 +314,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="listener" type="listenerType" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="listener" type="retryListenerType" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="mergeAttribute"/>
</xsd:complexType>
@@ -543,12 +528,41 @@
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="listenerType">
<xsd:complexType name="retryListenerType">
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="ref" type="xsd:string"/>
<xsd:attribute name="class" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="jobExecutionListenerType">
<xsd:attribute name="id" type="xsd:ID" />
<xsd:attribute name="ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
A reference to a JobExecutionListener or a POJO
(with before-job-method / after-job-method).
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="class" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
A class name used to create a job execution listener from the default constructor.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.Class" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="before-job-method" type="xsd:string" />
<xsd:attribute name="after-job-method" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="stepListenerType">
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="ref" type="xsd:string">
@@ -592,22 +606,6 @@
<xsd:attribute name="on-skip-in-write-method" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="jobExecutionListenerType">
<xsd:attribute name="before-method" type="xsd:string"/>
<xsd:attribute name="after-method" type="xsd:string"/>
<xsd:attribute name="ref" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
A bean definition for a job listener (or POJO if using *-method attributes)
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:group name="stepListeners">
<xsd:sequence>
<xsd:element name="listeners" minOccurs="0" maxOccurs="1">

View File

@@ -74,6 +74,26 @@ public class JobParserTests {
assertTrue(c);
}
@Test
public void testStandaloneListener() throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
"org/springframework/batch/core/configuration/xml/JobParserParentAttributeTests-context.xml");
List<?> jobListeners = getListeners("job3", ctx);
assertEquals(2, jobListeners.size());
boolean a = false;
boolean b = false;
for (Object l : jobListeners) {
if (l instanceof DummyAnnotationJobExecutionListener) {
a = true;
}
else if (l instanceof JobExecutionListenerSupport) {
b = true;
}
}
assertTrue(a);
assertTrue(b);
}
@SuppressWarnings("unchecked")
private List<?> getListeners(String jobName, ApplicationContext ctx) throws Exception {
Map<String, Object> beans = ctx.getBeansOfType(Job.class);

View File

@@ -22,10 +22,28 @@
</listeners>
</job>
<job id="job3" parent="baseJob3">
<step id="s3" tasklet="dummyTasklet"/>
<listeners merge="true">
<listener ref="listener1"/>
</listeners>
</job>
<job id="baseJob" abstract="true">
<listeners>
<listener class="org.springframework.batch.core.configuration.xml.DummyAnnotationJobExecutionListener"/>
</listeners>
</job>
<job-listener id="listener1" class="org.springframework.batch.core.configuration.xml.DummyAnnotationJobExecutionListener"/>
<beans:bean id="baseJob3" abstract="true">
<beans:property name="jobExecutionListeners">
<beans:list>
<job-listener class="org.springframework.batch.core.listener.JobExecutionListenerSupport"/>
</beans:list>
</beans:property>
</beans:bean>
</beans:beans>