Zip: Some deep cleanup and polishing

* Upgrade to Gradle-2.5, SI-4.2.4
* Remove redundant dependencies
* Add `slf4j-log4j12` to avoid log noise during testing
* Add `settings.gradle` to allow Artifactory Release Management
* Move XSD stuff to the proper place - `org\springframework\integration\zip\config`
* Get rid of manual `enum` transformation in the `Parser`:
  - we can't do that there because `property-placeholder` and SpEL are processed later
  - no reason to do that at all - `enum`s are properly converted by the SF during bean population phase
* Fix `UnZipTransformer` to `delete()` file in the `finally` block after closing the `InputStream` on file
This commit is contained in:
Artem Bilan
2016-01-07 21:43:15 -05:00
parent f7b31228c2
commit 0a5fedcd7a
21 changed files with 170 additions and 240 deletions

View File

@@ -61,7 +61,8 @@ If the payload is an instance of `File`, this property specifies whether to dele
### workDirectory
Set the work-directory. The work directory is used when the ZipResultType is set to ZipResultType.FILE. By default this property is set to the System temporary directory containing a sub-directory "ziptransformer".
Set the work-directory. The work directory is used when the ZipResultType is set to ZipResultType.FILE.
By default this property is set to the System temporary directory containing a sub-directory "ziptransformer".
### ZipResultType
@@ -120,7 +121,8 @@ To build complete distribution including `-dist` and `-schema` zip files (result
# IDE Support
While your custom Spring Integration Adapter is initially created with SpringSource Tool Suite, you in fact end up with a Gradle-based project. As such, the created project can be imported into other IDEs as well.
While your custom Spring Integration Adapter is initially created with SpringSource Tool Suite, you in fact end up with a Gradle-based project.
As such, the created project can be imported into other IDEs as well.
## Using Spring Tool Suite
@@ -155,17 +157,19 @@ Check out the [spring-integration][spring-integration tag] tag on [Stack Overflo
* [Spring Integration][]
* [Spring Integration Samples][]
* [Spring Integration Templates][]
* [Spring Integration Java DSL][]
* [Spring Integration Dsl Groovy][]
* [Spring Integration Dsl Scala][]
For more information, please also don't forget to visit the [Spring Integration][] website.
[Spring Integration]: https://github.com/SpringSource/spring-integration
[Spring Integration]: https://github.com/spring-projects/spring-integration
[spring-integration tag]: http://stackoverflow.com/questions/tagged/spring-integration
[Spring Integration Samples]: https://github.com/SpringSource/spring-integration-samples
[Spring Integration Templates]: https://github.com/SpringSource/spring-integration-templates/tree/master/si-sts-templates
[Spring Integration Dsl Groovy]: https://github.com/SpringSource/spring-integration-dsl-groovy
[Spring Integration Dsl Scala]: https://github.com/SpringSource/spring-integration-dsl-scala
[Spring Integration Samples]: https://github.com/spring-projects/spring-integration-samples
[Spring Integration Templates]: https://github.com/spring-projects/spring-integration-templates/tree/master/si-sts-templates
[Spring Integration Java DSL]: https://github.com/spring-projects/spring-integration-java-dsl
[Spring Integration Dsl Groovy]: https://github.com/spring-projects/spring-integration-dsl-groovy
[Spring Integration Dsl Scala]: https://github.com/spring-projects/spring-integration-dsl-scala
[Stack Overflow]: http://stackoverflow.com/faq
[Zip]: http://en.wikipedia.org/wiki/Zip_%28file_format%29
[Zip]: http://en.wikipedia.org/wiki/Zip_%28file_format%29

View File

@@ -2,7 +2,7 @@ description = 'Spring Integration Zip Adapter'
buildscript {
repositories {
maven { url 'https://repo.springsource.org/plugins-snapshot' }
maven { url 'https://repo.spring.io/plugins-release' }
}
}
@@ -10,12 +10,16 @@ apply plugin: 'java'
apply from: "${rootProject.projectDir}/publish-maven.gradle"
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'jacoco'
group = 'org.springframework.integration'
repositories {
maven { url 'http://repo.springsource.org/libs-milestone' }
maven { url 'http://repo.springsource.org/plugins-release' }
if (version.endsWith('BUILD-SNAPSHOT')) {
maven { url 'https://repo.spring.io/libs-snapshot' }
}
maven { url 'https://repo.spring.io/libs-milestone' }
mavenCentral()
}
sourceCompatibility=1.6
@@ -30,12 +34,9 @@ ext {
linkScmConnection = 'https://github.com/spring-projects/spring-integration-extensions.git'
linkScmDevConnection = 'git@github.com:spring-projects/spring-integration-extensions.git'
junitVersion = '4.11'
log4jVersion = '1.2.17'
mockitoVersion = '1.9.5'
springVersion = '4.0.7.RELEASE'
springIntegrationVersion = '4.2.0.M1'
ztZipVersion = '1.8'
slf4jVersion = "1.7.13"
springIntegrationVersion = '4.2.4.RELEASE'
ztZipVersion = '1.9'
idPrefix = 'zip'
}
@@ -54,33 +55,40 @@ sourceSets {
}
}
// See http://www.gradle.org/docs/current/userguide/dependency_management.html#sub:configurations
// and http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ConfigurationContainer.html
configurations {
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
jacoco {
toolVersion = "0.7.2.201409121644"
}
dependencies {
compile "org.springframework.integration:spring-integration-core:$springIntegrationVersion"
compile "org.springframework.integration:spring-integration-file:$springIntegrationVersion"
compile "org.zeroturnaround:zt-zip:$ztZipVersion"
testCompile "org.springframework.integration:spring-integration-test:$springIntegrationVersion"
testCompile "junit:junit:$junitVersion"
testCompile "log4j:log4j:$log4jVersion"
testCompile "org.mockito:mockito-all:$mockitoVersion"
testCompile "org.springframework:spring-test:$springVersion"
jacoco group: "org.jacoco", name: "org.jacoco.agent", version: "0.7.4.201502262128", classifier: "runtime"
testRuntime "org.slf4j:slf4j-log4j12:$slf4jVersion"
}
// enable all compiler warnings; individual projects may customize further
ext.xLintArg = '-Xlint:all'
ext.xLintArg = '-Xlint:all,-options'
[compileJava, compileTestJava]*.options*.compilerArgs = [xLintArg]
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination "${buildDir}/reports/jacoco/html"
}
}
test {
// suppress all console output during testing unless running `gradle -i`
logging.captureStandardOutput(LogLevel.INFO)
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=*"
maxHeapSize = "1024m"
jacoco {
append = false
destinationFile = file("$buildDir/jacoco.exec")
}
}
task sourcesJar(type: Jar) {
@@ -98,6 +106,8 @@ artifacts {
archives javadocJar
}
build.dependsOn jacocoTestReport
apply plugin: 'sonar-runner'
sonarRunner {
@@ -136,19 +146,18 @@ task schemaZip(type: Zip) {
def shortName = idPrefix.replaceFirst("${idPrefix}-", '')
project.sourceSets.main.resources.find {
it.path.endsWith('META-INF/spring.schemas')
it.path.endsWith("META-INF${File.separator}spring.schemas")
}?.withInputStream { schemas.load(it) }
for (def key : schemas.keySet()) {
File xsdFile = project.sourceSets.main.resources.find {
it.path.endsWith(schemas.get(key))
it.path.replaceAll('\\\\', '/').endsWith(schemas.get(key))
}
assert xsdFile != null
into ("integration/${shortName}") {
from xsdFile.path
}
}
}
task docsZip(type: Zip) {
@@ -239,5 +248,6 @@ task dist(dependsOn: assemble) {
task wrapper(type: Wrapper) {
description = 'Generates gradlew[.bat] scripts'
gradleVersion = '2.4'
gradleVersion = '2.5'
distributionUrl = "http://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"
}

View File

@@ -1,6 +1,6 @@
#Tue May 12 22:21:08 EDT 2015
#Thu Jan 07 20:03:45 EST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-2.5-all.zip

View File

@@ -31,10 +31,10 @@ def customizePom(pom, gradleProject) {
generatedPom.project {
name = gradleProject.description
description = gradleProject.description
url = 'https://github.com/SpringSource/spring-integration-extensions'
url = 'https://github.com/spring-projects/spring-integration-extensions'
organization {
name = 'SpringSource'
url = 'http://springsource.org'
name = 'SpringIO'
url = 'http://spring.io'
}
licenses {
license {
@@ -44,16 +44,16 @@ def customizePom(pom, gradleProject) {
}
}
scm {
url = 'https://github.com/SpringSource/spring-integration-extensions'
connection = 'scm:git:git://github.com/SpringSource/spring-integration-extensions'
developerConnection = 'scm:git:git://github.com/SpringSource/spring-integration-extensions'
url = 'https://github.com/spring-projects/spring-integration-extensions'
connection = 'scm:git:git://github.com/spring-projects/spring-integration-extensions'
developerConnection = 'scm:git:git://github.com/spring-projects/spring-integration-extensions'
}
developers {
developer {
id = 'not specified'
id = 'ghiller'
name = 'Gunnar Hillert'
email = 'not specified'
email = 'ghiller@pivotal.io'
}
}
}

View File

@@ -0,0 +1 @@
rootProject.name = 'spring-integration-zip'

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -21,12 +21,14 @@ import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractTransformerParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.StringUtils;
/**
* Base class for Zip transformer parsers.
*
* @author Gunnar Hillert
* @author Artem Bilan
* @since 1.0
*/
public abstract class AbstractZipTransformerParser extends AbstractTransformerParser {
@@ -42,7 +44,9 @@ public abstract class AbstractZipTransformerParser extends AbstractTransformerPa
if (StringUtils.hasText(deleteFiles)) {
builder.addPropertyValue("deleteFiles", deleteFiles);
}
this.postProcessTransformer(element, parserContext, builder);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "result-type", "zipResultType");
postProcessTransformer(element, parserContext, builder);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -16,18 +16,18 @@
package org.springframework.integration.zip.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.zip.transformer.UnZipTransformer;
import org.springframework.integration.zip.transformer.ZipResultType;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the 'unzip-transformer' element.
*
* @author Gunnar Hillert
* @author Artem Bilan
* @since 1.0
*/
public class UnZipTransformerParser extends AbstractZipTransformerParser {
@@ -39,27 +39,7 @@ public class UnZipTransformerParser extends AbstractZipTransformerParser {
@Override
protected void postProcessTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
Object source = parserContext.extractSource(element);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
final String resultType = element.getAttribute("result-type");
if (StringUtils.hasText(resultType)) {
final ZipResultType zipResultType = ZipResultType.convertToZipResultType(resultType);
if (zipResultType != null) {
builder.addPropertyValue("zipResultType", zipResultType);
}
else {
parserContext.getReaderContext().error(
String.format("Unable to convert the provided result-type '%s' " +
"to the respective ZipResultType enum.", resultType), source);
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -16,18 +16,18 @@
package org.springframework.integration.zip.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.zip.transformer.ZipResultType;
import org.springframework.integration.zip.transformer.ZipTransformer;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the 'zip-transformer' element.
*
* @author Gunnar Hillert
* @author Artem Bilan
* @since 1.0
*/
public class ZipTransformerParser extends AbstractZipTransformerParser {
@@ -39,27 +39,7 @@ public class ZipTransformerParser extends AbstractZipTransformerParser {
@Override
protected void postProcessTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
Object source = parserContext.extractSource(element);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "compression-level");
final String resultType = element.getAttribute("result-type");
if (StringUtils.hasText(resultType)) {
final ZipResultType zipResultType = ZipResultType.convertToZipResultType(resultType);
if (zipResultType != null) {
builder.addPropertyValue("zipResultType", zipResultType);
}
else {
parserContext.getReaderContext().error(
String.format("Unable to convert the provided result-type '%s' " +
"to the respective ZipResultType enum.", resultType), source);
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -31,6 +31,7 @@ import org.springframework.util.Assert;
* Base class for transformers that provide Zip compression.
*
* @author Gunnar Hillert
* @author Artem Bilan
* @since 1.0
*/
public abstract class AbstractZipTransformer extends AbstractTransformer {
@@ -41,9 +42,10 @@ public abstract class AbstractZipTransformer extends AbstractTransformer {
protected volatile FileNameGenerator fileNameGenerator;
protected volatile ZipResultType zipResultType = ZipResultType.FILE;
protected ZipResultType zipResultType = ZipResultType.FILE;
protected volatile File workDirectory = new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer");
protected volatile File workDirectory =
new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer");
protected volatile boolean deleteFiles;
@@ -93,11 +95,11 @@ public abstract class AbstractZipTransformer extends AbstractTransformer {
protected void onInit() throws Exception {
super.onInit();
if (!workDirectory.exists()) {
if (!this.workDirectory.exists()) {
if (logger.isInfoEnabled()) {
logger.info(String.format("Creating work directory '%s'.", this.workDirectory));
}
workDirectory.mkdirs();
Assert.isTrue(this.workDirectory.mkdirs(), "Can't create the 'workDirectory': " + this.workDirectory);
}
final DefaultFileNameGenerator defaultFileNameGenerator = new DefaultFileNameGenerator();
defaultFileNameGenerator.setBeanFactory(getBeanFactory());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -28,17 +28,19 @@ import java.util.zip.ZipEntry;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zeroturnaround.zip.ZipEntryCallback;
import org.zeroturnaround.zip.ZipUtil;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.MessagingException;
import org.zeroturnaround.zip.ZipEntryCallback;
import org.zeroturnaround.zip.ZipUtil;
/**
* Transformer implementation that applies an UnZip transformation to the message
* payload.
*
* @author Gunnar Hillert
* @author Artem Bilan
* @since 1.0
*
*/
@@ -83,11 +85,13 @@ public class UnZipTransformer extends AbstractZipTransformer {
final File filePayload = (File) payload;
if (filePayload.isDirectory()) {
throw new UnsupportedOperationException(String.format("Cannot unzip a directory: '%s'", filePayload.getAbsolutePath()));
throw new UnsupportedOperationException(String.format("Cannot unzip a directory: '%s'",
filePayload.getAbsolutePath()));
}
if (!SpringZipUtils.isValid(filePayload)) {
throw new IllegalStateException(String.format("Not a zip file: '%s'.", filePayload.getAbsolutePath()));
throw new IllegalStateException(String.format("Not a zip file: '%s'.",
filePayload.getAbsolutePath()));
}
inputStream = new FileInputStream(filePayload);
@@ -99,8 +103,9 @@ public class UnZipTransformer extends AbstractZipTransformer {
inputStream = new ByteArrayInputStream((byte[]) payload);
}
else {
throw new IllegalArgumentException(String.format("Unsupported payload type '%s'. The only supported payload types are " +
"java.io.File, byte[] and java.io.InputStream", payload.getClass().getSimpleName()));
throw new IllegalArgumentException(String.format("Unsupported payload type '%s'. " +
"The only supported payload types are java.io.File, byte[] and java.io.InputStream",
payload.getClass().getSimpleName()));
}
final SortedMap<String, Object> uncompressedData = new TreeMap<String, Object>();
@@ -115,18 +120,19 @@ public class UnZipTransformer extends AbstractZipTransformer {
final long zipEntryCompressedSize = zipEntry.getCompressedSize();
final String type = zipEntry.isDirectory() ? "directory" : "file";
if (logger.isWarnEnabled()) {
logger.warn(String.format("Unpacking Zip Entry - Name: '%s',Time: '%s', Compressed Size: '%s', Type: '%s'",
if (logger.isInfoEnabled()) {
logger.info(String.format("Unpacking Zip Entry - Name: '%s',Time: '%s', " +
"Compressed Size: '%s', Type: '%s'",
zipEntryName, zipEntryTime, zipEntryCompressedSize, type));
}
if (ZipResultType.FILE.equals(zipResultType)) {
final File tempDir = new File(workDirectory, message.getHeaders().getId().toString());
tempDir.mkdirs();
tempDir.mkdirs(); //NOSONAR false positive
final File destinationFile = new File(tempDir, zipEntryName);
if (zipEntry.isDirectory()) {
destinationFile.mkdirs();
destinationFile.mkdirs(); //NOSONAR false positive
}
else {
SpringZipUtils.copy(zipEntryInputStream, destinationFile);
@@ -168,7 +174,9 @@ public class UnZipTransformer extends AbstractZipTransformer {
}
}
}
finally {
IOUtils.closeQuietly(inputStream);
if (payload instanceof File && this.deleteFiles) {
final File filePayload = (File) payload;
if (!filePayload.delete() && logger.isWarnEnabled()) {
@@ -178,13 +186,11 @@ public class UnZipTransformer extends AbstractZipTransformer {
}
}
}
finally {
IOUtils.closeQuietly(inputStream);
}
return unzippedData;
}
catch (Exception e) {
throw new MessageHandlingException(message, "Failed to apply Zip transformation.", e);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -15,48 +15,12 @@
*/
package org.springframework.integration.zip.transformer;
import org.springframework.util.Assert;
/**
*
* @author Gunnar Hillert
* @since 1.0
*/
public enum ZipResultType {
FILE("FILE"),
BYTE_ARRAY("BYTE_ARRAY");
private String id;
private ZipResultType(String id) {
this.id = id;
}
/**
* Retrieves the matching enum constant for a provided String representation
* of the {@link ZipResultType}. The provided name must match exactly the identifier as
* used to declare the enum constant.
*
* @param zipResultTypeAsString Name of the enum to convert. Must be not null and not empty.
* @return The enumeration that matches. Returns Null of no match was found.
*
*/
public static ZipResultType convertToZipResultType(String zipResultTypeAsString) {
Assert.hasText(zipResultTypeAsString, "Parameter zipResultTypeAsString must not be null or empty");
for (ZipResultType zipResultType : ZipResultType.values()) {
if (zipResultType.name().equalsIgnoreCase(zipResultTypeAsString)) {
return zipResultType;
}
}
return null;
}
public String getId() {
return id;
}
FILE, BYTE_ARRAY
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -24,8 +24,10 @@ import java.util.zip.Deflater;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.zeroturnaround.zip.ByteSource;
import org.zeroturnaround.zip.FileSource;
import org.zeroturnaround.zip.ZipEntrySource;
import org.springframework.integration.file.FileHeaders;
import org.springframework.integration.transformer.Transformer;
import org.springframework.integration.zip.ZipHeaders;
@@ -34,9 +36,6 @@ import org.springframework.messaging.MessageHandlingException;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.zeroturnaround.zip.ByteSource;
import org.zeroturnaround.zip.FileSource;
import org.zeroturnaround.zip.ZipEntrySource;
/**
* {@link Transformer} implementation that applies a Zip transformation to the
@@ -63,8 +62,6 @@ public class ZipTransformer extends AbstractZipTransformer {
private volatile boolean useFileAttributes = true;
@Autowired Environment env;
/**
* Sets the compression level. Default is {@link Deflater#DEFAULT_COMPRESSION}.
*
@@ -148,7 +145,8 @@ public class ZipTransformer extends AbstractZipTransformer {
for (Object item : (Iterable<?>) payload) {
final ZipEntrySource zipEntrySource = createZipEntrySource(item, lastModifiedDate, baseName + "_" + counter + fileExtension, useFileAttributes);
final ZipEntrySource zipEntrySource = createZipEntrySource(item, lastModifiedDate, baseName + "_"
+ counter + fileExtension, this.useFileAttributes);
if (logger.isDebugEnabled()) {
logger.debug("ZipEntrySource path: '" + zipEntrySource.getPath() + "'");
}
@@ -157,26 +155,30 @@ public class ZipTransformer extends AbstractZipTransformer {
}
}
else {
final ZipEntrySource zipEntrySource = createZipEntrySource(payload, lastModifiedDate, zipEntryName, useFileAttributes);
final ZipEntrySource zipEntrySource =
createZipEntrySource(payload, lastModifiedDate, zipEntryName, this.useFileAttributes);
entries.add(zipEntrySource);
}
final byte[] zippedBytes = SpringZipUtils.pack(entries, this.compressionLevel);
if (ZipResultType.FILE.equals(zipResultType)) {
if (ZipResultType.FILE.equals(this.zipResultType)) {
final File zippedFile = new File(this.workDirectory, zipFileName);
FileCopyUtils.copy(zippedBytes, zippedFile);
zippedData = zippedFile;
}
else if (ZipResultType.BYTE_ARRAY.equals(zipResultType)) {
else if (ZipResultType.BYTE_ARRAY.equals(this.zipResultType)) {
zippedData = zippedBytes;
}
else {
throw new IllegalStateException("Unsupported zipResultType " + zipResultType);
throw new IllegalStateException("Unsupported zipResultType " + this.zipResultType);
}
return this.getMessageBuilderFactory()
.withPayload(zippedData).copyHeaders(message.getHeaders()).setHeader(FileHeaders.FILENAME, zipFileName).build();
return getMessageBuilderFactory()
.withPayload(zippedData)
.copyHeaders(message.getHeaders())
.setHeader(FileHeaders.FILENAME, zipFileName)
.build();
}
catch (Exception e) {
throw new MessageHandlingException(message, "Failed to apply Zip transformation.", e);
@@ -217,13 +219,12 @@ public class ZipTransformer extends AbstractZipTransformer {
bytesToCompress = (byte[]) item;
}
final ZipEntrySource zipEntrySource = new ByteSource(zipEntryName, bytesToCompress, lastModifiedDate.getTime());
return zipEntrySource;
return new ByteSource(zipEntryName, bytesToCompress, lastModifiedDate.getTime());
}
else {
throw new IllegalArgumentException("Unsupported payload type. The only supported payloads are " +
"java.io.File, java.lang.String, and byte[]");
}
}
}

View File

@@ -1,2 +1,2 @@
http\://www.springframework.org/schema/integration/zip/spring-integration-zip-1.0.xsd=org/springframework/integration/config/xml/spring-integration-zip-1.0.xsd
http\://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd=org/springframework/integration/config/xml/spring-integration-zip-1.0.xsd
http\://www.springframework.org/schema/integration/zip/spring-integration-zip-1.0.xsd=org/springframework/integration/zip/config/spring-integration-zip-1.0.xsd
http\://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd=org/springframework/integration/zip/config/spring-integration-zip-1.0.xsd

View File

@@ -1,4 +1,4 @@
# Tooling related information for the integration Zip namespace
http\://www.springframework.org/schema/integration/zip@name=integration Zip Namespace
http\://www.springframework.org/schema/integration/zip@prefix=int-zip
http\://www.springframework.org/schema/integration/zip@icon=org/springframework/integration/config/xml/spring-integration-zip.gif
http\://www.springframework.org/schema/integration/zip@icon=org/springframework/integration/zip/config/spring-integration-zip.gif

View File

@@ -69,39 +69,15 @@
</xsd:element>
<xsd:complexType name="transformerType">
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[Identifies the underlying Spring bean definition (EventDrivenConsumer)]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="input-channel" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[The input channel of the transformer.]]>
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.integration.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="output-channel" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[The channel to which the transformer will send the transformed message.
Optional, because incoming messages can specify a reply channel using the 'replyChannel'
message header value themselves.]]>
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.integration.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attributeGroup ref="integration:inputOutputChannelGroup"/>
<xsd:attribute name="delete-files" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

View File

@@ -12,9 +12,11 @@
*/
package org.springframework.integration.zip.config.xml;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -24,7 +26,8 @@ import java.util.zip.Deflater;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.channel.AbstractMessageChannel;
@@ -38,10 +41,8 @@ import org.springframework.integration.zip.transformer.ZipTransformer;
import org.springframework.util.Assert;
/**
*
* @author Gunnar Hillert
* @since 1.0
*
*/
public class ZipTransformerParserTests {
@@ -52,7 +53,7 @@ public class ZipTransformerParserTests {
setUp("ZipTransformerParserTests.xml", getClass());
EventDrivenConsumer consumer = this.context.getBean("zipTransformerWithDefaults", EventDrivenConsumer.class);
EventDrivenConsumer consumer = this.context.getBean("zipTransformerWithDefaults", EventDrivenConsumer.class);
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
assertEquals("input", inputChannel.getComponentName());
@@ -93,7 +94,7 @@ public class ZipTransformerParserTests {
setUp("ZipTransformerParserTests.xml", getClass());
EventDrivenConsumer consumer = this.context.getBean("zipTransformer", EventDrivenConsumer.class);
EventDrivenConsumer consumer = this.context.getBean("zipTransformer", EventDrivenConsumer.class);
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
assertEquals("input", inputChannel.getComponentName());
@@ -130,30 +131,27 @@ public class ZipTransformerParserTests {
}
@Test
public void testZiptransformerParserWithIncorrectResultType() {
public void testZipTransformerParserWithIncorrectResultType() {
try {
setUp("ZipTransformerParserTestsWithIncorrectResultType.xml", getClass());
setUp("ZipTransformerParserTestsWithIncorrectResultType.xml", getClass());
fail("Expected a BeanDefinitionParsingException to be thrown.");
}
catch (BeanDefinitionParsingException e) {
String expectedErrorMessage = "Unable to convert the provided result-type 'INCORRECT' " +
"to the respective ZipResultType enum.";
assertTrue(String.format("Expected exception message to contain '%s' but got '%s'", expectedErrorMessage, e.getMessage()),
e.getMessage().contains(expectedErrorMessage));
return;
catch (BeanCreationException e) {
assertThat(e.getMessage(), containsString("Failed to convert property value of type [java.lang.String] " +
"to required type [org.springframework.integration.zip.transformer.ZipResultType] "));
}
fail("Expected a BeanDefinitionParsingException to be thrown.");
}
@After
public void tearDown(){
if(context != null){
public void tearDown() {
if (context != null) {
context.close();
}
}
public void setUp(String name, Class<?> cls){
context = new ClassPathXmlApplicationContext(name, cls);
public void setUp(String name, Class<?> cls) {
context = new ClassPathXmlApplicationContext(name, cls);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -17,7 +17,6 @@
package org.springframework.integration.zip.transformer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -31,6 +30,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@@ -43,11 +43,12 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author Gunnar Hillert
* @author Artem Bilan
* @since 1.0
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:org/springframework/integration/zip/transformer/UnZipTransformerTests.xml"})
@ContextConfiguration
public class UnZipTransformerTests {
@Rule
@@ -70,7 +71,7 @@ public class UnZipTransformerTests {
* @throws IOException
*/
@Test
public void unzipSingleFileAsInputstreamToByteArray() throws IOException {
public void unzipSingleFileAsInputStreamToByteArray() throws IOException {
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
final InputStream is = resource.getInputStream();
@@ -142,7 +143,9 @@ public class UnZipTransformerTests {
final File inputFile = new File(this.workDir, "unzipSingleFileToByteArray");
IOUtils.copy(is, new FileOutputStream(inputFile));
FileOutputStream output = new FileOutputStream(inputFile);
IOUtils.copy(is, output);
output.close();
final Message<File> message = MessageBuilder.withPayload(inputFile).build();
@@ -172,7 +175,7 @@ public class UnZipTransformerTests {
* @throws IOException
*/
@Test
public void unzipMultipleFilesAsInputstreamToByteArray() throws IOException {
public void unzipMultipleFilesAsInputStreamToByteArray() throws IOException {
final Resource resource = resourceLoader.getResource("classpath:testzipdata/countries.zip");
final InputStream is = resource.getInputStream();
@@ -228,26 +231,26 @@ public class UnZipTransformerTests {
}
@Test
public void unzipInvalidZipFile() throws FileNotFoundException, IOException, InterruptedException {
public void unzipInvalidZipFile() throws IOException, InterruptedException {
final File fileToUnzip = testFolder.newFile();
File fileToUnzip = testFolder.newFile();
FileUtils.writeStringToFile(fileToUnzip, "hello world");
final UnZipTransformer unZipTransformer = new UnZipTransformer();
UnZipTransformer unZipTransformer = new UnZipTransformer();
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
unZipTransformer.setExpectSingleResult(true);
unZipTransformer.afterPropertiesSet();
final Message<File> message = MessageBuilder.withPayload(fileToUnzip).build();
Message<File> message = MessageBuilder.withPayload(fileToUnzip).build();
try {
unZipTransformer.transform(message);
Assert.fail("Expected a MessagingException to be thrown.");
}
catch (MessagingException e) {
Assert.assertTrue(e.getMessage().contains(String.format("Not a zip file: '%s'.", fileToUnzip.getAbsolutePath())));
return;
Assert.assertTrue(e.getMessage().contains(String.format("Not a zip file: '%s'.",
fileToUnzip.getAbsolutePath())));
}
Assert.fail("Expected a MessagingException to be thrown.");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -35,15 +35,17 @@ import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.messaging.Message;
import org.zeroturnaround.zip.ZipUtil;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.zip.ZipHeaders;
import org.zeroturnaround.zip.ZipUtil;
import org.springframework.messaging.Message;
/**
*
* @author Gunnar Hillert
* @author Artem Bilan
* @since 1.0
*
*/
@@ -59,7 +61,7 @@ public class ZipTransformerTests {
* @throws IOException
*/
@Test
public void zipString() throws FileNotFoundException, IOException {
public void zipString() throws IOException {
final ZipTransformer zipTransformer = new ZipTransformer();
zipTransformer.setBeanFactory(mock(BeanFactory.class));
zipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
@@ -95,7 +97,7 @@ public class ZipTransformerTests {
}
@Test
public void zipStringCollection() throws FileNotFoundException, IOException {
public void zipStringCollection() throws IOException {
final ZipTransformer zipTransformer = new ZipTransformer();
zipTransformer.setBeanFactory(mock(BeanFactory.class));
zipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
@@ -161,10 +163,9 @@ public class ZipTransformerTests {
}
@Test
public void zipStringToFile() throws FileNotFoundException, IOException {
public void zipStringToFile() throws IOException {
final ZipTransformer zipTransformer = new ZipTransformer();
zipTransformer.setBeanFactory(mock(BeanFactory.class));
zipTransformer.setZipResultType(ZipResultType.FILE);
zipTransformer.afterPropertiesSet();
final String stringToCompress = "Hello World";