Skip to content

Commit

Permalink
Merge branch '2.2.x' into 2.3.x
Browse files Browse the repository at this point in the history
Closes gh-22998
  • Loading branch information
philwebb committed Aug 18, 2020
2 parents ff36f8b + aac367e commit 2b1b096
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 76 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2012-2020 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
*
* https://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.loader.jar;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Permission;

/**
* Base class for extended variants of {@link java.util.jar.JarFile}.
*
* @author Phillip Webb
*/
abstract class AbstractJarFile extends java.util.jar.JarFile {

/**
* Create a new {@link AbstractJarFile}.
* @param file the root jar file.
* @throws IOException on IO error
*/
AbstractJarFile(File file) throws IOException {
super(file);
}

/**
* Return a URL that can be used to access this JAR file. NOTE: the specified URL
* cannot be serialized and or cloned.
* @return the URL
* @throws MalformedURLException if the URL is malformed
*/
protected abstract URL getUrl() throws MalformedURLException;

/**
* Return the {@link JarFileType} of this instance.
* @return the jar file type
*/
protected abstract JarFileType getType();

/**
* Return the security permission for this JAR.
* @return the security permission.
*/
protected abstract Permission getPermission();

/**
* Return an {@link InputStream} for the entire jar contents.
* @return the contents input stream
* @throws IOException on IO error
*/
protected abstract InputStream getInputStream() throws IOException;

/**
* The type of a {@link JarFile}.
*/
enum JarFileType {

DIRECT, NESTED_DIRECTORY, NESTED_JAR

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
package org.springframework.boot.loader.jar;

import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.Permission;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Spliterator;
Expand Down Expand Up @@ -52,7 +54,7 @@
* @author Andy Wilkinson
* @since 1.0.0
*/
public class JarFile extends java.util.jar.JarFile implements Iterable<java.util.jar.JarEntry> {
public class JarFile extends AbstractJarFile implements Iterable<java.util.jar.JarEntry> {

private static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";

Expand All @@ -64,7 +66,7 @@ public class JarFile extends java.util.jar.JarFile implements Iterable<java.util

private static final AsciiBytes SIGNATURE_FILE_EXTENSION = new AsciiBytes(".SF");

private final JarFile parent;
private static final String READ_ACTION = "read";

private final RandomAccessDataFile rootFile;

Expand Down Expand Up @@ -108,28 +110,6 @@ public JarFile(File file) throws IOException {
this(file, "", file, JarFileType.DIRECT);
}

/**
* Create a new JarFile copy based on a given parent.
* @param parent the parent jar
* @throws IOException if the file cannot be read
*/
JarFile(JarFile parent) throws IOException {
super(parent.rootFile.getFile());
super.close();
this.parent = parent;
this.rootFile = parent.rootFile;
this.pathFromRoot = parent.pathFromRoot;
this.data = parent.data;
this.type = parent.type;
this.url = parent.url;
this.urlString = parent.urlString;
this.entries = parent.entries;
this.manifestSupplier = parent.manifestSupplier;
this.manifest = parent.manifest;
this.signed = parent.signed;
this.comment = parent.comment;
}

/**
* Private constructor used to create a new {@link JarFile} either directly or from a
* nested entry.
Expand All @@ -141,14 +121,13 @@ public JarFile(File file) throws IOException {
*/
private JarFile(RandomAccessDataFile rootFile, String pathFromRoot, RandomAccessData data, JarFileType type)
throws IOException {
this(null, rootFile, pathFromRoot, data, null, type, null);
this(rootFile, pathFromRoot, data, null, type, null);
}

private JarFile(JarFile parent, RandomAccessDataFile rootFile, String pathFromRoot, RandomAccessData data,
JarEntryFilter filter, JarFileType type, Supplier<Manifest> manifestSupplier) throws IOException {
private JarFile(RandomAccessDataFile rootFile, String pathFromRoot, RandomAccessData data, JarEntryFilter filter,
JarFileType type, Supplier<Manifest> manifestSupplier) throws IOException {
super(rootFile.getFile());
super.close();
this.parent = parent;
this.rootFile = rootFile;
this.pathFromRoot = pathFromRoot;
CentralDirectoryParser parser = new CentralDirectoryParser();
Expand Down Expand Up @@ -198,8 +177,9 @@ public void visitEnd() {
};
}

JarFile getParent() {
return this.parent;
@Override
protected Permission getPermission() {
return new FilePermission(this.rootFile.getFile().getPath(), READ_ACTION);
}

protected final RandomAccessDataFile getRootJarFile() {
Expand Down Expand Up @@ -267,6 +247,11 @@ public ZipEntry getEntry(String name) {
return this.entries.getEntry(name);
}

@Override
protected InputStream getInputStream() throws IOException {
return this.data.getInputStream();
}

@Override
public synchronized InputStream getInputStream(ZipEntry entry) throws IOException {
ensureOpen();
Expand Down Expand Up @@ -320,9 +305,8 @@ private JarFile createJarFileFromDirectoryEntry(JarEntry entry) throws IOExcepti
}
return null;
};
return new JarFile(this, this.rootFile,
this.pathFromRoot + "!/" + entry.getName().substring(0, name.length() - 1), this.data, filter,
JarFileType.NESTED_DIRECTORY, this.manifestSupplier);
return new JarFile(this.rootFile, this.pathFromRoot + "!/" + entry.getName().substring(0, name.length() - 1),
this.data, filter, JarFileType.NESTED_DIRECTORY, this.manifestSupplier);
}

private JarFile createJarFileFromFileEntry(JarEntry entry) throws IOException {
Expand Down Expand Up @@ -355,7 +339,7 @@ public void close() throws IOException {
return;
}
this.closed = true;
if (this.type == JarFileType.DIRECT && this.parent == null) {
if (this.type == JarFileType.DIRECT) {
this.rootFile.close();
}
}
Expand All @@ -377,12 +361,7 @@ String getUrlString() throws MalformedURLException {
return this.urlString;
}

/**
* Return a URL that can be used to access this JAR file. NOTE: the specified URL
* cannot be serialized and or cloned.
* @return the URL
* @throws MalformedURLException if the URL is malformed
*/
@Override
public URL getUrl() throws MalformedURLException {
if (this.url == null) {
String file = this.rootFile.getFile().toURI() + this.pathFromRoot + "!/";
Expand Down Expand Up @@ -441,7 +420,8 @@ protected String getPathFromRoot() {
return this.pathFromRoot;
}

JarFileType getType() {
@Override
protected JarFileType getType() {
return this.type;
}

Expand Down Expand Up @@ -470,15 +450,6 @@ private static void resetCachedUrlHandlers() {
}
}

/**
* The type of a {@link JarFile}.
*/
enum JarFileType {

DIRECT, NESTED_DIRECTORY, NESTED_JAR

}

/**
* An {@link Enumeration} on {@linkplain java.util.jar.JarEntry jar entries}.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright 2012-2020 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
*
* https://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.loader.jar;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Permission;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

/**
* A wrapper used to create a copy of a {@link JarFile} so that it can be safely closed
* without closing the original.
*
* @author Phillip Webb
*/
class JarFileWrapper extends AbstractJarFile {

private final JarFile parent;

JarFileWrapper(JarFile parent) throws IOException {
super(parent.getRootJarFile().getFile());
this.parent = parent;
super.close();
}

@Override
protected URL getUrl() throws MalformedURLException {
return this.parent.getUrl();
}

@Override
protected JarFileType getType() {
return this.parent.getType();
}

@Override
protected Permission getPermission() {
return this.parent.getPermission();
}

@Override
public Manifest getManifest() throws IOException {
return this.parent.getManifest();
}

@Override
public Enumeration<JarEntry> entries() {
return this.parent.entries();
}

@Override
public JarEntry getJarEntry(String name) {
return this.parent.getJarEntry(name);
}

@Override
public ZipEntry getEntry(String name) {
return this.parent.getEntry(name);
}

@Override
protected InputStream getInputStream() throws IOException {
return this.parent.getInputStream();
}

@Override
public synchronized InputStream getInputStream(ZipEntry ze) throws IOException {
return this.parent.getInputStream(ze);
}

@Override
public String getComment() {
return this.parent.getComment();
}

@Override
public int size() {
return this.parent.size();
}

@Override
public String toString() {
return this.parent.toString();
}

@Override
public String getName() {
return this.parent.getName();
}

static JarFile unwrap(java.util.jar.JarFile jarFile) {
if (jarFile instanceof JarFile) {
return (JarFile) jarFile;
}
if (jarFile instanceof JarFileWrapper) {
return unwrap(((JarFileWrapper) jarFile).parent);
}
throw new IllegalStateException("Not a JarFile or Wrapper");
}

}
Loading

0 comments on commit 2b1b096

Please sign in to comment.