Commit f440b7b7 authored by Andy Wilkinson's avatar Andy Wilkinson

Move decision about an entry's compression out into BootJar and BootWar

parent 5bf8f778
......@@ -16,13 +16,14 @@
package org.springframework.boot.gradle.bundling;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Function;
import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.file.RelativePath;
import org.gradle.api.internal.file.copy.CopyAction;
......@@ -54,7 +55,7 @@ class BootArchiveSupport {
private final PatternSet requiresUnpack = new PatternSet();
private final Set<String> storedPathPrefixes;
private final Function<FileCopyDetails, ZipCompression> compressionResolver;
private final PatternSet exclusions = new PatternSet();
......@@ -64,9 +65,10 @@ class BootArchiveSupport {
private boolean excludeDevtools = true;
BootArchiveSupport(String loaderMainClass, String... storedPathPrefixes) {
BootArchiveSupport(String loaderMainClass,
Function<FileCopyDetails, ZipCompression> compressionResolver) {
this.loaderMainClass = loaderMainClass;
this.storedPathPrefixes = new HashSet<>(Arrays.asList(storedPathPrefixes));
this.compressionResolver = compressionResolver;
this.requiresUnpack.include(Specs.satisfyNone());
configureExclusions();
}
......@@ -81,7 +83,7 @@ class BootArchiveSupport {
CopyAction copyAction = new BootZipCopyAction(jar.getArchivePath(),
jar.isPreserveFileTimestamps(), isUsingDefaultLoader(jar),
this.requiresUnpack.getAsSpec(), this.exclusions.getAsExcludeSpec(),
this.launchScript, this.storedPathPrefixes);
this.launchScript, this.compressionResolver);
if (!jar.isReproducibleFileOrder()) {
return copyAction;
}
......
......@@ -23,6 +23,7 @@ import java.util.concurrent.Callable;
import org.gradle.api.Action;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.specs.Spec;
......@@ -36,7 +37,7 @@ import org.gradle.api.tasks.bundling.Jar;
public class BootJar extends Jar implements BootArchive {
private BootArchiveSupport support = new BootArchiveSupport(
"org.springframework.boot.loader.JarLauncher", "BOOT-INF/lib");
"org.springframework.boot.loader.JarLauncher", this::resolveZipCompression);
private FileCollection classpath;
......@@ -122,4 +123,21 @@ public class BootJar extends Jar implements BootArchive {
this.support.setExcludeDevtools(excludeDevtools);
}
/**
* Returns the {@link ZipCompression} that should be used when adding the file
* represented by the given {@code details} to the jar.
* <p>
* By default, any file in {@code BOOT-INF/lib/} is stored and all other files are
* deflated.
*
* @param details the details
* @return the compression to use
*/
protected ZipCompression resolveZipCompression(FileCopyDetails details) {
if (details.getRelativePath().getPathString().startsWith("BOOT-INF/lib/")) {
return ZipCompression.STORED;
}
return ZipCompression.DEFLATED;
}
}
......@@ -23,6 +23,7 @@ import java.util.concurrent.Callable;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.specs.Spec;
......@@ -37,8 +38,7 @@ import org.gradle.api.tasks.bundling.War;
public class BootWar extends War implements BootArchive {
private final BootArchiveSupport support = new BootArchiveSupport(
"org.springframework.boot.loader.WarLauncher", "WEB-INF/lib/",
"WEB-INF/lib-provided");
"org.springframework.boot.loader.WarLauncher", this::resolveZipCompression);
private String mainClass;
......@@ -122,4 +122,23 @@ public class BootWar extends War implements BootArchive {
this.support.setExcludeDevtools(excludeDevtools);
}
/**
* Returns the {@link ZipCompression} that should be used when adding the file
* represented by the given {@code details} to the jar.
* <p>
* By default, any file in {@code WEB-INF/lib/} or {@code WEB-INF/lib-provided/} is
* stored and all other files are deflated.
*
* @param details the details
* @return the compression to use
*/
protected ZipCompression resolveZipCompression(FileCopyDetails details) {
String relativePath = details.getRelativePath().getPathString();
if (relativePath.startsWith("WEB-INF/lib/")
|| relativePath.startsWith("WEB-INF/lib-provided/")) {
return ZipCompression.STORED;
}
return ZipCompression.DEFLATED;
}
}
......@@ -21,7 +21,7 @@ import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.function.Function;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
......@@ -61,19 +61,19 @@ class BootZipCopyAction implements CopyAction {
private final LaunchScriptConfiguration launchScript;
private final Set<String> storedPathPrefixes;
private final Function<FileCopyDetails, ZipCompression> compressionResolver;
BootZipCopyAction(File output, boolean preserveFileTimestamps,
boolean includeDefaultLoader, Spec<FileTreeElement> requiresUnpack,
Spec<FileTreeElement> exclusions, LaunchScriptConfiguration launchScript,
Set<String> storedPathPrefixes) {
Function<FileCopyDetails, ZipCompression> compressionResolver) {
this.output = output;
this.preserveFileTimestamps = preserveFileTimestamps;
this.includeDefaultLoader = includeDefaultLoader;
this.requiresUnpack = requiresUnpack;
this.exclusions = exclusions;
this.launchScript = launchScript;
this.storedPathPrefixes = storedPathPrefixes;
this.compressionResolver = compressionResolver;
}
@Override
......@@ -91,7 +91,7 @@ class BootZipCopyAction implements CopyAction {
try {
stream.process(new ZipStreamAction(zipStream, this.output,
this.preserveFileTimestamps, this.requiresUnpack, this.exclusions,
this.storedPathPrefixes));
this.compressionResolver));
}
finally {
try {
......@@ -162,17 +162,18 @@ class BootZipCopyAction implements CopyAction {
private final Spec<FileTreeElement> exclusions;
private final Set<String> storedPathPrefixes;
private final Function<FileCopyDetails, ZipCompression> compressionType;
private ZipStreamAction(ZipOutputStream zipStream, File output,
boolean preserveFileTimestamps, Spec<FileTreeElement> requiresUnpack,
Spec<FileTreeElement> exclusions, Set<String> storedPathPrefixes) {
Spec<FileTreeElement> exclusions,
Function<FileCopyDetails, ZipCompression> compressionType) {
this.zipStream = zipStream;
this.output = output;
this.preserveFileTimestamps = preserveFileTimestamps;
this.requiresUnpack = requiresUnpack;
this.exclusions = exclusions;
this.storedPathPrefixes = storedPathPrefixes;
this.compressionType = compressionType;
}
@Override
......@@ -207,7 +208,8 @@ class BootZipCopyAction implements CopyAction {
ZipEntry archiveEntry = new ZipEntry(relativePath);
archiveEntry.setTime(getTime(details));
this.zipStream.putNextEntry(archiveEntry);
if (isStoredEntry(relativePath)) {
ZipCompression compression = this.compressionType.apply(details);
if (compression == ZipCompression.STORED) {
archiveEntry.setMethod(ZipEntry.STORED);
archiveEntry.setSize(details.getSize());
archiveEntry.setCompressedSize(details.getSize());
......@@ -225,15 +227,6 @@ class BootZipCopyAction implements CopyAction {
this.zipStream.closeEntry();
}
private boolean isStoredEntry(String relativePath) {
for (String prefix : this.storedPathPrefixes) {
if (relativePath.startsWith(prefix)) {
return true;
}
}
return false;
}
private long getTime(FileCopyDetails details) {
return this.preserveFileTimestamps ? details.getLastModified()
: GUtil.CONSTANT_TIME_FOR_ZIP_ENTRIES;
......
/*
* Copyright 2012-2017 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.boot.gradle.bundling;
import java.util.zip.ZipEntry;
/**
* An enumeration of supported compression options for an entry in a ZIP archive.
*
* @author Andy Wilkinson
*/
public enum ZipCompression {
/**
* The entry should be {@link ZipEntry#STORED} in the archive.
*/
STORED,
/**
* The entry should be {@link ZipEntry#DEFLATED} in the archive.
*/
DEFLATED;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment