From 0a5fedcd7a67f9cc36f99a1dc9fa06c300f0b787 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 7 Jan 2016 21:43:15 -0500 Subject: [PATCH] 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 --- spring-integration-zip/README.md | 20 +++--- spring-integration-zip/build.gradle | 58 ++++++++++-------- .../gradle/wrapper/gradle-wrapper.jar | Bin 51017 -> 52271 bytes .../gradle/wrapper/gradle-wrapper.properties | 4 +- spring-integration-zip/publish-maven.gradle | 16 ++--- spring-integration-zip/settings.gradle | 1 + .../xml/AbstractZipTransformerParser.java | 8 ++- .../config/xml/UnZipTransformerParser.java | 28 ++------- .../zip/config/xml/ZipTransformerParser.java | 28 ++------- .../transformer/AbstractZipTransformer.java | 12 ++-- .../zip/transformer/UnZipTransformer.java | 36 ++++++----- .../zip/transformer/ZipResultType.java | 40 +----------- .../zip/transformer/ZipTransformer.java | 37 +++++------ .../main/resources/META-INF/spring.schemas | 4 +- .../main/resources/META-INF/spring.tooling | 2 +- .../config}/spring-integration-zip-1.0.xsd | 32 ++-------- .../config}/spring-integration-zip.gif | Bin .../config/xml/ZipTransformerParserTests.java | 38 ++++++------ ....xml => UnZipTransformerTests-context.xml} | 0 .../transformer/UnZipTransformerTests.java | 31 +++++----- .../zip/transformer/ZipTransformerTests.java | 15 ++--- 21 files changed, 170 insertions(+), 240 deletions(-) create mode 100644 spring-integration-zip/settings.gradle rename spring-integration-zip/src/main/resources/org/springframework/integration/{config/xml => zip/config}/spring-integration-zip-1.0.xsd (79%) rename spring-integration-zip/src/main/resources/org/springframework/integration/{config/xml => zip/config}/spring-integration-zip.gif (100%) rename spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/{UnZipTransformerTests.xml => UnZipTransformerTests-context.xml} (100%) diff --git a/spring-integration-zip/README.md b/spring-integration-zip/README.md index 10fc814..306d04f 100644 --- a/spring-integration-zip/README.md +++ b/spring-integration-zip/README.md @@ -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 \ No newline at end of file +[Zip]: http://en.wikipedia.org/wiki/Zip_%28file_format%29 diff --git a/spring-integration-zip/build.gradle b/spring-integration-zip/build.gradle index 4bbfbc0..255a0d5 100644 --- a/spring-integration-zip/build.gradle +++ b/spring-integration-zip/build.gradle @@ -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" } diff --git a/spring-integration-zip/gradle/wrapper/gradle-wrapper.jar b/spring-integration-zip/gradle/wrapper/gradle-wrapper.jar index 3d0dee6e8edfecc92e04653ec780de06f7b34f8b..30d399d8d2bf522ff5de94bf434a7cc43a9a74b5 100644 GIT binary patch delta 22949 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 diff --git a/spring-integration-zip/gradle/wrapper/gradle-wrapper.properties b/spring-integration-zip/gradle/wrapper/gradle-wrapper.properties index 1330889..785b596 100644 --- a/spring-integration-zip/gradle/wrapper/gradle-wrapper.properties +++ b/spring-integration-zip/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/spring-integration-zip/publish-maven.gradle b/spring-integration-zip/publish-maven.gradle index 6294f70..7bb31f5 100644 --- a/spring-integration-zip/publish-maven.gradle +++ b/spring-integration-zip/publish-maven.gradle @@ -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' } } } diff --git a/spring-integration-zip/settings.gradle b/spring-integration-zip/settings.gradle new file mode 100644 index 0000000..91ffdcc --- /dev/null +++ b/spring-integration-zip/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'spring-integration-zip' diff --git a/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/AbstractZipTransformerParser.java b/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/AbstractZipTransformerParser.java index 578c71b..253e9f7 100644 --- a/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/AbstractZipTransformerParser.java +++ b/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/AbstractZipTransformerParser.java @@ -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); } /** diff --git a/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/UnZipTransformerParser.java b/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/UnZipTransformerParser.java index d7ef757..3d58847 100644 --- a/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/UnZipTransformerParser.java +++ b/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/UnZipTransformerParser.java @@ -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); - } - - } } } diff --git a/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/ZipTransformerParser.java b/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/ZipTransformerParser.java index 45d9b96..b22456f 100644 --- a/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/ZipTransformerParser.java +++ b/spring-integration-zip/src/main/java/org/springframework/integration/zip/config/xml/ZipTransformerParser.java @@ -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); - } - - } } } diff --git a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/AbstractZipTransformer.java b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/AbstractZipTransformer.java index c32f411..38a4b66 100644 --- a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/AbstractZipTransformer.java +++ b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/AbstractZipTransformer.java @@ -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()); diff --git a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/UnZipTransformer.java b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/UnZipTransformer.java index c8ec135..6dd300e 100644 --- a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/UnZipTransformer.java +++ b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/UnZipTransformer.java @@ -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 uncompressedData = new TreeMap(); @@ -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); } } + } diff --git a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipResultType.java b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipResultType.java index 5583c74..291a9fe 100644 --- a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipResultType.java +++ b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipResultType.java @@ -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 } diff --git a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipTransformer.java b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipTransformer.java index f0d124f..92e1553 100644 --- a/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipTransformer.java +++ b/spring-integration-zip/src/main/java/org/springframework/integration/zip/transformer/ZipTransformer.java @@ -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[]"); } } + } diff --git a/spring-integration-zip/src/main/resources/META-INF/spring.schemas b/spring-integration-zip/src/main/resources/META-INF/spring.schemas index 5261bf2..92a75b7 100644 --- a/spring-integration-zip/src/main/resources/META-INF/spring.schemas +++ b/spring-integration-zip/src/main/resources/META-INF/spring.schemas @@ -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 diff --git a/spring-integration-zip/src/main/resources/META-INF/spring.tooling b/spring-integration-zip/src/main/resources/META-INF/spring.tooling index c8c2bdc..990490a 100644 --- a/spring-integration-zip/src/main/resources/META-INF/spring.tooling +++ b/spring-integration-zip/src/main/resources/META-INF/spring.tooling @@ -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 diff --git a/spring-integration-zip/src/main/resources/org/springframework/integration/config/xml/spring-integration-zip-1.0.xsd b/spring-integration-zip/src/main/resources/org/springframework/integration/zip/config/spring-integration-zip-1.0.xsd similarity index 79% rename from spring-integration-zip/src/main/resources/org/springframework/integration/config/xml/spring-integration-zip-1.0.xsd rename to spring-integration-zip/src/main/resources/org/springframework/integration/zip/config/spring-integration-zip-1.0.xsd index f39ad96..23d2546 100644 --- a/spring-integration-zip/src/main/resources/org/springframework/integration/config/xml/spring-integration-zip-1.0.xsd +++ b/spring-integration-zip/src/main/resources/org/springframework/integration/zip/config/spring-integration-zip-1.0.xsd @@ -69,39 +69,15 @@ + + + - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/spring-integration-zip/src/main/resources/org/springframework/integration/config/xml/spring-integration-zip.gif b/spring-integration-zip/src/main/resources/org/springframework/integration/zip/config/spring-integration-zip.gif similarity index 100% rename from spring-integration-zip/src/main/resources/org/springframework/integration/config/xml/spring-integration-zip.gif rename to spring-integration-zip/src/main/resources/org/springframework/integration/zip/config/spring-integration-zip.gif diff --git a/spring-integration-zip/src/test/java/org/springframework/integration/zip/config/xml/ZipTransformerParserTests.java b/spring-integration-zip/src/test/java/org/springframework/integration/zip/config/xml/ZipTransformerParserTests.java index bcc3f6a..fdc6869 100644 --- a/spring-integration-zip/src/test/java/org/springframework/integration/zip/config/xml/ZipTransformerParserTests.java +++ b/spring-integration-zip/src/test/java/org/springframework/integration/zip/config/xml/ZipTransformerParserTests.java @@ -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); } } diff --git a/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests.xml b/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests-context.xml similarity index 100% rename from spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests.xml rename to spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests-context.xml diff --git a/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests.java b/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests.java index 42919ae..1653a04 100644 --- a/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests.java +++ b/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/UnZipTransformerTests.java @@ -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 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 message = MessageBuilder.withPayload(fileToUnzip).build(); + Message 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."); } + } diff --git a/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/ZipTransformerTests.java b/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/ZipTransformerTests.java index 678bf02..4b9632c 100644 --- a/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/ZipTransformerTests.java +++ b/spring-integration-zip/src/test/java/org/springframework/integration/zip/transformer/ZipTransformerTests.java @@ -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";