WICKET-6025 Read resource files with Java's NIO API

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/e0c2f1bb
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/e0c2f1bb
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/e0c2f1bb

Branch: refs/heads/lambdas
Commit: e0c2f1bbae576d26f2dc54996905e9acb63ccca0
Parents: 6355d71
Author: Tobias Soloschenko <[email protected]>
Authored: Sun Nov 1 09:22:57 2015 +0100
Committer: Tobias Soloschenko <[email protected]>
Committed: Fri Nov 6 22:41:38 2015 +0100

----------------------------------------------------------------------
 .../FileSystemResourceStreamReference.java      |  29 +++
 .../wicket/resource/FileSystemResource.java     | 130 +++++++++++
 .../resource/FileSystemResourceReference.java   | 170 +++++++++++++++
 .../services/java.nio.file.spi.FileTypeDetector |   1 +
 .../wicket/filetype/TestFileTypeDetector.java   |  42 ++++
 .../resource/FileSystemResourceReference.txt    |   1 +
 .../resource/FileSystemResourceReference.uke    |   1 +
 .../FileSystemResourceReferenceTest.java        | 218 +++++++++++++++++++
 .../FileSystemResourceReferenceTest.zip         | Bin 0 -> 986 bytes
 .../util/resource/FileSystemResourceStream.java | 169 ++++++++++++++
 10 files changed, 761 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/main/java/org/apache/wicket/core/util/resource/locator/caching/FileSystemResourceStreamReference.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/core/util/resource/locator/caching/FileSystemResourceStreamReference.java
 
