From e8cf610388ef6189d975bb1ecf6f859a306bd1ac Mon Sep 17 00:00:00 2001 From: Tobias Soloschenko Date: Sun, 13 Dec 2015 10:45:03 +0100 Subject: [PATCH] WICKET-6025 - FileSystemPathService for FSRR --- .../resource/FileSystemJarPathService.java | 94 +++++++++++++++++++ .../resource/FileSystemPathService.java | 53 +++++++++++ .../wicket/resource/FileSystemResource.java | 4 +- .../resource/FileSystemResourceReference.java | 56 +++-------- ...ache.wicket.resource.FileSystemPathService | 1 + .../docs/guide/resources/resources_15.gdoc | 6 ++ 6 files changed, 168 insertions(+), 46 deletions(-) create mode 100644 wicket-core/src/main/java/org/apache/wicket/resource/FileSystemJarPathService.java create mode 100644 wicket-core/src/main/java/org/apache/wicket/resource/FileSystemPathService.java create mode 100644 wicket-core/src/main/resources/META-INF/services/org.apache.wicket.resource.FileSystemPathService diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemJarPathService.java b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemJarPathService.java new file mode 100644 index 00000000000..87600f4b7b1 --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemJarPathService.java @@ -0,0 +1,94 @@ +/* + * 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.util.HashMap; +import java.util.Map; + +import org.apache.wicket.Application; +import org.apache.wicket.MetaDataKey; +import org.apache.wicket.WicketRuntimeException; + +/** + * Gets the actual path for a jar file system + * + * @author Tobias Soloschenko + * + */ +public class FileSystemJarPathService implements FileSystemPathService +{ + + /** The key for the file system meta data **/ + public static final MetaDataKey> FILE_SYSTEM_META_DATA_KEY = new MetaDataKey>() + { + private static final long serialVersionUID = 1L; + }; + + @Override + public Path getPath(URI uri, Map env) + { + try + { + String uriString = uri.toString(); + int indexOfExclamationMark = uriString.indexOf('!'); + String jarFile = uriString.substring(0, indexOfExclamationMark); + FileSystem fileSystem = null; + + synchronized (FILE_SYSTEM_META_DATA_KEY) + { + Map metaData = Application.get() + .getMetaData(FILE_SYSTEM_META_DATA_KEY); + if (metaData == null) + { + metaData = new HashMap(); + Application.get().setMetaData(FILE_SYSTEM_META_DATA_KEY, metaData); + } + fileSystem = metaData.get(jarFile); + if (fileSystem == null) + { + if (env == null) + { + env = new HashMap<>(); + env.put("create", "true"); + env.put("encoding", "UTF-8"); + } + fileSystem = FileSystems.newFileSystem(new URI(jarFile), env); + metaData.put(jarFile, fileSystem); + } + } + String fileName = uriString.substring(uriString.indexOf('!') + 1); + + return fileSystem.getPath(fileName); + } + catch (IOException | URISyntaxException e) + { + throw new WicketRuntimeException("Error while creating a jar file system", e); + } + } + + @Override + public boolean isResponsible(URI uri) + { + return uri.getScheme().equals("jar") && uri.toString().indexOf('!') != -1; + } +} diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemPathService.java b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemPathService.java new file mode 100644 index 00000000000..11f98ff7a6c --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemPathService.java @@ -0,0 +1,53 @@ +/* + * 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.net.URI; +import java.nio.file.Path; +import java.util.Map; + +/** + * Gets the actual path for a specific file system. Have a look into + * {@link org.apache.wicket.resource.FileSystemJarPathService} to find a reference implementation. + * + * @see org.apache.wicket.resource.FileSystemJarPathService + * @author Tobias Soloschenko + * + */ +public interface FileSystemPathService +{ + /** + * Gets the actual path for a specific file system to work on + * + * @param uri + * the uri to get the path from + * @param env + * environment variables to be applied to the file system + * @return the actual path or null if the implementation is not responsible + * + */ + Path getPath(URI uri, Map env); + + /** + * Checks if the file system path service is responsible to handle the given URI + * + * @param uri + * the URI to detect if the file system path service is responsible + * @return if the file system path service is responsible to handle the given URI + */ + boolean isResponsible(URI uri); +} 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 index 8585567c6f6..6348316683a 100644 --- a/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResource.java +++ b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResource.java @@ -74,8 +74,8 @@ protected ResourceResponse newResourceResponse(Attributes attributes) /** * Creates a resource response based on the given attributes * - * @param attributes - * the attributes to create the resource response on + * @param path + * the path to create the resource response with * @return the actual resource response x */ protected ResourceResponse createResourceResponse(Path path) 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 index d4330c1e77f..b3bf9131a10 100644 --- a/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResourceReference.java +++ b/wicket-core/src/main/java/org/apache/wicket/resource/FileSystemResourceReference.java @@ -19,15 +19,12 @@ 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.Iterator; import java.util.Map; +import java.util.ServiceLoader; -import org.apache.wicket.Application; -import org.apache.wicket.MetaDataKey; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.request.resource.IResource; import org.apache.wicket.request.resource.ResourceReference; @@ -97,12 +94,6 @@ public class FileSystemResourceReference extends ResourceReference private Path path; - /** The key for the file system meta data **/ - public static final MetaDataKey> FILE_SYSTEM_META_DATA_KEY = new MetaDataKey>() - { - private static final long serialVersionUID = 1L; - }; - /** * Creates a file system resource reference based on the given path * @@ -176,48 +167,25 @@ protected FileSystemResource getFileSystemResource() * @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 env) - throws IOException, URISyntaxException { - String uriString = uri.toString(); - int indexOfExclamationMark = uriString.indexOf('!'); - if (indexOfExclamationMark == -1) + Iterator pathServiceIterator = ServiceLoader + .load(FileSystemPathService.class).iterator(); + while (pathServiceIterator.hasNext()) { - return Paths.get(uri); - } - String zipFile = uriString.substring(0, indexOfExclamationMark); - FileSystem fileSystem = null; - - synchronized (FILE_SYSTEM_META_DATA_KEY) - { - Map metaData = Application.get() - .getMetaData(FILE_SYSTEM_META_DATA_KEY); - if (metaData == null) + FileSystemPathService pathService = pathServiceIterator.next(); + if (pathService.isResponsible(uri)) { - metaData = new HashMap(); - Application.get().setMetaData(FILE_SYSTEM_META_DATA_KEY, metaData); - } - fileSystem = metaData.get(zipFile); - if (fileSystem == null) - { - if (env == null) + Path fileSystemPath = pathService.getPath(uri, env); + if (fileSystemPath != null) { - env = new HashMap<>(); - env.put("create", "true"); - env.put("encoding", "UTF-8"); + return fileSystemPath; } - fileSystem = FileSystems.newFileSystem(new URI(zipFile), env); - metaData.put(zipFile, fileSystem); } } - String fileName = uriString.substring(uriString.indexOf('!') + 1); - - return fileSystem.getPath(fileName); + // fall back to just get the path from the URI + return Paths.get(uri); } /** diff --git a/wicket-core/src/main/resources/META-INF/services/org.apache.wicket.resource.FileSystemPathService b/wicket-core/src/main/resources/META-INF/services/org.apache.wicket.resource.FileSystemPathService new file mode 100644 index 00000000000..60615c2f548 --- /dev/null +++ b/wicket-core/src/main/resources/META-INF/services/org.apache.wicket.resource.FileSystemPathService @@ -0,0 +1 @@ +org.apache.wicket.resource.FileSystemJarPathService \ No newline at end of file diff --git a/wicket-user-guide/src/docs/guide/resources/resources_15.gdoc b/wicket-user-guide/src/docs/guide/resources/resources_15.gdoc index 69d61a46386..475473a4c93 100644 --- a/wicket-user-guide/src/docs/guide/resources/resources_15.gdoc +++ b/wicket-user-guide/src/docs/guide/resources/resources_15.gdoc @@ -51,6 +51,12 @@ mountResource("/filecontent/${name}", new FileSystemResourceReference("filesyste }); {code} +FileSystemResourceReference.getPath(uri) uses a FileSystemPathService to setup a path the resource reference can work on. + +So if you write a custom file system you can easily handle every path by adding a *org.apache.wicket.resource.FileSystemPathService* text file into *META-INF/services* and put in your implementation. + +A reference implementation can be found in the java class org.apache.wicket.resource.FileSystemJarPathService. + Further FileSystemProviders and the corresponding FileSystems can be implemented as described here: [http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/filesystemprovider.html|http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/filesystemprovider.html] \ No newline at end of file