INTEXT-40 Add ZIP Transformer
* Add zip-transformer * Add unzip-transformer * Add UnZipResultSplitter * Add sample For reference see: https://jira.springsource.org/browse/INTEXT-40
This commit is contained in:
22
spring-integration-zip/src/api/overview.html
Normal file
22
spring-integration-zip/src/api/overview.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<body>
|
||||
This document is the API specification for Spring Integration
|
||||
<hr/>
|
||||
<div id="overviewBody">
|
||||
<p>
|
||||
For further API reference and developer documentation, see the
|
||||
<a href="http://static.springsource.org/spring-integration/reference" target="_top">Spring
|
||||
Integration reference documentation</a>.
|
||||
That documentation contains more detailed, developer-targeted
|
||||
descriptions, with conceptual overviews, definitions of terms,
|
||||
workarounds, and working code examples.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you are interested in commercial training, consultancy, and
|
||||
support for Spring Integration, please visit <a href="http://www.springsource.com" target="_top">
|
||||
http://www.springsource.com</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
15
spring-integration-zip/src/dist/changelog.txt
vendored
Normal file
15
spring-integration-zip/src/dist/changelog.txt
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
Spring Integration Zip Adapter CHANGELOG
|
||||
=========================================
|
||||
|
||||
For the full detailed changelog, see:
|
||||
https://....
|
||||
|
||||
|
||||
Changes in version 1.0 GA (insert date here)
|
||||
https://....
|
||||
|
||||
|
||||
*** GENERAL ***
|
||||
|
||||
Upgraded Spring Framework dependency to ...
|
||||
...
|
||||
201
spring-integration-zip/src/dist/license.txt
vendored
Normal file
201
spring-integration-zip/src/dist/license.txt
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
21
spring-integration-zip/src/dist/notice.txt
vendored
Normal file
21
spring-integration-zip/src/dist/notice.txt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
========================================================================
|
||||
== NOTICE file corresponding to section 4 d of the Apache License, ==
|
||||
== Version 2.0, in this case for the Spring Integration distribution. ==
|
||||
========================================================================
|
||||
|
||||
This product includes software developed by
|
||||
the Apache Software Foundation (http://www.apache.org).
|
||||
|
||||
The end-user documentation included with a redistribution, if any,
|
||||
must include the following acknowledgement:
|
||||
|
||||
"This product includes software developed by the Spring Framework
|
||||
Project (http://www.springframework.org)."
|
||||
|
||||
Alternatively, this acknowledgement may appear in the software itself,
|
||||
if and wherever such third-party acknowledgements normally appear.
|
||||
|
||||
The names "Spring", "Spring Framework", and "Spring Integration" must
|
||||
not be used to endorse or promote products derived from this software
|
||||
without prior written permission. For written permission, please contact
|
||||
enquiries@springsource.com.
|
||||
13
spring-integration-zip/src/dist/readme.txt
vendored
Normal file
13
spring-integration-zip/src/dist/readme.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Spring Integration Zip Adapter
|
||||
-----------------------------------
|
||||
|
||||
To find out what has changed since any earlier releases, see 'changelog.txt'.
|
||||
|
||||
Please consult the documentation located within the 'docs/reference' directory
|
||||
of this release and also visit the official Spring Integration home at
|
||||
http://www.springsource.org/spring-integration
|
||||
|
||||
There you will find links to the forum, issue tracker, and several other resources.
|
||||
|
||||
See https://github.com/SpringSource/spring-integration#readme for additional
|
||||
information including instructions on building from source.
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip;
|
||||
|
||||
/**
|
||||
* Zip adapter specific message headers.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class ZipHeaders {
|
||||
|
||||
private static final String PREFIX = "zip_";
|
||||
|
||||
public static final String ZIP_ENTRY_FILE_NAME = PREFIX + "entryFilename";
|
||||
public static final String ZIP_ENTRY_PATH = PREFIX + "entryPath";
|
||||
public static final String ZIP_ENTRY_LAST_MODIFIED_DATE = PREFIX + "entryLastModifiedDate";
|
||||
|
||||
/** Noninstantiable utility class */
|
||||
private ZipHeaders() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2015 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.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.AbstractTransformerParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for Zip transformer parsers.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class AbstractZipTransformerParser extends AbstractTransformerParser {
|
||||
|
||||
/**
|
||||
* @param element The XML Element to process
|
||||
* @param parserContext The Spring ParserContext
|
||||
* @param builder BeanDefinitionBuilder for constructing Bean Definitions
|
||||
*/
|
||||
@Override
|
||||
protected final void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
String deleteFiles = element.getAttribute("delete-files");
|
||||
if (StringUtils.hasText(deleteFiles)) {
|
||||
builder.addPropertyValue("deleteFiles", deleteFiles);
|
||||
}
|
||||
this.postProcessTransformer(element, parserContext, builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide additional configuration.
|
||||
*
|
||||
* @param element The XML Element to process
|
||||
* @param parserContext The Spring ParserContext
|
||||
* @param builder BeanDefinitionBuilder for constructing Bean Definitions
|
||||
*/
|
||||
protected void postProcessTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.config.xml;
|
||||
|
||||
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
|
||||
* @since 1.0
|
||||
*/
|
||||
public class UnZipTransformerParser extends AbstractZipTransformerParser {
|
||||
|
||||
@Override
|
||||
protected String getTransformerClassName() {
|
||||
return UnZipTransformer.class.getName();
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.config.xml;
|
||||
|
||||
import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
|
||||
|
||||
/**
|
||||
* The namespace handler for the Zip namespace
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
this.registerBeanDefinitionParser("zip-transformer", new ZipTransformerParser());
|
||||
this.registerBeanDefinitionParser("unzip-transformer", new UnZipTransformerParser());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.config.xml;
|
||||
|
||||
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
|
||||
* @since 1.0
|
||||
*/
|
||||
public class ZipTransformerParser extends AbstractZipTransformerParser {
|
||||
|
||||
@Override
|
||||
protected String getTransformerClassName() {
|
||||
return ZipTransformer.class.getName();
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Provides parser classes to provide Xml namespace support for the Zip components.
|
||||
*/
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Root package of the Zip Module.
|
||||
*/
|
||||
package org.springframework.integration.zip;
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.transformer;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.transformer.AbstractTransformer;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for transformers that provide Zip compression.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class AbstractZipTransformer extends AbstractTransformer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ZipTransformer.class);
|
||||
|
||||
protected volatile Charset charset = Charset.defaultCharset();
|
||||
|
||||
protected volatile FileNameGenerator fileNameGenerator;
|
||||
|
||||
protected volatile ZipResultType zipResultType = ZipResultType.FILE;
|
||||
|
||||
protected volatile File workDirectory = new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer");
|
||||
|
||||
protected volatile boolean deleteFiles;
|
||||
|
||||
/**
|
||||
* If the payload is an instance of {@link File}, this property specifies
|
||||
* whether to delete the {@link File} after transformation.
|
||||
* Default is <em>false</em>.
|
||||
*
|
||||
* @param deleteFiles Defaults to <em>false</em> if not set
|
||||
*/
|
||||
public void setDeleteFiles(boolean deleteFiles) {
|
||||
this.deleteFiles = deleteFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the work-directory. The work directory is used when the {@link ZipResultType}
|
||||
* is set to {@link ZipResultType#FILE}. By default this property is set to
|
||||
* the System temporary directory containing a sub-directory "ziptransformer".
|
||||
*
|
||||
* @param workDirectory Must not be null and must not represent a file.
|
||||
*/
|
||||
public void setWorkDirectory(File workDirectory) {
|
||||
Assert.notNull(workDirectory, "workDirectory must not be null.");
|
||||
Assert.isTrue(!workDirectory.isFile(), "The workDirectory specified must not point to a file");
|
||||
this.workDirectory = workDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the format of the data returned after transformation. Available
|
||||
* options are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>File</li>
|
||||
* <li>Byte Array</li>
|
||||
* </ul>
|
||||
*
|
||||
* Defaults to {@link ZipResultType#FILE}.
|
||||
*
|
||||
* @param zipResultType Must not be null
|
||||
*/
|
||||
public void setZipResultType(ZipResultType zipResultType) {
|
||||
Assert.notNull(zipResultType, "The zipResultType must not be empty.");
|
||||
this.zipResultType = zipResultType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() throws Exception {
|
||||
super.onInit();
|
||||
|
||||
if (!workDirectory.exists()) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format("Creating work directory '%s'.", this.workDirectory));
|
||||
}
|
||||
workDirectory.mkdirs();
|
||||
}
|
||||
final DefaultFileNameGenerator defaultFileNameGenerator = new DefaultFileNameGenerator();
|
||||
defaultFileNameGenerator.setBeanFactory(getBeanFactory());
|
||||
defaultFileNameGenerator.setConversionService(getConversionService());
|
||||
this.fileNameGenerator = defaultFileNameGenerator;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message the message and its payload must not be null.
|
||||
*/
|
||||
@Override
|
||||
protected Object doTransform(Message<?> message) throws Exception {
|
||||
Assert.notNull(message, "message must not be null");
|
||||
final Object payload = message.getPayload();
|
||||
Assert.notNull(payload, "payload must not be null");
|
||||
|
||||
return doZipTransform(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method to provide the Zip transformation
|
||||
* logic.
|
||||
*
|
||||
* @param message The message will never be null.
|
||||
* @return The result of the Zip transformation.
|
||||
* @throws Exception Any exception.
|
||||
*/
|
||||
protected abstract Object doZipTransform(Message<?> message) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.transformer;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.zeroturnaround.zip.ZipEntrySource;
|
||||
import org.zeroturnaround.zip.ZipException;
|
||||
|
||||
/**
|
||||
* Once the Spring Integration Zip support matures, we need to contribute the
|
||||
* methods in this utility class back to the ZT Zip project.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class SpringZipUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpringZipUtils.class);
|
||||
|
||||
public static byte[] pack(Collection<ZipEntrySource> entries, int compressionLevel) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Creating byte array from '%s'.",
|
||||
entries));
|
||||
}
|
||||
|
||||
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
pack(entries, outputStream, compressionLevel);
|
||||
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
public static void pack(Collection<ZipEntrySource> entries, File zip,
|
||||
int compressionLevel) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating '" + zip + "' from "
|
||||
+ entries + ".");
|
||||
}
|
||||
|
||||
final FileOutputStream outputStream;
|
||||
try {
|
||||
outputStream = new FileOutputStream(zip);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IllegalStateException(String.format("File '%s' not found.", zip.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
pack(entries, outputStream, compressionLevel);
|
||||
|
||||
}
|
||||
|
||||
private static void pack(Collection<ZipEntrySource> entries, OutputStream outputStream, int compressionLevel) {
|
||||
|
||||
ZipOutputStream out = null;
|
||||
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
|
||||
|
||||
try {
|
||||
out = new ZipOutputStream(bufferedOutputStream);
|
||||
out.setLevel(compressionLevel);
|
||||
for (ZipEntrySource entry : entries) {
|
||||
addEntry(entry, out);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw rethrow(e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void addEntry(ZipEntrySource entry, ZipOutputStream out)
|
||||
throws IOException {
|
||||
out.putNextEntry(entry.getEntry());
|
||||
InputStream in = entry.getInputStream();
|
||||
if (in != null) {
|
||||
try {
|
||||
IOUtils.copy(in, out);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
out.closeEntry();
|
||||
}
|
||||
|
||||
private static ZipException rethrow(IOException e) {
|
||||
throw new ZipException(e);
|
||||
}
|
||||
|
||||
public static void copy(InputStream in, File file) throws IOException {
|
||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
|
||||
try {
|
||||
IOUtils.copy(in, out);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] copy(InputStream in) throws IOException {
|
||||
return IOUtils.toByteArray(in);
|
||||
}
|
||||
|
||||
static boolean isValid(final File file) {
|
||||
ZipFile zipfile = null;
|
||||
try {
|
||||
zipfile = new ZipFile(file);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (zipfile != null) {
|
||||
zipfile.close();
|
||||
zipfile = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.transformer;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
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.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
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZipTransformer extends AbstractZipTransformer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(UnZipTransformer.class);
|
||||
|
||||
private volatile boolean expectSingleResult = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* This parameter indicates that only one result object shall be returned as
|
||||
* a result from the executed Unzip operation. If set to <code>true</code> and
|
||||
* more than 1 element is returned, then that
|
||||
* 1 element is extracted and returned as payload.
|
||||
*
|
||||
* If the result map contains more than 1 element and
|
||||
* {@link #expectSingleResult} is <code>true</code>, then a
|
||||
* {@link MessagingException} is thrown.
|
||||
*
|
||||
* If set to <code>false</code>, the complete result list is returned as the
|
||||
* payload. This is the {@code default}.
|
||||
*
|
||||
* @param expectSingleResult If not set explicitly, will default to false
|
||||
*
|
||||
*/
|
||||
public void setExpectSingleResult(boolean expectSingleResult) {
|
||||
this.expectSingleResult = expectSingleResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doZipTransform(final Message<?> message) throws Exception {
|
||||
|
||||
try {
|
||||
final Object payload = message.getPayload();
|
||||
final Object unzippedData;
|
||||
|
||||
InputStream inputStream = null;
|
||||
|
||||
try {
|
||||
if (payload instanceof File) {
|
||||
final File filePayload = (File) payload;
|
||||
|
||||
if (filePayload.isDirectory()) {
|
||||
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()));
|
||||
}
|
||||
|
||||
inputStream = new FileInputStream(filePayload);
|
||||
}
|
||||
else if (payload instanceof InputStream) {
|
||||
inputStream = (InputStream) payload;
|
||||
}
|
||||
else if (payload instanceof byte[]) {
|
||||
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()));
|
||||
}
|
||||
|
||||
final SortedMap<String, Object> uncompressedData = new TreeMap<String, Object>();
|
||||
|
||||
ZipUtil.iterate(inputStream, new ZipEntryCallback() {
|
||||
|
||||
@Override
|
||||
public void process(InputStream zipEntryInputStream, ZipEntry zipEntry) throws IOException {
|
||||
|
||||
final String zipEntryName = zipEntry.getName();
|
||||
final long zipEntryTime = zipEntry.getTime();
|
||||
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'",
|
||||
zipEntryName, zipEntryTime, zipEntryCompressedSize, type));
|
||||
}
|
||||
|
||||
if (ZipResultType.FILE.equals(zipResultType)) {
|
||||
final File tempDir = new File(workDirectory, message.getHeaders().getId().toString());
|
||||
tempDir.mkdirs();
|
||||
final File destinationFile = new File(tempDir, zipEntryName);
|
||||
|
||||
if (zipEntry.isDirectory()) {
|
||||
destinationFile.mkdirs();
|
||||
}
|
||||
else {
|
||||
SpringZipUtils.copy(zipEntryInputStream, destinationFile);
|
||||
uncompressedData.put(zipEntryName, destinationFile);
|
||||
}
|
||||
}
|
||||
else if (ZipResultType.BYTE_ARRAY.equals(zipResultType)) {
|
||||
if (!zipEntry.isDirectory()) {
|
||||
byte[] data = IOUtils.toByteArray(zipEntryInputStream);
|
||||
uncompressedData.put(zipEntryName, data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Unsupported zipResultType " + zipResultType);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (uncompressedData.isEmpty()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("No data unzipped from payload with message Id " + message.getHeaders().getId());
|
||||
}
|
||||
unzippedData = null;
|
||||
}
|
||||
else {
|
||||
|
||||
if (this.expectSingleResult) {
|
||||
if (uncompressedData.size() == 1) {
|
||||
unzippedData = uncompressedData.values().iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new MessagingException(message,
|
||||
String.format("The UnZip operation extracted %s "
|
||||
+ "result objects but expectSingleResult was 'true'.", uncompressedData.size()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
unzippedData = uncompressedData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (payload instanceof File && this.deleteFiles) {
|
||||
final File filePayload = (File) payload;
|
||||
if (!filePayload.delete() && logger.isWarnEnabled()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("failed to delete File '" + filePayload + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
return unzippedData;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MessageHandlingException(message, "Failed to apply Zip transformation.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2015 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.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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.transformer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
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.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.transformer.Transformer;
|
||||
import org.springframework.integration.zip.ZipHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
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
|
||||
* message payload. Keep in mind that Zip entry timestamps are recorded only to
|
||||
* two 2 second precision:
|
||||
*
|
||||
* See also: http://mindprod.com/jgloss/zip.html
|
||||
*
|
||||
* If you want to generate Zip files larger than {@code 4GB}, you must use Java 7:
|
||||
*
|
||||
* See also: https://blogs.oracle.com/xuemingshen/entry/zip64_support_for_4g_zipfile
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipTransformer extends AbstractZipTransformer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ZipTransformer.class);
|
||||
|
||||
private static final String ZIP_EXTENSION = ".zip";
|
||||
|
||||
private volatile int compressionLevel = Deflater.DEFAULT_COMPRESSION;
|
||||
|
||||
private volatile boolean useFileAttributes = true;
|
||||
|
||||
@Autowired Environment env;
|
||||
|
||||
/**
|
||||
* Sets the compression level. Default is {@link Deflater#DEFAULT_COMPRESSION}.
|
||||
*
|
||||
* @param compressionLevel Must be an integer value from 0-9.
|
||||
*/
|
||||
public void setCompressionLevel(int compressionLevel) {
|
||||
Assert.isTrue(compressionLevel >= 0 && compressionLevel <= 9, "Acceptable levels are 0-9");
|
||||
this.compressionLevel = compressionLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the name of the file shall be used for the
|
||||
* zip entry.
|
||||
*
|
||||
* @param useFileAttributes Defaults to true if not set explicitly
|
||||
*/
|
||||
public void setUseFileAttributes(boolean useFileAttributes) {
|
||||
this.useFileAttributes = useFileAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The payload may encompass the following types:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link File}
|
||||
*...<li>{@link String}
|
||||
*...<li>byte[]
|
||||
*...<li>{@link Iterable}
|
||||
* </ul>
|
||||
*
|
||||
* When providing an {@link Iterable}, nested Iterables are not supported. However,
|
||||
* payloads can be of of any of the other supported types.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected Object doZipTransform(Message<?> message) throws Exception {
|
||||
|
||||
try {
|
||||
|
||||
final Object payload = message.getPayload();
|
||||
final Object zippedData;
|
||||
final String baseFileName = this.fileNameGenerator.generateFileName(message);
|
||||
|
||||
final String zipEntryName;
|
||||
final String zipFileName;
|
||||
|
||||
if (message.getHeaders().containsKey(ZipHeaders.ZIP_ENTRY_FILE_NAME)) {
|
||||
zipEntryName = (String) message.getHeaders().get(ZipHeaders.ZIP_ENTRY_FILE_NAME);
|
||||
}
|
||||
else {
|
||||
zipEntryName = baseFileName;
|
||||
}
|
||||
|
||||
if (message.getHeaders().containsKey(FileHeaders.FILENAME)) {
|
||||
zipFileName = baseFileName;
|
||||
}
|
||||
else {
|
||||
zipFileName = baseFileName + ZIP_EXTENSION;
|
||||
}
|
||||
|
||||
final Date lastModifiedDate;
|
||||
|
||||
if (message.getHeaders().containsKey(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE)) {
|
||||
lastModifiedDate = (Date) message.getHeaders().get(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE);
|
||||
}
|
||||
else {
|
||||
lastModifiedDate = new Date();
|
||||
}
|
||||
|
||||
java.util.List<ZipEntrySource> entries = new ArrayList<ZipEntrySource>();
|
||||
|
||||
if (payload instanceof Iterable<?>) {
|
||||
int counter = 1;
|
||||
|
||||
String baseName = FilenameUtils.getBaseName(zipEntryName);
|
||||
String fileExtension = FilenameUtils.getExtension(zipEntryName);
|
||||
|
||||
if (StringUtils.hasText(fileExtension)) {
|
||||
fileExtension = FilenameUtils.EXTENSION_SEPARATOR_STR + fileExtension;
|
||||
}
|
||||
|
||||
for (Object item : (Iterable<?>) payload) {
|
||||
|
||||
final ZipEntrySource zipEntrySource = createZipEntrySource(item, lastModifiedDate, baseName + "_" + counter + fileExtension, useFileAttributes);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ZipEntrySource path: '" + zipEntrySource.getPath() + "'");
|
||||
}
|
||||
entries.add(zipEntrySource);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
final ZipEntrySource zipEntrySource = createZipEntrySource(payload, lastModifiedDate, zipEntryName, useFileAttributes);
|
||||
entries.add(zipEntrySource);
|
||||
}
|
||||
|
||||
final byte[] zippedBytes = SpringZipUtils.pack(entries, this.compressionLevel);
|
||||
|
||||
if (ZipResultType.FILE.equals(zipResultType)) {
|
||||
final File zippedFile = new File(this.workDirectory, zipFileName);
|
||||
FileCopyUtils.copy(zippedBytes, zippedFile);
|
||||
zippedData = zippedFile;
|
||||
}
|
||||
else if (ZipResultType.BYTE_ARRAY.equals(zipResultType)) {
|
||||
zippedData = zippedBytes;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Unsupported zipResultType " + zipResultType);
|
||||
}
|
||||
|
||||
return this.getMessageBuilderFactory()
|
||||
.withPayload(zippedData).copyHeaders(message.getHeaders()).setHeader(FileHeaders.FILENAME, zipFileName).build();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MessageHandlingException(message, "Failed to apply Zip transformation.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ZipEntrySource createZipEntrySource(Object item,
|
||||
Date lastModifiedDate, String zipEntryName, boolean useFileAttributes) {
|
||||
|
||||
if (item instanceof File) {
|
||||
final File filePayload = (File) item;
|
||||
|
||||
final String fileName = useFileAttributes ? filePayload.getName() : zipEntryName;
|
||||
|
||||
if (((File) item).isDirectory()) {
|
||||
throw new UnsupportedOperationException("Zipping of directories is not supported.");
|
||||
}
|
||||
|
||||
final FileSource fileSource = new FileSource(fileName, filePayload);
|
||||
|
||||
if (this.deleteFiles) {
|
||||
if (!filePayload.delete() && logger.isWarnEnabled()) {
|
||||
logger.warn("failed to delete File '" + filePayload + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return fileSource;
|
||||
|
||||
}
|
||||
else if (item instanceof byte[] || item instanceof String) {
|
||||
|
||||
byte[] bytesToCompress = null;
|
||||
|
||||
if (item instanceof String) {
|
||||
bytesToCompress = ((String) item).getBytes(this.charset);
|
||||
}
|
||||
else {
|
||||
bytesToCompress = (byte[]) item;
|
||||
}
|
||||
|
||||
final ZipEntrySource zipEntrySource = new ByteSource(zipEntryName, bytesToCompress, lastModifiedDate.getTime());
|
||||
|
||||
return zipEntrySource;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unsupported payload type. The only supported payloads are " +
|
||||
"java.io.File, java.lang.String, and byte[]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.transformer.splitter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.zip.ZipHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZipResultSplitter {
|
||||
|
||||
public List<Message<Object>> splitUnzippedMap(Map<String, Object> unzippedEntries) {
|
||||
|
||||
final List<Message<Object>> messages = new ArrayList<Message<Object>>(unzippedEntries.size());
|
||||
|
||||
for (Map.Entry<String, Object> entry : unzippedEntries.entrySet()) {
|
||||
final String path = FilenameUtils.getPath(entry.getKey());
|
||||
final String filename = FilenameUtils.getName(entry.getKey());
|
||||
final Message<Object> splitMessage = MessageBuilder.withPayload(entry.getValue())
|
||||
.setHeader(FileHeaders.FILENAME, filename)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_PATH, path).build();
|
||||
messages.add(splitMessage);
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
http\://www.springframework.org/schema/integration/zip=org.springframework.integration.zip.config.xml.ZipNamespaceHandler
|
||||
@@ -0,0 +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
|
||||
@@ -0,0 +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
|
||||
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/integration/zip"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
targetNamespace="http://www.springframework.org/schema/integration/zip"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/integration"
|
||||
schemaLocation="http://www.springframework.org/schema/integration/spring-integration.xsd" />
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for the Spring Integration
|
||||
Zip Adapter.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="zip-transformer">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Creates a Transformer that compresses message
|
||||
payloads using Zip compressions. The following payload types are
|
||||
supported:
|
||||
|
||||
- java.io.File
|
||||
- byte[]
|
||||
- String
|
||||
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="transformerType">
|
||||
<xsd:attribute name="compression-level" type="xsd:integer"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Sets the compression level. Default is
|
||||
java.util.zip.Deflater.DEFAULT_COMPRESSION
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="unzip-transformer">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Creates a Transformer that uncompresses message
|
||||
payloads using Zip compressions. The following payload types are
|
||||
supported:
|
||||
|
||||
- java.io.File
|
||||
- byte[]
|
||||
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="transformerType">
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="transformerType">
|
||||
<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:attribute name="delete-files" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[If the payload is an instance of {@link File}, this
|
||||
attribute specifies whether to delete the {@link File} after
|
||||
transformation. The default is 'false'.]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expect-single-result" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[If set to 'true', this property indicates
|
||||
that only one result object shall be returned as a result
|
||||
from the executed Unzip operation. Defaults to 'false'.]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="result-type" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines the format of the data returned after
|
||||
transformation. Available options are:
|
||||
- File
|
||||
- Byte Array
|
||||
|
||||
Depending on the used input format, not all
|
||||
options may be applicable.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="resultType xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="resultType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="BYTE_ARRAY" />
|
||||
<xsd:enumeration value="FILE" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 539 B |
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xmlns:int-file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
|
||||
<int:chain input-channel="input" output-channel="out">
|
||||
<int-zip:unzip-transformer result-type="BYTE_ARRAY"/>
|
||||
<int:splitter method="splitUnzippedMap">
|
||||
<bean class="org.springframework.integration.zip.transformer.splitter.UnZipResultSplitter"/>
|
||||
</int:splitter>
|
||||
</int:chain>
|
||||
|
||||
<int:channel id="out">
|
||||
<int:interceptors>
|
||||
<int:wire-tap channel="logger"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
|
||||
<int:logging-channel-adapter id="logger" log-full-message="true" level="WARN"/>
|
||||
|
||||
<int-file:outbound-channel-adapter id="write-file" channel="out" directory-expression="'${workDir}/' + headers.zip_entryPath" auto-create-directory="true"/>
|
||||
|
||||
<context:property-placeholder properties-ref="properties"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZip2FileTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
private ResourceLoader resourceLoader;
|
||||
private MessageChannel input;
|
||||
|
||||
private static final Properties properties = new Properties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
private File workDir;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
this.workDir = testFolder.newFolder();
|
||||
properties.put("workDir", workDir);
|
||||
System.out.print(this.workDir.getAbsolutePath());
|
||||
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
context.register(ContextConfiguration.class);
|
||||
context.refresh();
|
||||
input = context.getBean("input", MessageChannel.class);
|
||||
resourceLoader = context;
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void unZipWithOneEntry() throws Exception {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
byte[] zipdata = IOUtils.toByteArray(is);
|
||||
|
||||
final Message<byte[]> message = MessageBuilder.withPayload(zipdata).build();
|
||||
|
||||
input.send(message);
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
|
||||
File fileInWorkDir = this.workDir.listFiles()[0];
|
||||
|
||||
Assert.assertTrue(fileInWorkDir.isFile());
|
||||
Assert.assertEquals("single.txt", fileInWorkDir.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unZipWithMultipleEntries() throws Exception {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/countries.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
byte[] zipdata = IOUtils.toByteArray(is);
|
||||
|
||||
final Message<byte[]> message = MessageBuilder.withPayload(zipdata).build();
|
||||
|
||||
input.send(message);
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 4);
|
||||
|
||||
File[] files = this.workDir.listFiles();
|
||||
|
||||
boolean continents = false;
|
||||
boolean de = false;
|
||||
boolean fr = false;
|
||||
boolean pl = false;
|
||||
|
||||
for (File file : files) {
|
||||
if (file.getName().equals("continents")) {
|
||||
continents = true;
|
||||
Assert.assertTrue(file.isDirectory());
|
||||
Assert.assertTrue(file.list().length == 2);
|
||||
}
|
||||
if (file.getName().equals("de.txt")) {
|
||||
de = true;
|
||||
Assert.assertTrue(file.isFile());
|
||||
}
|
||||
if (file.getName().equals("fr.txt")) {
|
||||
fr = true;
|
||||
Assert.assertTrue(file.isFile());
|
||||
}
|
||||
if (file.getName().equals("pl.txt")) {
|
||||
pl = true;
|
||||
Assert.assertTrue(file.isFile());
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue(continents);
|
||||
Assert.assertTrue(de);
|
||||
Assert.assertTrue(fr);
|
||||
Assert.assertTrue(pl);
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("classpath:org/springframework/integration/zip/UnZip2FileTests-context.xml")
|
||||
public static class ContextConfiguration {
|
||||
|
||||
@Bean
|
||||
Properties properties() throws IOException {
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xmlns:int-file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<int:channel id="input">
|
||||
</int:channel>
|
||||
|
||||
<int-zip:zip-transformer input-channel="input" output-channel="write-file" result-type="BYTE_ARRAY"/>
|
||||
<int-file:outbound-channel-adapter id="write-file" directory="${workDir}" auto-create-directory="true"/>
|
||||
|
||||
<context:property-placeholder properties-ref="properties"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class Zip2FileTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
private MessageChannel input;
|
||||
|
||||
private static final Properties properties = new Properties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
private File workDir;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
this.workDir = testFolder.newFolder();
|
||||
properties.put("workDir", workDir);
|
||||
System.out.print(this.workDir.getAbsolutePath());
|
||||
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
context.register(ContextConfiguration.class);
|
||||
context.refresh();
|
||||
input = context.getBean("input", MessageChannel.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringWithDefaultFileName() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
final Message<String> message = MessageBuilder.withPayload("Zip me up.").build();
|
||||
|
||||
input.send(message);
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
|
||||
File fileInWorkDir = this.workDir.listFiles()[0];
|
||||
|
||||
Assert.assertTrue(fileInWorkDir.isFile());
|
||||
Assert.assertTrue(fileInWorkDir.getName().contains(message.getHeaders().getId().toString()));
|
||||
Assert.assertTrue("The created file should have a 'zip' file extension.", fileInWorkDir.getName().endsWith(".zip"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringWithExplicitFileName() throws FileNotFoundException, IOException, InterruptedException {
|
||||
input.send(MessageBuilder.withPayload("Zip me up.").setHeader(FileHeaders.FILENAME, "zipString.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("zipString.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipBytesWithExplicitFileName() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
input.send(MessageBuilder.withPayload("Zip me up.".getBytes()).setHeader(FileHeaders.FILENAME, "zipString.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("zipString.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipFile() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
final File fileToCompress = testFolder.newFile();
|
||||
FileUtils.writeStringToFile(fileToCompress, "hello world");
|
||||
|
||||
input.send(MessageBuilder.withPayload(fileToCompress).build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals(fileToCompress.getName() + ".zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipIterableWithMultipleStrings() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
String stringToCompress1 = "String1";
|
||||
String stringToCompress2 = "String2";
|
||||
String stringToCompress3 = "String3";
|
||||
String stringToCompress4 = "String4";
|
||||
|
||||
final List<String> stringsToCompress = new ArrayList<String>(4);
|
||||
|
||||
stringsToCompress.add(stringToCompress1);
|
||||
stringsToCompress.add(stringToCompress2);
|
||||
stringsToCompress.add(stringToCompress3);
|
||||
stringsToCompress.add(stringToCompress4);
|
||||
|
||||
input.send(MessageBuilder.withPayload(stringsToCompress).setHeader(FileHeaders.FILENAME, "zipWith4Strings.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("zipWith4Strings.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipIterableWithDifferentTypes() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
String stringToCompress = "String1";
|
||||
byte[] bytesToCompress = "String2".getBytes();
|
||||
final File fileToCompress = testFolder.newFile();
|
||||
FileUtils.writeStringToFile(fileToCompress, "hello world");
|
||||
|
||||
final List<Object> objectsToCompress = new ArrayList<Object>(3);
|
||||
|
||||
objectsToCompress.add(stringToCompress);
|
||||
objectsToCompress.add(bytesToCompress);
|
||||
objectsToCompress.add(fileToCompress);
|
||||
|
||||
input.send(MessageBuilder.withPayload(objectsToCompress).setHeader(FileHeaders.FILENAME, "objects-to-compress.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("objects-to-compress.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("classpath:org/springframework/integration/zip/Zip2FileTests-context.xml")
|
||||
public static class ContextConfiguration {
|
||||
|
||||
@Bean
|
||||
Properties properties() throws IOException {
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.transformer.MessageTransformingHandler;
|
||||
import org.springframework.integration.zip.transformer.UnZipTransformer;
|
||||
import org.springframework.integration.zip.transformer.ZipResultType;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZipTransformerParserTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testUnZiptransformerParserWithDefaults() {
|
||||
|
||||
setUp("UnZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("unzipTransformerWithDefaults", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final UnZipTransformer unZipTransformer = TestUtils.getPropertyValue(handler, "transformer", UnZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(unZipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(unZipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(unZipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(unZipTransformer, "workDirectory", File.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(unZipTransformer, "deleteFiles", Boolean.class);
|
||||
final Boolean expectSingleResult = TestUtils.getPropertyValue(unZipTransformer, "expectSingleResult", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(deleteFiles);
|
||||
assertNotNull(expectSingleResult);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.FILE, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertFalse("By default the 'deleteFiles' property should be false.", deleteFiles);
|
||||
assertFalse("The 'expectSingleResult' property should be false.", expectSingleResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnZiptransformerParserWithExplicitSettings() {
|
||||
|
||||
setUp("UnZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("unzipTransformer", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final UnZipTransformer unZipTransformer = TestUtils.getPropertyValue(handler, "transformer", UnZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(unZipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(unZipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(unZipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(unZipTransformer, "workDirectory", File.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(unZipTransformer, "deleteFiles", Boolean.class);
|
||||
final Boolean expectSingleResult = TestUtils.getPropertyValue(unZipTransformer, "expectSingleResult", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(deleteFiles);
|
||||
assertNotNull(expectSingleResult);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.FILE, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertTrue("The 'deleteFiles' property should be true.", deleteFiles);
|
||||
assertTrue("The 'expectSingleResult' property should be true.", expectSingleResult);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown(){
|
||||
if(context != null){
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setUp(String name, Class<?> cls){
|
||||
context = new ClassPathXmlApplicationContext(name, cls);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
<int:channel id="output"/>
|
||||
|
||||
<int-zip:unzip-transformer id="unzipTransformer"
|
||||
delete-files="true" input-channel="input" output-channel="output"
|
||||
result-type="FILE" expect-single-result="true"/>
|
||||
|
||||
<int-zip:unzip-transformer id="unzipTransformerWithDefaults"
|
||||
input-channel="input" output-channel="output" />
|
||||
</beans>
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.transformer.MessageTransformingHandler;
|
||||
import org.springframework.integration.zip.transformer.ZipResultType;
|
||||
import org.springframework.integration.zip.transformer.ZipTransformer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipTransformerParserTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testZiptransformerParserWithDefaults() {
|
||||
|
||||
setUp("ZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("zipTransformerWithDefaults", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final ZipTransformer zipTransformer = TestUtils.getPropertyValue(handler, "transformer", ZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(zipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(zipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(zipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(zipTransformer, "workDirectory", File.class);
|
||||
final Integer compressionLevel = TestUtils.getPropertyValue(zipTransformer, "compressionLevel", Integer.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(zipTransformer, "deleteFiles", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(compressionLevel);
|
||||
assertNotNull(deleteFiles);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.FILE, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertEquals(Integer.valueOf(Deflater.DEFAULT_COMPRESSION), Integer.valueOf(compressionLevel));
|
||||
assertFalse("By default the 'deleteFiles' property should be false.", deleteFiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZiptransformerParserWithExplicitSettings() {
|
||||
|
||||
setUp("ZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("zipTransformer", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final ZipTransformer zipTransformer = TestUtils.getPropertyValue(handler, "transformer", ZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(zipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(zipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(zipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(zipTransformer, "workDirectory", File.class);
|
||||
final Integer compressionLevel = TestUtils.getPropertyValue(zipTransformer, "compressionLevel", Integer.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(zipTransformer, "deleteFiles", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(compressionLevel);
|
||||
assertNotNull(deleteFiles);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.BYTE_ARRAY, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertEquals(Integer.valueOf(2), Integer.valueOf(compressionLevel));
|
||||
assertTrue("The 'deleteFiles' property should be true.", deleteFiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZiptransformerParserWithIncorrectResultType() {
|
||||
|
||||
try {
|
||||
setUp("ZipTransformerParserTestsWithIncorrectResultType.xml", getClass());
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
fail("Expected a BeanDefinitionParsingException to be thrown.");
|
||||
}
|
||||
@After
|
||||
public void tearDown(){
|
||||
if(context != null){
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setUp(String name, Class<?> cls){
|
||||
context = new ClassPathXmlApplicationContext(name, cls);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
<int:channel id="output"/>
|
||||
|
||||
<int-zip:zip-transformer id="zipTransformer" compression-level="2"
|
||||
delete-files="true" input-channel="input" output-channel="output"
|
||||
result-type="BYTE_ARRAY"/>
|
||||
|
||||
<int-zip:zip-transformer id="zipTransformerWithDefaults"
|
||||
input-channel="input" output-channel="output" />
|
||||
</beans>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
<int:channel id="output"/>
|
||||
|
||||
<int-zip:zip-transformer id="zipTransformer" compression-level="2"
|
||||
delete-files="true" input-channel="input" output-channel="output"
|
||||
result-type="INCORRECT"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.transformer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
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;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({"classpath:org/springframework/integration/zip/transformer/UnZipTransformerTests.xml"})
|
||||
public class UnZipTransformerTests {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
private File workDir;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
this.workDir = testFolder.newFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* UnCompress a ZIP archive containing a single file only. The result will be
|
||||
* a byte array.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipSingleFileAsInputstreamToByteArray() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final Message<InputStream> message = MessageBuilder.withPayload(is).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 1);
|
||||
Assert.assertEquals("Spring Integration Rocks!", new String(unzippedData.values().iterator().next()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipSingleFileToByteArray() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final File inputFile = new File(this.workDir, "unzipSingleFileToByteArray");
|
||||
|
||||
IOUtils.copy(is, new FileOutputStream(inputFile));
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(inputFile).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 1);
|
||||
Assert.assertTrue(inputFile.exists());
|
||||
Assert.assertEquals("Spring Integration Rocks!", new String(unzippedData.values().iterator().next()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipSingleFileToByteArrayWithDeleteFilesTrue() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final File inputFile = new File(this.workDir, "unzipSingleFileToByteArray");
|
||||
|
||||
IOUtils.copy(is, new FileOutputStream(inputFile));
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(inputFile).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.setDeleteFiles(true);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 1);
|
||||
Assert.assertFalse(inputFile.exists());
|
||||
Assert.assertEquals("Spring Integration Rocks!", new String(unzippedData.values().iterator().next()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* UnCompress a ZIP archive containing multiple files. The result will be
|
||||
* a collection of files.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipMultipleFilesAsInputstreamToByteArray() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/countries.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final Message<InputStream> message = MessageBuilder.withPayload(is).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 5);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* UnCompress a ZIP archive containing multiple files. The result will be
|
||||
* a collection of files.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipMultipleFilesAsInputstreamWithExpectSingleResultTrue() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/countries.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final Message<InputStream> message = MessageBuilder.withPayload(is).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.setExpectSingleResult(true);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
unZipTransformer.transform(message);
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
Assert.assertTrue(e.getMessage().contains("The UnZip operation extracted "
|
||||
+ "5 result objects but expectSingleResult was 'true'."));
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.fail("Expected a MessagingException to be thrown.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unzipInvalidZipFile() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
final File fileToUnzip = testFolder.newFile();
|
||||
FileUtils.writeStringToFile(fileToUnzip, "hello world");
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.setExpectSingleResult(true);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(fileToUnzip).build();
|
||||
|
||||
try {
|
||||
unZipTransformer.transform(message);
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
Assert.assertTrue(e.getMessage().contains(String.format("Not a zip file: '%s'.", fileToUnzip.getAbsolutePath())));
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.fail("Expected a MessagingException to be thrown.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright 2015 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.zip.transformer;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.zip.ZipHeaders;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipTransformerTests {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
/**
|
||||
* Compress a simple String. The result will be a byte array.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void zipString() throws FileNotFoundException, IOException {
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final String stringToCompress = "Hello World";
|
||||
|
||||
final Date fileDate = new Date();
|
||||
|
||||
final Message<String> message = MessageBuilder.withPayload(stringToCompress)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_FILE_NAME, "test.txt")
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE, fileDate)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Object resultPayload = result.getPayload();
|
||||
|
||||
Assert.assertTrue("Expected payload to be an instance of byte but was "
|
||||
+ resultPayload.getClass().getName(), resultPayload instanceof byte[]);
|
||||
|
||||
final File temporaryTestDirectory = testFolder.newFolder();
|
||||
|
||||
ZipUtil.unpack(new ByteArrayInputStream((byte[]) resultPayload), temporaryTestDirectory);
|
||||
|
||||
final File unzippedEntry = new File(temporaryTestDirectory, "test.txt");
|
||||
Assert.assertTrue(unzippedEntry.exists());
|
||||
Assert.assertTrue(unzippedEntry.isFile());
|
||||
|
||||
//See http://stackoverflow.com/questions/3725662/what-is-the-earliest-timestamp-value-that-is-supported-in-zip-file-format
|
||||
Assert.assertTrue((fileDate.getTime() - 3000) < unzippedEntry.lastModified());
|
||||
Assert.assertTrue((fileDate.getTime() + 3000) > unzippedEntry.lastModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringCollection() throws FileNotFoundException, IOException {
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final String string1ToCompress = "Cartman";
|
||||
final String string2ToCompress = "Kenny";
|
||||
final String string3ToCompress = "Butters";
|
||||
|
||||
final List<String> strings = new ArrayList<String>(3);
|
||||
|
||||
strings.add(string1ToCompress);
|
||||
strings.add(string2ToCompress);
|
||||
strings.add(string3ToCompress);
|
||||
|
||||
final Date fileDate = new Date();
|
||||
|
||||
final Message<List<String>> message = MessageBuilder.withPayload(strings)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_FILE_NAME, "test.txt")
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE, fileDate)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Object resultPayload = result.getPayload();
|
||||
|
||||
Assert.assertTrue("Expected payload to be an instance of byte but was "
|
||||
+ resultPayload.getClass().getName(), resultPayload instanceof byte[]);
|
||||
|
||||
final File temporaryTestDirectory = testFolder.newFolder();
|
||||
|
||||
ZipUtil.unpack(new ByteArrayInputStream((byte[]) resultPayload), temporaryTestDirectory);
|
||||
|
||||
File[] files = temporaryTestDirectory.listFiles();
|
||||
|
||||
Assert.assertTrue(files.length >= 3);
|
||||
|
||||
final Set<String> expectedFileNames = new HashSet<String>();
|
||||
|
||||
expectedFileNames.add("test_1.txt");
|
||||
expectedFileNames.add("test_2.txt");
|
||||
expectedFileNames.add("test_3.txt");
|
||||
|
||||
for (File file : files) {
|
||||
|
||||
if (file.getName().startsWith("test")) {
|
||||
Assert.assertTrue(file.exists());
|
||||
Assert.assertTrue(file.isFile());
|
||||
|
||||
//See http://stackoverflow.com/questions/3725662/what-is-the-earliest-timestamp-value-that-is-supported-in-zip-file-format
|
||||
Assert.assertTrue(String.format("%s : %s", fileDate.getTime() - 4000, file.lastModified()), (fileDate.getTime() - 4000) < file.lastModified());
|
||||
Assert.assertTrue((fileDate.getTime() + 4000) > file.lastModified());
|
||||
|
||||
Assert.assertTrue(
|
||||
String.format("File '%s' did not end with '.txt'.", file.getName()),
|
||||
file.getName().endsWith(".txt"));
|
||||
|
||||
Assert.assertTrue(expectedFileNames.contains(file.getName()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringToFile() throws FileNotFoundException, IOException {
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.setZipResultType(ZipResultType.FILE);
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final String stringToCompress = "Hello World";
|
||||
|
||||
final String zipEntryFileName = "test.txt";
|
||||
final Message<String> message = MessageBuilder.withPayload(stringToCompress)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_FILE_NAME, zipEntryFileName)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Assert.assertTrue("Expected payload to be an instance of file but was "
|
||||
+ result.getPayload().getClass().getName(), result.getPayload() instanceof File);
|
||||
|
||||
final File payload = (File) result.getPayload();
|
||||
|
||||
System.out.println(payload.getAbsolutePath());
|
||||
|
||||
Assert.assertEquals(message.getHeaders().getId().toString() + ".msg.zip", payload.getName());
|
||||
Assert.assertTrue(SpringZipUtils.isValid(payload));
|
||||
|
||||
final byte[] zipEntryData = ZipUtil.unpackEntry(payload, "test.txt");
|
||||
|
||||
Assert.assertNotNull("Entry '" + zipEntryFileName + "' was not found.", zipEntryData);
|
||||
Assert.assertTrue("Hello World".equals(new String(zipEntryData)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipFile() throws IOException {
|
||||
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final File testFile = createTestFile(10);
|
||||
|
||||
Assert.assertTrue(testFile.exists());
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(testFile).build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Assert.assertTrue(result.getPayload() instanceof File);
|
||||
|
||||
final File payload = (File) result.getPayload();
|
||||
|
||||
Assert.assertEquals(testFile.getName() + ".zip", payload.getName());
|
||||
Assert.assertTrue(SpringZipUtils.isValid(payload));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipCollection() throws IOException {
|
||||
|
||||
final File testFile1 = createTestFile(1);
|
||||
final File testFile2 = createTestFile(2);
|
||||
final File testFile3 = createTestFile(3);
|
||||
final File testFile4 = createTestFile(4);
|
||||
|
||||
Assert.assertTrue(testFile1.exists());
|
||||
Assert.assertTrue(testFile2.exists());
|
||||
Assert.assertTrue(testFile3.exists());
|
||||
Assert.assertTrue(testFile4.exists());
|
||||
|
||||
final Collection<File> files = new ArrayList<File>();
|
||||
|
||||
files.add(testFile1);
|
||||
files.add(testFile2);
|
||||
files.add(testFile3);
|
||||
files.add(testFile4);
|
||||
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<Collection<File>> message = MessageBuilder.withPayload(files)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Assert.assertTrue(result.getPayload() instanceof File);
|
||||
|
||||
final File outputZipFile = (File) result.getPayload();
|
||||
|
||||
Assert.assertTrue(outputZipFile.exists());
|
||||
Assert.assertTrue(outputZipFile.isFile());
|
||||
Assert.assertTrue(outputZipFile.getName().endsWith("zip"));
|
||||
Assert.assertTrue(SpringZipUtils.isValid(outputZipFile));
|
||||
|
||||
}
|
||||
|
||||
private File createTestFile(int size) throws IOException {
|
||||
|
||||
final File temporaryTestDirectory = testFolder.newFolder();
|
||||
|
||||
final File testFile = new File(temporaryTestDirectory, "testdata" + UUID.randomUUID().toString() + ".data");
|
||||
|
||||
RandomAccessFile f = null;
|
||||
try {
|
||||
f = new RandomAccessFile(testFile, "rw");
|
||||
f.setLength(size * 1024 * 1024);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (f != null) {
|
||||
f.close();
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
return testFile;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
log4j.rootCategory=WARN, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n
|
||||
|
||||
log4j.category.org.springframework.integration=INFO
|
||||
log4j.category.org.springframework.integration.zip=INFO
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Asia
|
||||
@@ -0,0 +1 @@
|
||||
Europe
|
||||
@@ -0,0 +1 @@
|
||||
Germany
|
||||
@@ -0,0 +1 @@
|
||||
France
|
||||
@@ -0,0 +1 @@
|
||||
Poland
|
||||
BIN
spring-integration-zip/src/test/resources/testzipdata/single.zip
Normal file
BIN
spring-integration-zip/src/test/resources/testzipdata/single.zip
Normal file
Binary file not shown.
Reference in New Issue
Block a user