org.apache.taverna.robundle.fs.BundleFileSystem Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of taverna-robundle Show documentation
Show all versions of taverna-robundle Show documentation
API for dealing with RO Bundles
package org.apache.taverna.robundle.fs;
/*
* 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.
*/
import java.io.IOException;
import java.net.URI;
import java.nio.file.ClosedFileSystemException;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.WatchService;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class BundleFileSystem extends FileSystem {
protected final URI baseURI;
private FileSystem origFS;
private final String separator;
private final Path source;
protected BundleFileSystem(FileSystem origFS, URI baseURI) {
if (origFS == null || baseURI == null) {
throw new NullPointerException();
}
this.origFS = origFS;
this.baseURI = baseURI;
this.separator = origFS.getSeparator();
this.source = findSource();
}
@Override
public void close() throws IOException {
if (origFS == null) {
return;
}
origFS.close();
// De-reference the original ZIP file system so it can be
// garbage collected
origFS = null;
}
protected Path findSource() {
Path zipRoot = getRootDirectory().getZipPath();
URI uri = zipRoot.toUri();
String schemeSpecific;
if (provider().getJarDoubleEscaping()) {
schemeSpecific = uri.getSchemeSpecificPart();
} else {
// http://dev.mygrid.org.uk/issues/browse/T3-954
schemeSpecific = uri.getRawSchemeSpecificPart();
}
if (!schemeSpecific.endsWith("!/")) { // sanity check
throw new IllegalStateException("Can't parse JAR URI: " + uri);
}
URI zip = URI.create(schemeSpecific.substring(0,
schemeSpecific.length() - 2));
return Paths.get(zip); // Look up our path
}
public URI getBaseURI() {
return baseURI;
}
protected BundleFileStore getFileStore() {
// We assume there's only one file store, as is true for ZipProvider
return new BundleFileStore(this, getOrigFS().getFileStores().iterator()
.next());
}
@Override
public Iterable getFileStores() {
return Collections. singleton(getFileStore());
}
/**
* Thread-safe ClosedFileSystemException test
*
* @return
*/
protected FileSystem getOrigFS() {
FileSystem orig = origFS;
if (orig == null || !orig.isOpen()) {
throw new ClosedFileSystemException();
}
return orig;
}
@Override
public Path getPath(String first, String... more) {
Path zipPath = getOrigFS().getPath(first, more);
return wrap(zipPath);
}
@Override
public PathMatcher getPathMatcher(String syntaxAndPattern) {
final PathMatcher zipMatcher = getOrigFS().getPathMatcher(
syntaxAndPattern);
return new PathMatcher() {
@Override
public boolean matches(Path path) {
return zipMatcher.matches(unwrap(path));
}
};
}
@Override
public Iterable getRootDirectories() {
return Collections. singleton(getRootDirectory());
}
public BundlePath getRootDirectory() {
return wrap(getOrigFS().getRootDirectories().iterator().next());
}
@Override
public String getSeparator() {
return separator;
}
public Path getSource() {
return source;
}
@Override
public UserPrincipalLookupService getUserPrincipalLookupService() {
throw new UnsupportedOperationException();
}
@Override
public boolean isOpen() {
if (origFS == null) {
return false;
}
return origFS.isOpen();
}
@Override
public boolean isReadOnly() {
return getOrigFS().isReadOnly();
}
@Override
public WatchService newWatchService() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public BundleFileSystemProvider provider() {
return BundleFileSystemProvider.getInstance();
}
@Override
public Set supportedFileAttributeViews() {
if (origFS == null) {
throw new ClosedFileSystemException();
}
return origFS.supportedFileAttributeViews();
}
protected Path unwrap(Path bundlePath) {
if (!(bundlePath instanceof BundlePath)) {
// assume it's already unwrapped for some reason (for instance being
// null)
return bundlePath;
}
return ((BundlePath) bundlePath).getZipPath();
}
protected BundlePath wrap(Path zipPath) {
if (zipPath == null) {
return null;
}
if (zipPath instanceof BundlePath) {
throw new IllegalArgumentException("Did not expect BundlePath: "
+ zipPath);
}
return new BundlePath(this, zipPath);
}
protected Iterator wrapIterator(final Iterator iterator) {
return new Iterator() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public Path next() {
return wrap(iterator.next());
}
@Override
public void remove() {
iterator.remove();
}
};
}
}