b/wicket-core/src/main/java/org/apache/wicket/core/util/resource/locator/caching/FileSystemResourceStreamReference.java
new file mode 100644
index 0000000..1feae37
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/core/util/resource/locator/caching/FileSystemResourceStreamReference.java
@@ -0,0 +1,29 @@
+package org.apache.wicket.core.util.resource.locator.caching;
+
+import java.nio.file.Paths;
+
+import org.apache.wicket.util.resource.FileSystemResourceStream;
+
+/**
+ * A reference which can be used to recreate {@link FileSystemResourceStream}
+ * 
+ * @author Tobias Soloschenko
+ */
+public class FileSystemResourceStreamReference extends 
AbstractResourceStreamReference
+{
+       private final String absolutePath;
+
+       FileSystemResourceStreamReference(final FileSystemResourceStream 
fileSystemResourceStream)
+       {
+               absolutePath = 
fileSystemResourceStream.getPath().toAbsolutePath().toString();
+               saveResourceStream(fileSystemResourceStream);
+       }
+
+       @Override
+       public FileSystemResourceStream getReference()
+       {
+               FileSystemResourceStream fileSystemResourceStream = new 
FileSystemResourceStream(Paths.get(absolutePath));
+               restoreResourceStream(fileSystemResourceStream);
+               return fileSystemResourceStream;
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResource.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResource.java 
b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResource.java
new file mode 100644
index 0000000..56e1b95
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResource.java
@@ -0,0 +1,130 @@
+/*
+ * 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 org.apache.wicket.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.apache.wicket.request.resource.PartWriterCallback;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * Used to provide resources based on the on Java NIO FileSystem API.<br>
+ * <br>
+ * For more information see {@link 
org.apache.wicket.markup.html.media.FileSystemResourceReference}
+ * 
+ * @author Tobias Soloschenko
+ *
+ */
+public class FileSystemResource extends AbstractResource
+{
+       private static final long serialVersionUID = 1L;
+
+       private final Path path;
+
+       /**
+        * Creates a new file system resource based on the given path
+        * 
+        * @param path
+        *            the path to be read for the resource
+        */
+       public FileSystemResource(Path path)
+       {
+               Args.notNull(path, "path");
+               this.path = path;
+       }
+
+       /**
+        * Creates a new resource response and reads the given path
+        */
+       @Override
+       protected ResourceResponse newResourceResponse(Attributes attributes)
+       {
+               try
+               {
+                       long size = getSize();
+                       ResourceResponse resourceResponse = new 
ResourceResponse();
+                       resourceResponse.setContentType(getMimeType());
+                       resourceResponse.setAcceptRange(ContentRangeType.BYTES);
+                       resourceResponse.setContentLength(size);
+                       RequestCycle cycle = RequestCycle.get();
+                       Long startbyte = 
cycle.getMetaData(CONTENT_RANGE_STARTBYTE);
+                       Long endbyte = cycle.getMetaData(CONTENT_RANGE_ENDBYTE);
+                       resourceResponse.setWriteCallback(new 
PartWriterCallback(getInputStream(), size,
+                               startbyte, endbyte));
+                       return resourceResponse;
+               }
+               catch (IOException e)
+               {
+                       throw new WicketRuntimeException(
+                               "An error occured while processing the media 
resource response", e);
+               }
+       }
+
+       /**
+        * Gets the size of the resource
+        * 
+        * @return the size of the resource
+        * @throws IOException
+        *             if the size attribute can't be read
+        */
+       protected long getSize() throws IOException
+       {
+               return Files.readAttributes(path, 
BasicFileAttributes.class).size();
+       }
+
+       /**
+        * Gets the mime type to be used for the response it first uses the URL 
connection to get the
+        * mime type and after this the FileTypeDetector SPI is used.
+        * 
+        * @return the mime type to be used for the response
+        * @throws IOException
+        *             if the mime type could'nt be resoulved
+        */
+       protected String getMimeType() throws IOException
+       {
+               String mimeType = null;
+               if (Application.exists())
+               {
+                       mimeType = 
Application.get().getMimeType(path.getFileName().toString());
+               }
+               if (mimeType == null)
+               {
+                       mimeType = Files.probeContentType(path);
+               }
+               return mimeType;
+       }
+
+       /**
+        * Gets the input stream of the given path
+        * 
+        * @return the input stream of the given path
+        * @throws IOException
+        *             if there is an exception while receiving the input stream
+        */
+       protected InputStream getInputStream() throws IOException
+       {
+               return Files.newInputStream(path);
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResourceReference.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResourceReference.java
 
b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResourceReference.java
new file mode 100644
index 0000000..e10fe54
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResourceReference.java
@@ -0,0 +1,170 @@
+/*
+ * 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 org.apache.wicket.resource;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.MetaDataKey;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * This resource reference is used to provide a reference to a resource based 
on Java NIO FileSystem
+ * API.<br>
+ * <br>
+ * To implement a mime type detection refer to the documentation of
+ * {@link java.nio.file.Files#probeContentType(Path)} and provide an 
implementation for
+ * java.nio.file.spi.FileTypeDetector in the META-INF/services folder for jars 
or in the
+ * /WEB-INF/classes/META-INF/services folder for webapps<br>
+ * <br>
+ * You can optionally override {@link #getFileSystemResource()} to provide an 
inline mime type detection,
+ * which is preferred to the default detection.<br>
+ * <br>
+ * Example:
+ * 
+ * <pre>
+ * <code>
+ * Path path = 
FileSystemResourceReference.getPath(URI.create("jar:file:///folder/file.zip!/folderInZip/video.mp4"));
+ * add(new Video("video", new FileSystemResourceReference(path)));
+ * </code>
+ * </pre>
+ * 
+ * @author Tobias Soloschenko
+ */
+public class FileSystemResourceReference extends ResourceReference
+{
+       private static final long serialVersionUID = 1L;
+
+       private final Path path;
+
+       /** The key for the file system meta data **/
+       public static final MetaDataKey<Map<URI, FileSystem>> 
FILE_SYSTEM_META_DATA_KEY = new MetaDataKey<Map<URI, FileSystem>>()
+       {
+               private static final long serialVersionUID = 1L;
+       };
+
+       /**
+        * Creates a file system resource reference based on the given path
+        * 
+        * @param name
+        *            the name of the resource reference to expose data
+        * @param path
+        *            the path to create the resource reference
+        */
+       public FileSystemResourceReference(String name, Path path)
+       {
+               super(name);
+               Args.notNull(path, "path");
+               this.path = path;
+       }
+
+       /**
+        * Creates a new {@link 
org.apache.wicket.markup.html.media.FileSystemResource} and applies the
+        * path to it.
+        */
+       @Override
+       public IResource getResource()
+       {
+               return getFileSystemResource();
+       }
+
+       /**
+        * Gets the file system resource to be used for the resource reference
+        * 
+        * @return the file system resource to be used for the resource 
reference
+        */
+       protected FileSystemResource getFileSystemResource()
+       {
+               return new FileSystemResource(path);
+       }
+
+       /**
+        * Creates a path and a file system (if required) based on the given URI
+        * 
+        * @param uri
+        *            the URI to create the file system and the path of
+        * @param env
+        *            the environment parameter to create the file system with
+        * @return the path of the file in the file system
+        * @throws IOException
+        *             if the file system could'nt be created
+        * @throws URISyntaxException
+        *             if the URI has no valid syntax
+        */
+       public static Path getPath(URI uri, Map<String, String> env) throws 
IOException,
+               URISyntaxException
+       {
+               String uriString = uri.toString();
+               int indexOfExclamationMark = uriString.indexOf('!');
+               if (indexOfExclamationMark == -1)
+               {
+                       return Paths.get(uri);
+               }
+               String zipFile = uriString.substring(0, indexOfExclamationMark);
+               FileSystem fileSystem = null;
+
+               synchronized (FILE_SYSTEM_META_DATA_KEY)
+               {
+                       Map<URI, FileSystem> metaData = Application.get()
+                               .getMetaData(FILE_SYSTEM_META_DATA_KEY);
+                       if (metaData == null)
+                       {
+                               metaData = new HashMap<URI, FileSystem>();
+                               
Application.get().setMetaData(FILE_SYSTEM_META_DATA_KEY, metaData);
+                       }
+                       if (fileSystem == null)
+                       {
+                               if (env == null)
+                               {
+                                       env = new HashMap<>();
+                                       env.put("create", "true");
+                                       env.put("encoding", "UTF-8");
+                               }
+                               fileSystem = FileSystems.newFileSystem(new 
URI(zipFile), env);
+                               metaData.put(uri, fileSystem);
+                       }
+               }
+               String fileName = uriString.substring(uriString.indexOf('!') + 
1);
+               return fileSystem.getPath(fileName);
+       }
+
+       /**
+        * Creates a path and a file system (if required) based on the given URI
+        * 
+        * @param uri
+        *            the URI to create the file system and the path of
+        * @return the path of the file in the file system
+        * @throws IOException
+        *             if the file system could'nt be created
+        * @throws URISyntaxException
+        *             if the URI has no valid syntax
+        */
+       public static Path getPath(URI uri) throws IOException, 
URISyntaxException
+       {
+               return getPath(uri, null);
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/test/java/META-INF/services/java.nio.file.spi.FileTypeDetector
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/META-INF/services/java.nio.file.spi.FileTypeDetector
 
b/wicket-core/src/test/java/META-INF/services/java.nio.file.spi.FileTypeDetector
new file mode 100644
index 0000000..475e050
--- /dev/null
+++ 
b/wicket-core/src/test/java/META-INF/services/java.nio.file.spi.FileTypeDetector
@@ -0,0 +1 @@
+org.apache.wicket.filetype.TestFileTypeDetector
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/test/java/org/apache/wicket/filetype/TestFileTypeDetector.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/filetype/TestFileTypeDetector.java
 
b/wicket-core/src/test/java/org/apache/wicket/filetype/TestFileTypeDetector.java
new file mode 100644
index 0000000..115bebe
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/filetype/TestFileTypeDetector.java
@@ -0,0 +1,42 @@
+/*
+ * 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 org.apache.wicket.filetype;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.spi.FileTypeDetector;
+
+/**
+ * File type detector for unit tests of file system resource reference
+ * 
+ * @author Tobias Soloschenko
+ *
+ */
+public class TestFileTypeDetector extends FileTypeDetector
+{
+
+       @Override
+       public String probeContentType(Path path) throws IOException
+       {
+               
if(path.getFileName().toString().contains("FileSystemResourceReference")){      
                
+                       return "text/plain_provided_by_detector";
+               }else{
+                       return null;
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.txt
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.txt
 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.txt
new file mode 100644
index 0000000..3fa4830
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.txt
@@ -0,0 +1 @@
+FileSystemResourceReference.zip content in normal file
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.uke
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.uke
 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.uke
new file mode 100644
index 0000000..3fa4830
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReference.uke
@@ -0,0 +1 @@
+FileSystemResourceReference.zip content in normal file
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.java
new file mode 100644
index 0000000..acbb986
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.java
@@ -0,0 +1,218 @@
+/*
+ * 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 org.apache.wicket.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+
+import org.apache.wicket.util.io.ByteArrayOutputStream;
+import org.apache.wicket.util.io.IOUtils;
+import org.apache.wicket.util.tester.WicketTestCase;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for FileSystemResourceReference
+ * 
+ * @author Tobias Soloschenko
+ *
+ */
+public class FileSystemResourceReferenceTest extends WicketTestCase
+{
+
+       /**
+        * Test ZIP files
+        * 
+        * @throws IOException
+        *             if the ZIP file or the file content can't be read
+        * @throws URISyntaxException
+        *             if the URI is not readable
+        */
+       @Test
+       public void testFileSystemResourceReferenceWithZip() throws 
IOException, URISyntaxException
+       {
+               InputStream inputStream = null;
+               try
+               {
+                       URL resource = 
FileSystemResourceReferenceTest.class.getResource("FileSystemResourceReferenceTest.zip");
+                       Path path = 
FileSystemResourceReference.getPath(URI.create("jar:" + resource.toURI() +
+                               
"!/folderInZip/FileSystemResourceReference.txt"));
+                       final FileSystemResource fileSystemResource = new 
FileSystemResource(path);
+                       FileSystemResourceReference fileSystemResourceReference 
= new FileSystemResourceReference(
+                               "test", path)
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               protected FileSystemResource 
getFileSystemResource()
+                               {
+                                       return fileSystemResource;
+                               }
+                       };
+                       // Size
+                       Assert.assertEquals(fileSystemResource.getSize(), 39);
+
+                       // Content
+                       inputStream = fileSystemResource.getInputStream();
+                       ByteArrayOutputStream outputStream = new 
ByteArrayOutputStream();
+                       IOUtils.copy(inputStream, outputStream);
+                       Assert.assertEquals("FileSystemResourceReference.zip 
content", outputStream.toString());
+               }
+               finally
+               {
+                       IOUtils.closeQuietly(inputStream);
+               }
+       }
+
+       /**
+        * Test normal files
+        * 
+        * @throws IOException
+        *             if the file can't be read
+        * @throws URISyntaxException
+        *             if the URI is not readable
+        */
+       @Test
+       public void testFileSystemResourceReferenceWithNormalFile() throws 
IOException,
+               URISyntaxException
+       {
+               InputStream inputStream = null;
+               try
+               {
+                       URL resource = 
FileSystemResourceReferenceTest.class.getResource("FileSystemResourceReference.txt");
+                       Path path = 
FileSystemResourceReference.getPath(resource.toURI());
+                       final FileSystemResource fileSystemResource = new 
FileSystemResource(path);
+                       FileSystemResourceReference fileSystemResourceReference 
= new FileSystemResourceReference(
+                               "test", path)
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               protected FileSystemResource 
getFileSystemResource()
+                               {
+                                       return fileSystemResource;
+                               }
+                       };
+                       // Size
+                       Assert.assertEquals(fileSystemResource.getSize(), 54);
+
+                       // Content
+                       inputStream = fileSystemResource.getInputStream();
+                       ByteArrayOutputStream outputStream = new 
ByteArrayOutputStream();
+                       IOUtils.copy(inputStream, outputStream);
+                       Assert.assertEquals("FileSystemResourceReference.zip 
content in normal file",
+                               outputStream.toString());
+               }
+               finally
+               {
+                       IOUtils.closeQuietly(inputStream);
+               }
+       }
+
+       /**
+        * Test mime types
+        * 
+        * @throws IOException
+        *             if the file or the mime type can't be read
+        * @throws URISyntaxException
+        *             if the URI is not readable
+        */
+       @Test
+       public void testMimeTypeEqual() throws IOException, URISyntaxException
+       {
+               URL resource = 
FileSystemResourceReferenceTest.class.getResource("FileSystemResourceReference.txt");
+               Path path = 
FileSystemResourceReference.getPath(resource.toURI());
+               final FileSystemResource fileSystemResource = new 
FileSystemResource(path)
+               {
+
+                       private static final long serialVersionUID = 1L;
+
+                       protected String getMimeType() throws IOException
+                       {
+                               return "test/mime1";
+                       }
+               };
+               FileSystemResourceReference fileSystemResourceReference = new 
FileSystemResourceReference(
+                       "test", path)
+               {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       protected FileSystemResource getFileSystemResource()
+                       {
+                               return fileSystemResource;
+                       }
+               };
+               Assert.assertEquals("test/mime1", 
fileSystemResource.getMimeType());
+       }
+
+       /**
+        * Test mime type detection with java.nio.file.spi.FileTypeDetector
+        * 
+        * @throws IOException
+        *             if the file can't be read
+        * @throws URISyntaxException
+        *             if the
+        */
+       @Test
+       public void testMimeTypeDetection() throws IOException, 
URISyntaxException
+       {
+               // uke > unknown extension :-)
+               URL resource = 
FileSystemResourceReferenceTest.class.getResource("FileSystemResourceReference.uke");
+               Path path = 
FileSystemResourceReference.getPath(resource.toURI());
+
+               final FileSystemResource fileSystemResource = new 
FileSystemResource(path);
+               FileSystemResourceReference fileSystemResourceReference = new 
FileSystemResourceReference(
+                       "test", path)
+               {
+                       private static final long serialVersionUID = 1L;
+
+                       protected FileSystemResource getFileSystemResource()
+                       {
+                               return fileSystemResource;
+
+                       }
+               };
+               Assert.assertEquals("text/plain_provided_by_detector", 
fileSystemResource.getMimeType());
+
+               final FileSystemResource fileSystemResourceMime = new 
FileSystemResource(path)
+               {
+                       private static final long serialVersionUID = 1L;
+
+                       protected String getMimeType() throws IOException
+                       {
+                               return "text/plain";
+                       }
+               };
+               FileSystemResourceReference 
fileSystemResourceReferenceOverriddenMime = new FileSystemResourceReference(
+                       "test", path)
+               {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       protected FileSystemResource getFileSystemResource()
+                       {
+                               return fileSystemResourceMime;
+                       }
+               };
+               Assert.assertEquals("text/plain", 
fileSystemResourceMime.getMimeType());
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.zip
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.zip
 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.zip
new file mode 100644
index 0000000..7b77d43
Binary files /dev/null and 
b/wicket-core/src/test/java/org/apache/wicket/resource/FileSystemResourceReferenceTest.zip
 differ

http://git-wip-us.apache.org/repos/asf/wicket/blob/e0c2f1bb/wicket-util/src/main/java/org/apache/wicket/util/resource/FileSystemResourceStream.java
----------------------------------------------------------------------
diff --git 
a/wicket-util/src/main/java/org/apache/wicket/util/resource/FileSystemResourceStream.java
 
b/wicket-util/src/main/java/org/apache/wicket/util/resource/FileSystemResourceStream.java
new file mode 100644
index 0000000..61bd226
--- /dev/null
+++ 
b/wicket-util/src/main/java/org/apache/wicket/util/resource/FileSystemResourceStream.java
@@ -0,0 +1,169 @@
+package org.apache.wicket.util.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+
+import org.apache.wicket.util.file.File;
+import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.lang.Bytes;
+import org.apache.wicket.util.time.Time;
+
+/**
+ * A FileSystemResourceStream is an IResourceStream implementation for Java 
NIO paths.
+ * 
+ * @see org.apache.wicket.util.resource.IResourceStream
+ * @see org.apache.wicket.util.watch.IModifiable
+ * @author Tobias Soloschenko
+ */
+public class FileSystemResourceStream extends AbstractResourceStream
+       implements
+               IFixedLocationResourceStream
+{
+       private static final long serialVersionUID = 1L;
+
+       /** Any associated path */
+       private final Path path;
+
+       /** Resource stream */
+       private transient InputStream inputStream;
+
+       /**
+        * Constructor.
+        * 
+        * @param path
+        *            {@link Path} containing resource
+        */
+       public FileSystemResourceStream(final Path path)
+       {
+               Args.notNull(path, "path");
+               this.path = path;
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param file
+        *            {@link java.io.File} containing resource
+        */
+       public FileSystemResourceStream(final java.io.File file)
+       {
+               Args.notNull(file, "file");
+               this.path = file.toPath();
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param file
+        *            {@link File} containing resource
+        */
+       public FileSystemResourceStream(final File file)
+       {
+               Args.notNull(file, "file");
+               this.path = file.toPath();
+       }
+
+       @Override
+       public InputStream getInputStream() throws 
ResourceStreamNotFoundException
+       {
+               if (inputStream == null)
+               {
+                       try
+                       {
+                               inputStream = Files.newInputStream(path);
+                       }
+                       catch (IOException e)
+                       {
+                               throw new 
ResourceStreamNotFoundException("Input stream of path " + path +
+                                       " could not be acquired", e);
+                       }
+               }
+               return inputStream;
+       }
+
+       @Override
+       public void close() throws IOException
+       {
+               if (inputStream != null)
+               {
+                       inputStream.close();
+                       inputStream = null;
+               }
+       }
+
+       @Override
+       public String getContentType()
+       {
+               try
+               {
+                       String contentType = Files.probeContentType(path);
+                       if (contentType == null)
+                       {
+                               contentType = 
URLConnection.getFileNameMap().getContentTypeFor(
+                                       path.getFileName().toString());
+                       }
+                       return contentType;
+               }
+               catch (IOException e)
+               {
+                       throw new RuntimeException("Content type of path " + 
path + " could not be acquired", e);
+               }
+       }
+
+       /**
+        * @return The path this resource resides in, if any.
+        */
+       public final Path getPath()
+       {
+               return path;
+       }
+
+       @Override
+       public Time lastModifiedTime()
+       {
+               try
+               {
+                       BasicFileAttributes attributes = 
Files.readAttributes(path, BasicFileAttributes.class);
+                       FileTime lastModifiedTime = 
attributes.lastModifiedTime();
+                       long millis = lastModifiedTime.toMillis();
+                       return Time.millis(millis);
+               }
+               catch (IOException e)
+               {
+                       throw new RuntimeException("Modification time of path " 
+ path +
+                               " could not be acquired", e);
+               }
+       }
+
+       @Override
+       public Bytes length()
+       {
+               try
+               {
+                       BasicFileAttributes attributes = 
Files.readAttributes(path, BasicFileAttributes.class);
+                       long size = attributes.size();
+                       return Bytes.bytes(size);
+               }
+               catch (IOException e)
+               {
+                       throw new RuntimeException("Length of path " + path + " 
could not be acquired", e);
+               }
+       }
+
+       @Override
+       public String locationAsString()
+       {
+               return path.toString();
+       }
+
+       @Override
+       public String toString()
+       {
+               return locationAsString();
+       }
+}

Reply via email to