You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by jb...@apache.org on 2015/03/17 06:46:48 UTC
svn commit: r1667176 - in /tomcat/sandbox/niofs: src/META-INF/
src/META-INF/services/
src/META-INF/services/java.nio.file.spi.FileSystemProvider
src/niofs/ArchiveFileSystemProvider.java tst/niofs/ClassLoaderTest.java
Author: jboynes
Date: Tue Mar 17 05:46:48 2015
New Revision: 1667176
URL: http://svn.apache.org/r1667176
Log:
NIOFS URI support and tests with URLClassLoader
Added:
tomcat/sandbox/niofs/src/META-INF/
tomcat/sandbox/niofs/src/META-INF/services/
tomcat/sandbox/niofs/src/META-INF/services/java.nio.file.spi.FileSystemProvider
tomcat/sandbox/niofs/tst/niofs/ClassLoaderTest.java (with props)
Modified:
tomcat/sandbox/niofs/src/niofs/ArchiveFileSystemProvider.java
Added: tomcat/sandbox/niofs/src/META-INF/services/java.nio.file.spi.FileSystemProvider
URL: http://svn.apache.org/viewvc/tomcat/sandbox/niofs/src/META-INF/services/java.nio.file.spi.FileSystemProvider?rev=1667176&view=auto
==============================================================================
--- tomcat/sandbox/niofs/src/META-INF/services/java.nio.file.spi.FileSystemProvider (added)
+++ tomcat/sandbox/niofs/src/META-INF/services/java.nio.file.spi.FileSystemProvider Tue Mar 17 05:46:48 2015
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+niofs.ArchiveFileSystemProvider
Modified: tomcat/sandbox/niofs/src/niofs/ArchiveFileSystemProvider.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/niofs/src/niofs/ArchiveFileSystemProvider.java?rev=1667176&r1=1667175&r2=1667176&view=diff
==============================================================================
--- tomcat/sandbox/niofs/src/niofs/ArchiveFileSystemProvider.java (original)
+++ tomcat/sandbox/niofs/src/niofs/ArchiveFileSystemProvider.java Tue Mar 17 05:46:48 2015
@@ -21,6 +21,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.channels.NonWritableChannelException;
import java.nio.channels.SeekableByteChannel;
@@ -29,6 +30,7 @@ import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
+import java.nio.file.FileSystemNotFoundException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
@@ -36,6 +38,7 @@ import java.nio.file.NotDirectoryExcepti
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
import java.nio.file.ProviderMismatchException;
import java.nio.file.ReadOnlyFileSystemException;
import java.nio.file.StandardOpenOption;
@@ -55,37 +58,61 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
+import static java.net.URLEncoder.encode;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
/**
* A provider for read-only filesystems based on an underlying archive file in ZIP format.
*/
public class ArchiveFileSystemProvider extends FileSystemProvider {
+ private static final String UTF8 = UTF_8.toString();
+
+ private final Map<String, ArchiveFileSystem> fileSystems = new ConcurrentHashMap<>();
@Override
public String getScheme() {
return "archive";
}
- // TODO: We will need to support URIs in order to support converting paths to URLs.
@Override
- public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
- throw new UnsupportedOperationException();
+ public ArchiveFileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
+ String name = uri.getAuthority();
+ ArchiveFileSystem fileSystem = fileSystems.get(name);
+ if (fileSystem == null) {
+ fileSystem = newFileSystem(Paths.get(URI.create(name)), env);
+ fileSystems.put(name, fileSystem);
+ }
+ return fileSystem;
}
@Override
- public FileSystem getFileSystem(URI uri) {
- throw new UnsupportedOperationException();
+ public ArchiveFileSystem getFileSystem(URI uri) {
+ ArchiveFileSystem fileSystem = fileSystems.get(uri.getAuthority());
+ if (fileSystem == null) {
+ throw new FileSystemNotFoundException();
+ }
+ return fileSystem;
}
@Override
public Path getPath(URI uri) {
- throw new UnsupportedOperationException();
+ if (!getScheme().equals(uri.getScheme())) {
+ throw new ProviderMismatchException(uri.toString());
+ }
+ String name = uri.getAuthority();
+ FileSystem fileSystem = fileSystems.get(name);
+ if (fileSystem == null) {
+ throw new FileSystemNotFoundException(name);
+ }
+ return fileSystem.getPath(uri.getPath());
}
@Override
- public FileSystem newFileSystem(Path path, Map<String, ?> env) throws IOException {
+ public ArchiveFileSystem newFileSystem(Path path, Map<String, ?> env) throws IOException {
return new ArchiveFileSystem(path, env);
}
@@ -233,10 +260,16 @@ public class ArchiveFileSystemProvider e
*
*/
class ArchiveFileSystem extends FileSystem {
- private volatile boolean open = true;
+ private final URI baseURI;
private final Map<Path, DirectoryNode> directory;
+ private volatile boolean open = true;
public ArchiveFileSystem(Path path, Map<String, ?> env) throws IOException {
+ try {
+ baseURI = new URI(getScheme() + "://" + encode(path.toUri().toString(), UTF8));
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
directory = createIndex(path);
}
@@ -365,6 +398,9 @@ public class ArchiveFileSystemProvider e
@Override
public int read(ByteBuffer dst) throws IOException {
int size = Math.min(dst.remaining(), node.data.length - position);
+ if (size == 0) {
+ return -1;
+ }
dst.put(node.data, position, size);
position += size;
return size;
@@ -454,7 +490,7 @@ public class ArchiveFileSystemProvider e
} else {
StringBuilder builder = new StringBuilder(first);
for (String s : more) {
- builder.append(s);
+ builder.append(getSeparator()).append(s);
}
path = builder.toString();
}
@@ -564,7 +600,7 @@ public class ArchiveFileSystemProvider e
@Override
public URI toUri() {
- throw new UnsupportedOperationException();
+ return baseURI.resolve(path);
}
@Override
Added: tomcat/sandbox/niofs/tst/niofs/ClassLoaderTest.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/niofs/tst/niofs/ClassLoaderTest.java?rev=1667176&view=auto
==============================================================================
--- tomcat/sandbox/niofs/tst/niofs/ClassLoaderTest.java (added)
+++ tomcat/sandbox/niofs/tst/niofs/ClassLoaderTest.java Tue Mar 17 05:46:48 2015
@@ -0,0 +1,138 @@
+/*
+ * 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 niofs;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static java.net.URLEncoder.encode;
+import static org.junit.Assert.assertEquals;
+
+/**
+ *
+ */
+public class ClassLoaderTest {
+ @BeforeClass
+ public static void initURLHandler() {
+ // Need this to even construct URLs.
+ URLStreamHandlerFactory factory = protocol -> {
+ switch (protocol) {
+ case "archive":
+ return new URLStreamHandler() {
+ @Override
+ protected URLConnection openConnection(URL u) throws IOException {
+ URI archive = URI.create("archive://" + u.getHost());
+ FileSystem fileSystem = FileSystems.getFileSystem(archive);
+ Path path = fileSystem.getPath(u.getPath());
+ return new URLConnection(u) {
+ @Override
+ public void connect() throws IOException {
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return Files.newInputStream(path);
+ }
+ };
+ }
+ };
+ default:
+ return null;
+ }
+ };
+ URL.setURLStreamHandlerFactory(factory);
+ }
+
+ private ClassLoader classLoader;
+
+ @Before
+ public void initClassLoader() throws IOException {
+ ArchiveFileSystemProvider provider = new ArchiveFileSystemProvider();
+ Path war = FileSystems.getDefault().getPath("greenhouse-1.0.0.BUILD-SNAPSHOT.war");
+ URI warURI = URI.create(provider.getScheme() + "://" + encode(war.toUri().toString(), "UTF8"));
+ FileSystem fileSystem = FileSystems.newFileSystem(warURI, Collections.emptyMap());
+ URL[] urls = Files.list(fileSystem.getPath(fileSystem.getSeparator() + "WEB-INF", "lib"))
+ .filter(path -> path.getFileName().toString().matches(".*\\.(zip|jar)$"))
+ .map(path -> {
+ try {
+ return URI.create(provider.getScheme() + "://" + encode(path.toUri().toString(), "UTF8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException(e);
+ }
+ })
+ .peek(uri -> {
+ try {
+ FileSystems.newFileSystem(uri, Collections.emptyMap());
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ })
+ .map(uri -> {
+ try {
+ return new URL(uri.toString() + '/');
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ })
+ .toArray(URL[]::new);
+ classLoader = new URLClassLoader(urls);
+ }
+
+ @Test
+ public void testLoadable() throws ClassNotFoundException {
+ Class<?> inject = classLoader.loadClass("javax.inject.Inject");
+ assertEquals("Inject", inject.getSimpleName());
+ }
+
+ @Test
+ public void loadAllResources() throws IOException {
+ // Read all the paths in we are meant to open;
+ Set<String> paths;
+ try (BufferedReader reader = new BufferedReader(new FileReader("urls.log"))) {
+ paths = reader.lines()
+ .map(line -> line.split(" ")[1])
+ .collect(Collectors.toSet());
+ }
+ long time = -System.nanoTime();
+ Set<?> urls = paths.stream()
+ .map(classLoader::getResource)
+ .collect(Collectors.toSet());
+ time += System.nanoTime();
+ System.out.printf("Found %d resources in %dms\n", urls.size(), time / 1000000);
+ assertEquals(paths.size(), urls.size());
+ }
+}
Propchange: tomcat/sandbox/niofs/tst/niofs/ClassLoaderTest.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org