Java tutorial
/** * integration-common * * Copyright (c) 2019 Synopsys, Inc. * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 com.synopsys.integration.util; import java.io.*; import java.nio.file.Files; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.examples.Expander; import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import com.synopsys.integration.exception.IntegrationException; import com.synopsys.integration.log.IntLogger; /** * Used for expanding a given archive to a target directory. Subclasses can * override beforeExpansion and/or afterExpansion as needed for additional * processing. */ public class CommonZipExpander { protected final IntLogger logger; private final Expander expander; public CommonZipExpander(IntLogger logger) { this(logger, new Expander()); } public CommonZipExpander(IntLogger logger, Expander expander) { this.logger = logger; this.expander = expander; } public void expand(final File sourceArchiveFile, final File targetExpansionDirectory) throws IOException, ArchiveException, IntegrationException { expandUnknownFile(sourceArchiveFile, targetExpansionDirectory); } public void expand(final InputStream sourceArchiveStream, final File targetExpansionDirectory) throws IOException, ArchiveException, IntegrationException { // it is important to first create the zip file as a stream cannot be // unzipped correctly in all cases // "If possible, you should always prefer ZipFile over // ZipArchiveInputStream." // https://commons.apache.org/proper/commons-compress/zip.html#ZipArchiveInputStream_vs_ZipFile final File tempZipFile = File.createTempFile("tmpzip", null); try { try (FileOutputStream fileOutputStream = new FileOutputStream(tempZipFile)) { IOUtils.copy(sourceArchiveStream, fileOutputStream); } if (!tempZipFile.exists() || tempZipFile.length() <= 0) { throw new IntegrationException("The zip file was not created correctly. Please try again."); } expandUnknownFile(tempZipFile, targetExpansionDirectory); } finally { FileUtils.deleteQuietly(tempZipFile); } } private void expandUnknownFile(File unknownFile, File targetExpansionDirectory) throws IOException, IntegrationException, ArchiveException { String format; // we need to use an InputStream where inputStream.markSupported() == true try (InputStream i = new BufferedInputStream(Files.newInputStream(unknownFile.toPath()))) { format = new ArchiveStreamFactory().detect(i); } beforeExpansion(unknownFile, targetExpansionDirectory); // in the case of zip files, commons-compress creates, but does not close, the ZipFile. To avoid this unclosed resource, we handle it ourselves. try { if (ArchiveStreamFactory.ZIP.equals(format)) { try (ZipFile zipFile = new ZipFile(unknownFile)) { expander.expand(zipFile, targetExpansionDirectory); } } else { expander.expand(unknownFile, targetExpansionDirectory); } } catch (IOException | ArchiveException e) { logger.error("Couldn't extract the archive file - check the file's permissions: " + e.getMessage()); throw e; } afterExpansion(unknownFile, targetExpansionDirectory); } public void beforeExpansion(final File sourceArchiveFile, final File targetExpansionDirectory) throws IntegrationException { } public void afterExpansion(final File sourceArchiveFile, final File targetExpansionDirectory) throws IntegrationException { } }