/*
* Copyright 2013-2017 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.integration.file.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.file.DefaultFileNameGenerator;
import org.springframework.integration.file.filters.AbstractPersistentAcceptOnceFileListFilter;
import org.springframework.integration.file.filters.CompositeFileListFilter;
import org.springframework.integration.file.filters.ExpressionFileListFilter;
import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.integration.file.remote.RemoteFileOperations;
import org.springframework.integration.metadata.SimpleMetadataStore;
import org.springframework.util.StringUtils;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author David Turanski
* @author Gary Russell
* @author Artem Bilan
*
* @since 3.0
*
*/
public final class FileParserUtils {
private FileParserUtils() {
}
public static BeanDefinition parseRemoteFileTemplate(Element element, ParserContext parserContext,
boolean atLeastOneRemoteDirectoryAttributeRequired, Class<? extends RemoteFileOperations<?>> templateClass) {
BeanDefinitionBuilder templateBuilder = BeanDefinitionBuilder.genericBeanDefinition(templateClass);
templateBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
// configure MessageHandler properties
IntegrationNamespaceUtils.setValueIfAttributeDefined(templateBuilder, element, "temporary-file-suffix");
IntegrationNamespaceUtils.setValueIfAttributeDefined(templateBuilder, element, "use-temporary-file-name");
IntegrationNamespaceUtils.setValueIfAttributeDefined(templateBuilder, element, "auto-create-directory");
BeanDefinition expressionDef =
IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("remote-directory",
"remote-directory-expression", parserContext, element, atLeastOneRemoteDirectoryAttributeRequired);
if (expressionDef != null) {
templateBuilder.addPropertyValue("remoteDirectoryExpression", expressionDef);
}
expressionDef = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("temporary-remote-directory",
"temporary-remote-directory-expression", parserContext, element, false);
if (expressionDef != null) {
templateBuilder.addPropertyValue("temporaryRemoteDirectoryExpression", expressionDef);
}
// configure remote FileNameGenerator
String remoteFileNameGenerator = element.getAttribute("remote-filename-generator");
String remoteFileNameGeneratorExpression = element.getAttribute("remote-filename-generator-expression");
boolean hasRemoteFileNameGenerator = StringUtils.hasText(remoteFileNameGenerator);
boolean hasRemoteFileNameGeneratorExpression = StringUtils.hasText(remoteFileNameGeneratorExpression);
if (hasRemoteFileNameGenerator || hasRemoteFileNameGeneratorExpression) {
if (hasRemoteFileNameGenerator && hasRemoteFileNameGeneratorExpression) {
parserContext.getReaderContext().error(
"at most one of 'remote-filename-generator-expression' or 'remote-filename-generator' "
+ "is allowed on a remote file outbound adapter", element);
}
if (hasRemoteFileNameGenerator) {
templateBuilder.addPropertyReference("fileNameGenerator", remoteFileNameGenerator);
}
else {
BeanDefinitionBuilder fileNameGeneratorBuilder = BeanDefinitionBuilder
.genericBeanDefinition(DefaultFileNameGenerator.class);
fileNameGeneratorBuilder.addPropertyValue("expression", remoteFileNameGeneratorExpression);
templateBuilder.addPropertyValue("fileNameGenerator", fileNameGeneratorBuilder.getBeanDefinition());
}
}
IntegrationNamespaceUtils.setValueIfAttributeDefined(templateBuilder, element, "charset");
templateBuilder.addPropertyValue("remoteFileSeparator", element.getAttribute("remote-file-separator"));
return templateBuilder.getBeanDefinition();
}
static void configureFilter(BeanDefinitionBuilder synchronizerBuilder, Element element, ParserContext parserContext,
Class<? extends FileListFilter<?>> patternClass, Class<? extends FileListFilter<?>> regexClass,
Class<? extends AbstractPersistentAcceptOnceFileListFilter<?>> persistentAcceptOnceFileListFilterClass) {
String filter = element.getAttribute("filter");
String filterExpression = element.getAttribute("filter-expression");
String fileNamePattern = element.getAttribute("filename-pattern");
String fileNameRegex = element.getAttribute("filename-regex");
boolean hasFilter = StringUtils.hasText(filter);
boolean hasFilterExpression = StringUtils.hasText(filterExpression);
boolean hasFileNamePattern = StringUtils.hasText(fileNamePattern);
boolean hasFileNameRegex = StringUtils.hasText(fileNameRegex);
if (hasFilter || hasFilterExpression || hasFileNamePattern || hasFileNameRegex) {
int count = 0;
if (hasFilter) {
count++;
}
if (hasFileNamePattern) {
count++;
}
if (hasFileNameRegex) {
count++;
}
if (hasFilterExpression) {
count++;
}
if (count != 1) {
parserContext.getReaderContext().error("at most one of 'filename-pattern', " +
"'filename-regex', 'filter' or 'filter-expression' is allowed on remote file inbound adapter",
element);
}
if (hasFilter) {
synchronizerBuilder.addPropertyReference("filter", filter);
}
else if (hasFilterExpression) {
BeanDefinition expressionFilterBeanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(ExpressionFileListFilter.class)
.addConstructorArgValue(filterExpression)
.getBeanDefinition();
synchronizerBuilder.addPropertyValue("filter", expressionFilterBeanDefinition);
}
else if (hasFileNamePattern) {
BeanDefinition patternFilter =
BeanDefinitionBuilder.genericBeanDefinition(patternClass)
.addConstructorArgValue(fileNamePattern)
.getBeanDefinition();
composeFilters(synchronizerBuilder, persistentAcceptOnceFileListFilterClass, patternFilter);
}
else {
BeanDefinition regexFilter = BeanDefinitionBuilder.genericBeanDefinition(regexClass)
.addConstructorArgValue(fileNameRegex)
.getBeanDefinition();
composeFilters(synchronizerBuilder, persistentAcceptOnceFileListFilterClass, regexFilter);
}
}
}
private static void composeFilters(BeanDefinitionBuilder synchronizerBuilder,
Class<? extends AbstractPersistentAcceptOnceFileListFilter<?>> persistentAcceptOnceFileListFilterClass,
BeanDefinition filter) {
BeanDefinition persistentFilter =
BeanDefinitionBuilder.genericBeanDefinition(persistentAcceptOnceFileListFilterClass)
.addConstructorArgValue(
BeanDefinitionBuilder
.genericBeanDefinition(SimpleMetadataStore.class)
.getBeanDefinition())
.addConstructorArgValue("remoteFileMessageSource")
.getBeanDefinition();
ManagedList<BeanDefinition> filters = new ManagedList<>();
filters.add(filter);
filters.add(persistentFilter);
BeanDefinition compositeFilterDefinition =
BeanDefinitionBuilder.genericBeanDefinition(CompositeFileListFilter.class)
.addConstructorArgValue(filters)
.getBeanDefinition();
synchronizerBuilder.addPropertyValue("filter", compositeFilterDefinition);
}
}