Java tutorial
/** * Copyright 2011 Michael R. Lange <michael.r.lange@langmi.de>. * * 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 de.langmi.spring.batch.examples.readers.file.zip; import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ItemStreamException; import org.springframework.batch.item.file.MultiResourceItemReader; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; /** * Multi Resource Item Reader capable of reading zip archive files. Extracts only * the contained files, ignores directories. * <br /> * Falls back to normal MultiResourceItemReader behaviour if no archive is set. * * @author Michael R. Lange <michael.r.lange@langmi.de> * @param <T> */ public class ZipMultiResourceItemReader<T> extends MultiResourceItemReader<T> { private static final Logger LOG = LoggerFactory.getLogger(ZipMultiResourceItemReader.class); private Resource[] archives; private ZipFile[] zipFiles; /** * Tries to extract all files in the archives and adds them as resources to * the normal MultiResourceItemReader. Overwrites the Comparator from * the super class to get it working with itemstreams. * * @param executionContext * @throws ItemStreamException */ @Override public void open(ExecutionContext executionContext) throws ItemStreamException { // really used with archives? if (archives != null) { // overwrite the comparator to use description // instead of filename, the itemStream can only // have that description this.setComparator(new Comparator<Resource>() { /** Compares resource descriptions. */ @Override public int compare(Resource r1, Resource r2) { return r1.getDescription().compareTo(r2.getDescription()); } }); // get the inputStreams from all files inside the archives zipFiles = new ZipFile[archives.length]; List<Resource> extractedResources = new ArrayList<Resource>(); try { for (int i = 0; i < archives.length; i++) { // find files inside the current zip resource zipFiles[i] = new ZipFile(archives[i].getFile()); extractFiles(zipFiles[i], extractedResources); } } catch (Exception ex) { throw new ItemStreamException(ex); } // propagate extracted resources this.setResources(extractedResources.toArray(new Resource[extractedResources.size()])); } super.open(executionContext); } /** * Calls super.close() and tries to close all used zip files. * * @throws ItemStreamException */ @Override public void close() throws ItemStreamException { super.close(); // try to close all used zipfiles if (zipFiles != null) { for (int i = 0; i < zipFiles.length; i++) { try { zipFiles[i].close(); } catch (IOException ex) { throw new ItemStreamException(ex); } } } } /** * Extract only files from the zip archive. * * @param currentZipFile * @param extractedResources * @throws IOException */ private static void extractFiles(final ZipFile currentZipFile, final List<Resource> extractedResources) throws IOException { Enumeration<? extends ZipEntry> zipEntryEnum = currentZipFile.entries(); while (zipEntryEnum.hasMoreElements()) { ZipEntry zipEntry = zipEntryEnum.nextElement(); LOG.info("extracting:" + zipEntry.getName()); // traverse directories if (!zipEntry.isDirectory()) { // add inputStream extractedResources .add(new InputStreamResource(currentZipFile.getInputStream(zipEntry), zipEntry.getName())); LOG.info("using extracted file:" + zipEntry.getName()); } } } /** * Set archive files with normal Spring resources pattern, if not set, the * class will fallback to normal MultiResourceItemReader behaviour. * * @param archives */ public void setArchives(Resource[] archives) { this.archives = archives; } }