Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.springframework.batch.core.jsr.configuration.xml.ChunkParser Maven / Gradle / Ivy
/*
* Copyright 2013-2014 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
*
* https://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.jsr.configuration.xml;
import java.util.List;
import org.springframework.batch.core.configuration.xml.ExceptionElementParser;
import org.springframework.batch.core.jsr.configuration.support.BatchArtifactType;
import org.springframework.batch.core.step.item.ChunkOrientedTasklet;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
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.Node;
import org.w3c.dom.NodeList;
/**
* Parser for the <chunk /> element as specified in JSR-352. The current state
* parses a chunk element into it's related batch artifacts ({@link ChunkOrientedTasklet}, {@link ItemReader},
* {@link ItemProcessor}, and {@link ItemWriter}).
*
* @author Michael Minella
* @author Chris Schaefer
* @since 3.0
*
*/
public class ChunkParser {
private static final String TIME_LIMIT_ATTRIBUTE = "time-limit";
private static final String ITEM_COUNT_ATTRIBUTE = "item-count";
private static final String CHECKPOINT_ALGORITHM_ELEMENT = "checkpoint-algorithm";
private static final String CLASS_ATTRIBUTE = "class";
private static final String INCLUDE_ELEMENT = "include";
private static final String NO_ROLLBACK_EXCEPTION_CLASSES_ELEMENT = "no-rollback-exception-classes";
private static final String RETRYABLE_EXCEPTION_CLASSES_ELEMENT = "retryable-exception-classes";
private static final String SKIPPABLE_EXCEPTION_CLASSES_ELEMENT = "skippable-exception-classes";
private static final String WRITER_ELEMENT = "writer";
private static final String PROCESSOR_ELEMENT = "processor";
private static final String READER_ELEMENT = "reader";
private static final String REF_ATTRIBUTE = "ref";
private static final String RETRY_LIMIT_ATTRIBUTE = "retry-limit";
private static final String SKIP_LIMIT_ATTRIBUTE = "skip-limit";
private static final String CUSTOM_CHECKPOINT_POLICY = "custom";
private static final String ITEM_CHECKPOINT_POLICY = "item";
private static final String CHECKPOINT_POLICY_ATTRIBUTE = "checkpoint-policy";
public void parse(Element element, AbstractBeanDefinition bd, ParserContext parserContext, String stepName) {
MutablePropertyValues propertyValues = bd.getPropertyValues();
bd.setBeanClass(StepFactoryBean.class);
bd.setAttribute("isNamespaceStep", false);
propertyValues.addPropertyValue("hasChunkElement", Boolean.TRUE);
String checkpointPolicy = element.getAttribute(CHECKPOINT_POLICY_ATTRIBUTE);
if(StringUtils.hasText(checkpointPolicy)) {
if(checkpointPolicy.equals(ITEM_CHECKPOINT_POLICY)) {
String itemCount = element.getAttribute(ITEM_COUNT_ATTRIBUTE);
if (StringUtils.hasText(itemCount)) {
propertyValues.addPropertyValue("commitInterval", itemCount);
} else {
propertyValues.addPropertyValue("commitInterval", "10");
}
parseSimpleAttribute(element, propertyValues, TIME_LIMIT_ATTRIBUTE, "timeout");
} else if(checkpointPolicy.equals(CUSTOM_CHECKPOINT_POLICY)) {
parseCustomCheckpointAlgorithm(element, parserContext, propertyValues, stepName);
}
} else {
String itemCount = element.getAttribute(ITEM_COUNT_ATTRIBUTE);
if (StringUtils.hasText(itemCount)) {
propertyValues.addPropertyValue("commitInterval", itemCount);
} else {
propertyValues.addPropertyValue("commitInterval", "10");
}
parseSimpleAttribute(element, propertyValues, TIME_LIMIT_ATTRIBUTE, "timeout");
}
parseSimpleAttribute(element, propertyValues, SKIP_LIMIT_ATTRIBUTE, "skipLimit");
parseSimpleAttribute(element, propertyValues, RETRY_LIMIT_ATTRIBUTE, "retryLimit");
NodeList children = element.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node nd = children.item(i);
parseChildElement(element, parserContext, propertyValues, nd, stepName);
}
}
private void parseSimpleAttribute(Element element,
MutablePropertyValues propertyValues, String attributeName, String propertyName) {
String propertyValue = element.getAttribute(attributeName);
if (StringUtils.hasText(propertyValue)) {
propertyValues.addPropertyValue(propertyName, propertyValue);
}
}
private void parseChildElement(Element element, ParserContext parserContext,
MutablePropertyValues propertyValues, Node nd, String stepName) {
if (nd instanceof Element) {
Element nestedElement = (Element) nd;
String name = nestedElement.getLocalName();
String artifactName = nestedElement.getAttribute(REF_ATTRIBUTE);
if(name.equals(READER_ELEMENT)) {
if (StringUtils.hasText(artifactName)) {
propertyValues.addPropertyValue("stepItemReader", new RuntimeBeanReference(artifactName));
}
new PropertyParser(artifactName, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(nestedElement);
} else if(name.equals(PROCESSOR_ELEMENT)) {
if (StringUtils.hasText(artifactName)) {
propertyValues.addPropertyValue("stepItemProcessor", new RuntimeBeanReference(artifactName));
}
new PropertyParser(artifactName, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(nestedElement);
} else if(name.equals(WRITER_ELEMENT)) {
if (StringUtils.hasText(artifactName)) {
propertyValues.addPropertyValue("stepItemWriter", new RuntimeBeanReference(artifactName));
}
new PropertyParser(artifactName, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(nestedElement);
} else if(name.equals(SKIPPABLE_EXCEPTION_CLASSES_ELEMENT)) {
ManagedMap exceptionClasses = new ExceptionElementParser().parse(element, parserContext, SKIPPABLE_EXCEPTION_CLASSES_ELEMENT);
if(exceptionClasses != null) {
propertyValues.addPropertyValue("skippableExceptionClasses", exceptionClasses);
}
} else if(name.equals(RETRYABLE_EXCEPTION_CLASSES_ELEMENT)) {
ManagedMap exceptionClasses = new ExceptionElementParser().parse(element, parserContext, RETRYABLE_EXCEPTION_CLASSES_ELEMENT);
if(exceptionClasses != null) {
propertyValues.addPropertyValue("retryableExceptionClasses", exceptionClasses);
}
} else if(name.equals(NO_ROLLBACK_EXCEPTION_CLASSES_ELEMENT)) {
//TODO: Update to support excludes
ManagedList list = new ManagedList<>();
for (Element child : DomUtils.getChildElementsByTagName(nestedElement, INCLUDE_ELEMENT)) {
String className = child.getAttribute(CLASS_ATTRIBUTE);
list.add(new TypedStringValue(className, Class.class));
}
propertyValues.addPropertyValue("noRollbackExceptionClasses", list);
}
}
}
private void parseCustomCheckpointAlgorithm(Element element, ParserContext parserContext, MutablePropertyValues propertyValues, String stepName) {
List elements = DomUtils.getChildElementsByTagName(element, CHECKPOINT_ALGORITHM_ELEMENT);
if(elements.size() == 1) {
Element checkpointAlgorithmElement = elements.get(0);
String name = checkpointAlgorithmElement.getAttribute(REF_ATTRIBUTE);
if(StringUtils.hasText(name)) {
propertyValues.addPropertyValue("stepChunkCompletionPolicy", new RuntimeBeanReference(name));
}
new PropertyParser(name, parserContext, BatchArtifactType.STEP_ARTIFACT, stepName).parseProperties(checkpointAlgorithmElement);
} else if(elements.size() > 1){
parserContext.getReaderContext().error(
"The element may not appear more than once in a single <"
+ element.getNodeName() + "/>.", element);
}
}
}