diff --git a/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java b/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java
index a81f6c3818e..b811e1ab613 100644
--- a/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -38,6 +38,20 @@ import org.springframework.util.ResourceUtils;
*/
public abstract class AbstractFileResolvingResource extends AbstractResource {
+ @Override
+ public boolean isFile() {
+ try {
+ URL url = getURL();
+ if (url.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
+ return VfsResourceDelegate.getResource(url).isFile();
+ }
+ return ResourceUtils.URL_PROTOCOL_FILE.equals(url.getProtocol());
+ }
+ catch (IOException ex) {
+ return false;
+ }
+ }
+
/**
* This implementation returns a File reference for the underlying class path
* resource, provided that it refers to a file in the file system.
@@ -72,7 +86,25 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
}
/**
- * This implementation returns a File reference for the underlying class path
+ * This implementation returns a File reference for the given URI-identified
+ * resource, provided that it refers to a file in the file system.
+ * @since 5.0
+ * @see #getFile(URI)
+ */
+ protected boolean isFile(URI uri) {
+ try {
+ if (uri.getScheme().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
+ return VfsResourceDelegate.getResource(uri).isFile();
+ }
+ return ResourceUtils.URL_PROTOCOL_FILE.equals(uri.getScheme());
+ }
+ catch (IOException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * This implementation returns a File reference for the given URI-identified
* resource, provided that it refers to a file in the file system.
* @see org.springframework.util.ResourceUtils#getFile(java.net.URI, String)
*/
diff --git a/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java b/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java
index 1bc9e1b934e..627704e49fd 100644
--- a/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java
@@ -81,6 +81,14 @@ public abstract class AbstractResource implements Resource {
return false;
}
+ /**
+ * This implementation always returns {@code false}.
+ */
+ @Override
+ public boolean isFile() {
+ return false;
+ }
+
/**
* This implementation throws a FileNotFoundException, assuming
* that the resource cannot be resolved to a URL.
diff --git a/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java b/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java
index 294a3e3726b..f634724625f 100644
--- a/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -85,7 +85,6 @@ public class FileSystemResource extends AbstractResource implements WritableReso
return this.path;
}
-
/**
* This implementation returns whether the underlying file exists.
* @see java.io.File#exists()
@@ -153,6 +152,14 @@ public class FileSystemResource extends AbstractResource implements WritableReso
return this.file.toURI();
}
+ /**
+ * This implementation always indicates a file.
+ */
+ @Override
+ public boolean isFile() {
+ return true;
+ }
+
/**
* This implementation returns the underlying File reference.
*/
diff --git a/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java b/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java
index f31e6ef9a25..282ebb1eca7 100644
--- a/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -49,7 +49,6 @@ public interface InputStreamSource {
* that each {@code getInputStream()} call returns a fresh stream.
* @return the input stream for the underlying resource (must not be {@code null})
* @throws IOException if the stream could not be opened
- * @see org.springframework.mail.javamail.MimeMessageHelper#addAttachment(String, InputStreamSource)
*/
InputStream getInputStream() throws IOException;
diff --git a/spring-core/src/main/java/org/springframework/core/io/PathResource.java b/spring-core/src/main/java/org/springframework/core/io/PathResource.java
index 649cf5f7c47..1246e177c84 100644
--- a/spring-core/src/main/java/org/springframework/core/io/PathResource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/PathResource.java
@@ -171,6 +171,14 @@ public class PathResource extends AbstractResource implements WritableResource {
return this.path.toUri();
}
+ /**
+ * This implementation always indicates a file.
+ */
+ @Override
+ public boolean isFile() {
+ return true;
+ }
+
/**
* This implementation returns the underlying File reference.
*/
@@ -180,8 +188,8 @@ public class PathResource extends AbstractResource implements WritableResource {
return this.path.toFile();
}
catch (UnsupportedOperationException ex) {
- // only Paths on the default file system can be converted to a File
- // do exception translation for cases where conversion is not possible
+ // Only paths on the default file system can be converted to a File:
+ // Do exception translation for cases where conversion is not possible.
throw new FileNotFoundException(this.path + " cannot be resolved to " + "absolute file path");
}
}
diff --git a/spring-core/src/main/java/org/springframework/core/io/Resource.java b/spring-core/src/main/java/org/springframework/core/io/Resource.java
index e3fc2a4e59d..2b6a2bf580a 100644
--- a/spring-core/src/main/java/org/springframework/core/io/Resource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/Resource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -47,7 +47,7 @@ import java.net.URL;
public interface Resource extends InputStreamSource {
/**
- * Return whether this resource actually exists in physical form.
+ * Determine whether this resource actually exists in physical form.
*
This method performs a definitive existence check, whereas the
* existence of a {@code Resource} handle only guarantees a
* valid descriptor handle.
@@ -55,23 +55,39 @@ public interface Resource extends InputStreamSource {
boolean exists();
/**
- * Return whether the contents of this resource can be read,
- * e.g. via {@link #getInputStream()} or {@link #getFile()}.
+ * Indicate whether the contents of this resource can be read via
+ * {@link #getInputStream()}.
*
Will be {@code true} for typical resource descriptors;
* note that actual content reading may still fail when attempted.
* However, a value of {@code false} is a definitive indication
* that the resource content cannot be read.
* @see #getInputStream()
*/
- boolean isReadable();
+ default boolean isReadable() {
+ return true;
+ }
/**
- * Return whether this resource represents a handle with an open
- * stream. If true, the InputStream cannot be read multiple times,
+ * Indicate whether this resource represents a handle with an open stream.
+ * If {@code true}, the InputStream cannot be read multiple times,
* and must be read and closed to avoid resource leaks.
*
Will be {@code false} for typical resource descriptors.
*/
- boolean isOpen();
+ default boolean isOpen() {
+ return false;
+ }
+
+ /**
+ * Determine whether this resource represents a file in a file system.
+ * A value of {@code true} strongly suggests (but does not guarantee)
+ * that a {@link #getFile()} call will succeed.
+ *
This is conservatively {@code false} by default.
+ * @since 5.0
+ * @see #getFile()
+ */
+ default boolean isFile() {
+ return false;
+ }
/**
* Return a URL handle for this resource.
@@ -84,6 +100,7 @@ public interface Resource extends InputStreamSource {
* Return a URI handle for this resource.
* @throws IOException if the resource cannot be resolved as URI,
* i.e. if the resource is not available as descriptor
+ * @since 2.5
*/
URI getURI() throws IOException;
diff --git a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java
index 41aa4a03b48..19b33282ac2 100644
--- a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -61,6 +61,7 @@ public class UrlResource extends AbstractFileResolvingResource {
* Create a new {@code UrlResource} based on the given URI object.
* @param uri a URI
* @throws MalformedURLException if the given URL path is not valid
+ * @since 2.5
*/
public UrlResource(URI uri) throws MalformedURLException {
Assert.notNull(uri, "URI must not be null");
@@ -198,6 +199,16 @@ public class UrlResource extends AbstractFileResolvingResource {
}
}
+ @Override
+ public boolean isFile() {
+ if (this.uri != null) {
+ return super.isFile(this.uri);
+ }
+ else {
+ return super.isFile();
+ }
+ }
+
/**
* This implementation returns a File reference for the underlying URL/URI,
* provided that it refers to a file in the file system.
diff --git a/spring-core/src/main/java/org/springframework/core/io/WritableResource.java b/spring-core/src/main/java/org/springframework/core/io/WritableResource.java
index 72d4fe34ed3..780a419d0a2 100644
--- a/spring-core/src/main/java/org/springframework/core/io/WritableResource.java
+++ b/spring-core/src/main/java/org/springframework/core/io/WritableResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -30,8 +30,8 @@ import java.io.OutputStream;
public interface WritableResource extends Resource {
/**
- * Return whether the contents of this resource can be modified,
- * e.g. via {@link #getOutputStream()} or {@link #getFile()}.
+ * Indicate whether the contents of this resource can be written
+ * via {@link #getOutputStream()}.
*
Will be {@code true} for typical resource descriptors;
* note that actual content writing may still fail when attempted.
* However, a value of {@code false} is a definitive indication
@@ -39,7 +39,9 @@ public interface WritableResource extends Resource {
* @see #getOutputStream()
* @see #isReadable()
*/
- boolean isWritable();
+ default boolean isWritable() {
+ return true;
+ }
/**
* Return an {@link OutputStream} for the underlying resource,
diff --git a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java
index c32096882f3..e5be1cd49f7 100644
--- a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java
@@ -16,8 +16,6 @@
package org.springframework.util;
-import java.io.IOException;
-import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
@@ -28,13 +26,8 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Random;
-import javax.activation.FileTypeMap;
-import javax.activation.MimetypesFileTypeMap;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
import org.springframework.util.MimeType.SpecificityComparator;
/**
@@ -56,12 +49,6 @@ public abstract class MimeTypeUtils {
private static Charset US_ASCII = Charset.forName("US-ASCII");
- private static final FileTypeMap fileTypeMap;
-
- static {
- fileTypeMap = initFileTypeMap();
- }
-
/**
* Public constant mime type that includes all media ranges (i.e. "*/*").
*/
@@ -220,31 +207,6 @@ public abstract class MimeTypeUtils {
TEXT_XML = MimeType.valueOf(TEXT_XML_VALUE);
}
- private static FileTypeMap initFileTypeMap() {
- // See if we can find the extended mime.types from the context-support module...
- Resource mappingLocation = new ClassPathResource("org/springframework/mail/javamail/mime.types");
- if (mappingLocation.exists()) {
- InputStream inputStream = null;
- try {
- inputStream = mappingLocation.getInputStream();
- return new MimetypesFileTypeMap(inputStream);
- }
- catch (IOException ex) {
- // ignore
- }
- finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- }
- catch (IOException ex) {
- // ignore
- }
- }
- }
- }
- return FileTypeMap.getDefaultFileTypeMap();
- }
/**
* Parse the given String into a single {@code MimeType}.
@@ -322,23 +284,6 @@ public abstract class MimeTypeUtils {
return result;
}
- /**
- * Returns the {@code MimeType} of the given file name, using the Java Activation
- * Framework.
- * @param filename the filename whose mime type is to be found
- * @return the mime type, if any
- * @since 5.0
- */
- public static Optional getMimeType(String filename) {
- if (filename != null) {
- String mimeType = fileTypeMap.getContentType(filename);
- if (StringUtils.hasText(mimeType)) {
- return Optional.of(parseMimeType(mimeType));
- }
- }
- return Optional.empty();
- }
-
/**
* Return a string representation of the given list of {@code MimeType} objects.
* @param mimeTypes the string to parse
diff --git a/spring-core/src/main/java/org/springframework/util/ResourceUtils.java b/spring-core/src/main/java/org/springframework/util/ResourceUtils.java
index 082fade93ad..0f37194c056 100644
--- a/spring-core/src/main/java/org/springframework/util/ResourceUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/ResourceUtils.java
@@ -18,18 +18,12 @@ package org.springframework.util;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
-import org.springframework.core.io.ByteArrayResource;
-import org.springframework.core.io.DescriptiveResource;
-import org.springframework.core.io.InputStreamResource;
-import org.springframework.core.io.Resource;
-
/**
* Utility methods for resolving resource locations to files in the
* file system. Mainly for internal use within the framework.
@@ -235,6 +229,7 @@ public abstract class ResourceUtils {
* @return a corresponding File object
* @throws FileNotFoundException if the URL cannot be resolved to
* a file in the file system
+ * @since 2.5
*/
public static File getFile(URI resourceUri) throws FileNotFoundException {
return getFile(resourceUri, "URI");
@@ -249,6 +244,7 @@ public abstract class ResourceUtils {
* @return a corresponding File object
* @throws FileNotFoundException if the URL cannot be resolved to
* a file in the file system
+ * @since 2.5
*/
public static File getFile(URI resourceUri, String description) throws FileNotFoundException {
Assert.notNull(resourceUri, "Resource URI must not be null");
@@ -296,32 +292,6 @@ public abstract class ResourceUtils {
url.getPath().toLowerCase().endsWith(JAR_FILE_EXTENSION));
}
- /**
- * Indicates whether the given resource has a file, so that {@link
- * Resource#getFile()}
- * can be called without an {@link java.io.IOException}.
- * @param resource the resource to check
- * @return {@code true} if the given resource has a file; {@code false} otherwise
- * @since 5.0
- */
- public static boolean hasFile(Resource resource) {
- Assert.notNull(resource, "'resource' must not be null");
-
- // the following Resource implementations do not support getURI/getFile
- if (resource instanceof ByteArrayResource ||
- resource instanceof DescriptiveResource ||
- resource instanceof InputStreamResource) {
- return false;
- }
- try {
- URI resourceUri = resource.getURI();
- return URL_PROTOCOL_FILE.equals(resourceUri.getScheme());
- }
- catch (IOException ignored) {
- }
- return false;
- }
-
/**
* Extract the URL for the actual jar file from the given URL
* (which may point to a resource in a jar file or to a jar file itself).
diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java
index 6a3ec5b780a..e731edb319b 100644
--- a/spring-core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java
+++ b/spring-core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java
@@ -75,10 +75,10 @@ public class CollectionToCollectionConverterTests {
conversionService.addConverterFactory(new StringToNumberConverterFactory());
assertTrue(conversionService.canConvert(sourceType, targetType));
@SuppressWarnings("unchecked")
- List result = (List) conversionService.convert(list, sourceType, targetType);
+ List result = (List) conversionService.convert(list, sourceType, targetType);
assertFalse(list.equals(result));
- assertEquals(9, result.get(0));
- assertEquals(37, result.get(1));
+ assertEquals(9, result.get(0).intValue());
+ assertEquals(37, result.get(1).intValue());
}
@Test
@@ -303,6 +303,11 @@ public class CollectionToCollectionConverterTests {
return false;
}
+ @Override
+ public boolean isFile() {
+ return false;
+ }
+
@Override
public URL getURL() throws IOException {
return null;
diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
index 6f668bda022..09c1465d097 100644
--- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
+++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
@@ -18,13 +18,11 @@ package org.springframework.web.reactive.accept;
import java.util.Locale;
import java.util.Map;
-import java.util.Optional;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
+import org.springframework.http.MediaTypeFactory;
import org.springframework.util.Assert;
-import org.springframework.util.MimeType;
-import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.NotAcceptableStatusException;
import org.springframework.web.server.ServerWebExchange;
@@ -94,8 +92,7 @@ public class PathExtensionContentTypeResolver extends AbstractMappingContentType
@Override
protected MediaType handleNoMatch(String key) throws NotAcceptableStatusException {
if (this.useJaf) {
- Optional mimeType = MimeTypeUtils.getMimeType("file." + key);
- MediaType mediaType = mimeType.map(MediaType::toMediaType).orElse(null);
+ MediaType mediaType = MediaTypeFactory.getMediaType("file." + key);
if (mediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
return mediaType;
}
@@ -111,10 +108,10 @@ public class PathExtensionContentTypeResolver extends AbstractMappingContentType
* determine the media type for a given {@link Resource}. First it checks
* the explicitly registered mappings and then falls back on JAF.
* @param resource the resource
- * @return the MediaType for the extension or {@code null}.
+ * @return the MediaType for the extension, or {@code null} if none determined
*/
public MediaType resolveMediaTypeForResource(Resource resource) {
- Assert.notNull(resource);
+ Assert.notNull(resource, "Resource must not be null");
MediaType mediaType = null;
String filename = resource.getFilename();
String extension = StringUtils.getFilenameExtension(filename);
@@ -122,7 +119,7 @@ public class PathExtensionContentTypeResolver extends AbstractMappingContentType
mediaType = getMediaType(extension);
}
if (mediaType == null) {
- mediaType = MimeTypeUtils.getMimeType(filename).map(MediaType::toMediaType).orElse(null);
+ mediaType = MediaTypeFactory.getMediaType(filename);
}
if (MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
mediaType = null;
diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java
index e243a5eb759..02dd7bc9029 100644
--- a/spring-web/src/main/java/org/springframework/http/MediaType.java
+++ b/spring-web/src/main/java/org/springframework/http/MediaType.java
@@ -43,8 +43,7 @@ import org.springframework.util.comparator.CompoundComparator;
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
* @since 3.0
- * @see HTTP 1.1: Semantics
- * and Content, section 3.1.1.1
+ * @see HTTP 1.1: Semantics and Content, section 3.1.1.1
*/
public class MediaType extends MimeType implements Serializable {
@@ -450,15 +449,18 @@ public class MediaType extends MimeType implements Serializable {
* Re-create the given mime types as media types.
* @since 5.0
*/
- public static List toMediaTypes(List mimeTypes) {
- return mimeTypes.stream().map(MediaType::toMediaType).collect(Collectors.toList());
+ public static List asMediaTypes(List mimeTypes) {
+ return mimeTypes.stream().map(MediaType::asMediaType).collect(Collectors.toList());
}
/**
* Re-create the given mime type as a media type.
* @since 5.0
*/
- public static MediaType toMediaType(MimeType mimeType) {
+ public static MediaType asMediaType(MimeType mimeType) {
+ if (mimeType instanceof MediaType) {
+ return (MediaType) mimeType;
+ }
return new MediaType(mimeType.getType(), mimeType.getSubtype(), mimeType.getParameters());
}
diff --git a/spring-web/src/main/java/org/springframework/http/MediaTypeFactory.java b/spring-web/src/main/java/org/springframework/http/MediaTypeFactory.java
new file mode 100644
index 00000000000..d7752948ffa
--- /dev/null
+++ b/spring-web/src/main/java/org/springframework/http/MediaTypeFactory.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2002-2016 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.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.activation.FileTypeMap;
+import javax.activation.MimetypesFileTypeMap;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.util.StringUtils;
+
+/**
+ * A factory delegate for resolving {@link MediaType} objects
+ * from {@link Resource} handles or filenames.
+ *
+ * This implementation is based on the Java Activation Framework,
+ * sharing the MIME type definitions with Spring's JavaMail support.
+ * However, JAF is an implementation detail and not leaking out.
+ *
+ * @author Juergen Hoeller
+ * @since 5.0
+ */
+public class MediaTypeFactory {
+
+ private static final FileTypeMap fileTypeMap;
+
+ static {
+ fileTypeMap = loadFileTypeMapFromContextSupportModule();
+ }
+
+
+ private static FileTypeMap loadFileTypeMapFromContextSupportModule() {
+ // See if we can find the extended mime.types from the context-support module...
+ Resource mappingLocation = new ClassPathResource("org/springframework/mail/javamail/mime.types");
+ if (mappingLocation.exists()) {
+ InputStream inputStream = null;
+ try {
+ inputStream = mappingLocation.getInputStream();
+ return new MimetypesFileTypeMap(inputStream);
+ }
+ catch (IOException ex) {
+ // ignore
+ }
+ finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ }
+ catch (IOException ex) {
+ // ignore
+ }
+ }
+ }
+ }
+ return FileTypeMap.getDefaultFileTypeMap();
+ }
+
+
+ /**
+ * Determine a media type for the given resource, if possible.
+ * @param resource the resource to introspect
+ * @return the corresponding media type, or {@code null} if none found
+ */
+ public static MediaType getMediaType(Resource resource) {
+ String filename = resource.getFilename();
+ return (filename != null ? getMediaType(filename) : null);
+ }
+
+ /**
+ * Determine a media type for the given file name, if possible.
+ * @param filename the file name plus extension
+ * @return the corresponding media type, or {@code null} if none found
+ */
+ public static MediaType getMediaType(String filename) {
+ String mediaType = fileTypeMap.getContentType(filename);
+ return (StringUtils.hasText(mediaType) ? MediaType.parseMediaType(mediaType) : null);
+ }
+
+}
diff --git a/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java
index 93bd3a3a2aa..5e7a321d8b9 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java
@@ -19,19 +19,16 @@ package org.springframework.http.converter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import javax.activation.FileTypeMap;
-import javax.activation.MimetypesFileTypeMap;
import org.springframework.core.io.ByteArrayResource;
-import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
+import org.springframework.http.MediaTypeFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.StreamUtils;
-import org.springframework.util.StringUtils;
/**
* Implementation of {@link HttpMessageConverter} that can read and write {@link Resource Resources}
@@ -82,7 +79,7 @@ public class ResourceHttpMessageConverter extends AbstractHttpMessageConverter implements HttpMessageReader {
*/
public DecoderHttpMessageReader(Decoder decoder) {
this.decoder = decoder;
- this.readableMediaTypes = decoder != null ?
- MediaType.toMediaTypes(decoder.getDecodableMimeTypes()) :
- Collections.emptyList();
+ this.readableMediaTypes = (decoder != null ?
+ MediaType.asMediaTypes(decoder.getDecodableMimeTypes()) : Collections.emptyList());
}
diff --git a/spring-web/src/main/java/org/springframework/http/converter/reactive/EncoderHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/converter/reactive/EncoderHttpMessageWriter.java
index 5b2213dbf51..77762843fea 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/reactive/EncoderHttpMessageWriter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/reactive/EncoderHttpMessageWriter.java
@@ -32,8 +32,8 @@ import org.springframework.http.MediaType;
import org.springframework.http.ReactiveHttpOutputMessage;
/**
- * Implementation of the {@link HttpMessageWriter} interface that delegates to
- * an {@link Encoder}.
+ * Implementation of the {@link HttpMessageWriter} interface that delegates
+ * to an {@link Encoder}.
*
* @author Arjen Poutsma
* @author Sebastien Deleuze
@@ -53,9 +53,8 @@ public class EncoderHttpMessageWriter implements HttpMessageWriter {
*/
public EncoderHttpMessageWriter(Encoder encoder) {
this.encoder = encoder;
- this.writableMediaTypes = encoder != null ?
- MediaType.toMediaTypes(encoder.getEncodableMimeTypes()) :
- Collections.emptyList();
+ this.writableMediaTypes = (encoder != null ?
+ MediaType.asMediaTypes(encoder.getEncodableMimeTypes()) : Collections.emptyList());
}
diff --git a/spring-web/src/main/java/org/springframework/http/converter/reactive/ResourceHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/converter/reactive/ResourceHttpMessageWriter.java
index 0ff9a62bc2e..f1b9db49ad0 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/reactive/ResourceHttpMessageWriter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/reactive/ResourceHttpMessageWriter.java
@@ -31,10 +31,9 @@ import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
+import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ReactiveHttpOutputMessage;
import org.springframework.http.ZeroCopyHttpOutputMessage;
-import org.springframework.util.MimeTypeUtils;
-import org.springframework.util.ResourceUtils;
/**
* Implementation of {@link HttpMessageWriter} that can write
@@ -67,8 +66,7 @@ public class ResourceHttpMessageWriter extends EncoderHttpMessageWriter {
HttpHeaders headers = outputMessage.getHeaders();
addHeaders(headers, resource, contentType);
-
- return writeContent(resource, type, contentType, outputMessage);
+ return writeContent(resource, type, outputMessage);
}));
}
@@ -76,8 +74,7 @@ public class ResourceHttpMessageWriter extends EncoderHttpMessageWriter writeContent(Resource resource, ResolvableType type,
- MediaType contentType, ReactiveHttpOutputMessage outputMessage) {
-
+ private Mono writeContent(Resource resource, ResolvableType type, ReactiveHttpOutputMessage outputMessage) {
if (outputMessage instanceof ZeroCopyHttpOutputMessage) {
Optional file = getFile(resource);
if (file.isPresent()) {
@@ -119,11 +114,11 @@ public class ResourceHttpMessageWriter extends EncoderHttpMessageWriter getFile(Resource resource) {
- if (ResourceUtils.hasFile(resource)) {
+ if (resource.isFile()) {
try {
return Optional.of(resource.getFile());
}
- catch (IOException ignored) {
+ catch (IOException ex) {
// should not happen
}
}
diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
index 0a042f4384a..81d3fd1e5e2 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
@@ -16,20 +16,16 @@
package org.springframework.web.accept;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.Locale;
import java.util.Map;
-import javax.activation.FileTypeMap;
-import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
+import org.springframework.http.MediaTypeFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -128,7 +124,7 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
throws HttpMediaTypeNotAcceptableException {
if (this.useJaf && JAF_PRESENT) {
- MediaType mediaType = JafMediaTypeFactory.getMediaType("file." + extension);
+ MediaType mediaType = MediaTypeFactory.getMediaType("file." + extension);
if (mediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
return mediaType;
}
@@ -157,7 +153,7 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
mediaType = lookupMediaType(extension);
}
if (mediaType == null && JAF_PRESENT) {
- mediaType = JafMediaTypeFactory.getMediaType(filename);
+ mediaType = MediaTypeFactory.getMediaType(filename);
}
if (MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
mediaType = null;
@@ -165,56 +161,4 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
return mediaType;
}
-
- /**
- * Inner class to avoid hard-coded dependency on JAF.
- */
- private static class JafMediaTypeFactory {
-
- private static final FileTypeMap fileTypeMap;
-
- static {
- fileTypeMap = initFileTypeMap();
- }
-
- /**
- * Find extended mime.types from the spring-context-support module.
- */
- private static FileTypeMap initFileTypeMap() {
- Resource resource = new ClassPathResource("org/springframework/mail/javamail/mime.types");
- if (resource.exists()) {
- if (logger.isTraceEnabled()) {
- logger.trace("Loading JAF FileTypeMap from " + resource);
- }
- InputStream inputStream = null;
- try {
- inputStream = resource.getInputStream();
- return new MimetypesFileTypeMap(inputStream);
- }
- catch (IOException ex) {
- // ignore
- }
- finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- }
- catch (IOException ex) {
- // ignore
- }
- }
- }
- }
- if (logger.isTraceEnabled()) {
- logger.trace("Loading default Java Activation Framework FileTypeMap");
- }
- return FileTypeMap.getDefaultFileTypeMap();
- }
-
- public static MediaType getMediaType(String filename) {
- String mediaType = fileTypeMap.getContentType(filename);
- return (StringUtils.hasText(mediaType) ? MediaType.parseMediaType(mediaType) : null);
- }
- }
-
}
diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java
index a05b782f8cc..916a4c11949 100644
--- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java
+++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -77,6 +77,7 @@ public class ServletContextResource extends AbstractFileResolvingResource implem
this.path = pathToUse;
}
+
/**
* Return the ServletContext for this resource.
*/
@@ -91,7 +92,6 @@ public class ServletContextResource extends AbstractFileResolvingResource implem
return this.path;
}
-
/**
* This implementation checks {@code ServletContext.getResource}.
* @see javax.servlet.ServletContext#getResource(String)
@@ -129,6 +129,22 @@ public class ServletContextResource extends AbstractFileResolvingResource implem
}
}
+ @Override
+ public boolean isFile() {
+ try {
+ URL url = this.servletContext.getResource(this.path);
+ if (url != null && ResourceUtils.isFileURL(url)) {
+ return true;
+ }
+ else {
+ return (this.servletContext.getRealPath(this.path) != null);
+ }
+ }
+ catch (MalformedURLException ex) {
+ return false;
+ }
+ }
+
/**
* This implementation delegates to {@code ServletContext.getResourceAsStream},
* but throws a FileNotFoundException if no resource found.
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java
index 4c457db2a89..4187758514c 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -103,6 +103,11 @@ public class GzipResourceResolver extends AbstractResourceResolver {
return this.gzipped.isOpen();
}
+ @Override
+ public boolean isFile() {
+ return this.gzipped.isFile();
+ }
+
public URL getURL() throws IOException {
return this.gzipped.getURL();
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java
index c3c6557c347..5f897f7f9d4 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java
@@ -264,6 +264,11 @@ public class VersionResourceResolver extends AbstractResourceResolver {
return this.original.isOpen();
}
+ @Override
+ public boolean isFile() {
+ return this.original.isFile();
+ }
+
@Override
public URL getURL() throws IOException {
return this.original.getURL();