aboutsummaryrefslogtreecommitdiff
path: root/jimfs/src/main
diff options
context:
space:
mode:
authorColin Decker <cgdecker@google.com>2013-10-09 11:55:25 -0400
committerColin Decker <cgdecker@google.com>2013-10-09 11:55:25 -0400
commit7a8cac73d69714f7213c5ef86d90f0ede92e8461 (patch)
tree27208d21053d1822ec9b8d8d70432488bb0acad3 /jimfs/src/main
parent7c069a609098d38381252dc40c90167df291d14b (diff)
downloadjimfs-7a8cac73d69714f7213c5ef86d90f0ede92e8461.tar.gz
Add the ability to configure whether or not links and/or symbolic links are supported.
Diffstat (limited to 'jimfs/src/main')
-rw-r--r--jimfs/src/main/java/com/google/jimfs/Jimfs.java85
-rw-r--r--jimfs/src/main/java/com/google/jimfs/internal/FileSystemView.java4
-rw-r--r--jimfs/src/main/java/com/google/jimfs/internal/JimfsFileStore.java27
-rw-r--r--jimfs/src/main/java/com/google/jimfs/internal/JimfsFileSystems.java3
-rw-r--r--jimfs/src/main/java/com/google/jimfs/path/PathType.java3
5 files changed, 105 insertions, 17 deletions
diff --git a/jimfs/src/main/java/com/google/jimfs/Jimfs.java b/jimfs/src/main/java/com/google/jimfs/Jimfs.java
index a179a42..16109b4 100644
--- a/jimfs/src/main/java/com/google/jimfs/Jimfs.java
+++ b/jimfs/src/main/java/com/google/jimfs/Jimfs.java
@@ -31,6 +31,12 @@ import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -59,12 +65,19 @@ public final class Jimfs {
/**
* Returns a new in-memory file system with semantics similar to UNIX.
*
- * <p>The returned file system has a single root, "/", and uses "/" as a separator. It supports
- * symbolic and hard links. File lookup is case-sensitive. Only the "basic" file attribute view
- * is supported. The working directory for the file system is "/work".
+ * <p>The returned file system:
+ *
+ * <ul>
+ * <li>uses "/" as the path name separator (see {@link PathType#unix()} for more information on
+ * the path format)</li>
+ * <li>has root "/" and working directory "/work"</li>
+ * <li>supports symbolic links and hard links</li>
+ * <li>does case-sensitive lookup</li>
+ * <li>supports only the "basic" file attribute view</li>
+ * </ul>
*
* <p>For more advanced configuration, including changing the working directory, supported
- * attribute views or type of storage to use or for setting the host name to be used in the file
+ * attribute views or supported features or for setting the host name to be used in the file
* system's URI, use {@link #newUnixLikeConfiguration()}.
*/
public static FileSystem newUnixLikeFileSystem() {
@@ -74,7 +87,8 @@ public final class Jimfs {
/**
* Returns a new {@link Configuration} instance with defaults for a UNIX-like file
* system. If no changes are made to the configuration, the file system it creates will be
- * identical to that created by {@link #newUnixLikeFileSystem()}.
+ * identical to that created by {@link #newUnixLikeFileSystem()}. Legal paths are described by
+ * {@link PathType#unix()}. Only one root, "/", is allowed.
*
* <p>Example usage:
*
@@ -90,19 +104,27 @@ public final class Jimfs {
public static Configuration newUnixLikeConfiguration() {
return newConfiguration(PathType.unix())
.addRoots("/")
- .setWorkingDirectory("/work");
+ .setWorkingDirectory("/work")
+ .setSupportedFeatures(Feature.LINKS, Feature.SYMBOLIC_LINKS);
+
}
/**
* Returns a new in-memory file system with semantics similar to Windows.
*
- * <p>The returned file system has a single root, "C:\", and uses "\" as a separator. It also
- * recognizes "/" as a separator when parsing paths. It supports symbolic and hard links. File
- * lookup is not case-sensitive. Only the "basic" file attribute view is supported. The working
- * directory for the file system is "C:\work".
+ * <p>The returned file system:
+ *
+ * <ul>
+ * <li>uses "\" as the path name separator and recognizes "/" as a separator when parsing
+ * paths (see {@link PathType#windows()} for more information on path format)</li>
+ * <li>has root "C:\" and working directory "C:\work"</li>
+ * <li>supports symbolic links but not hard links</li>
+ * <li>does case-insensitive lookup (for ASCII characters only)</li>
+ * <li>supports only the "basic" file attribute view</li>
+ * </ul>
*
* <p>For more advanced configuration, including changing the working directory, supported
- * attribute views or type of storage to use or for setting the host name to be used in the file
+ * attribute views or supported features or for setting the host name to be used in the file
* system's URI, use {@link #newWindowsLikeConfiguration()}.
*/
public static FileSystem newWindowsLikeFileSystem() {
@@ -112,7 +134,8 @@ public final class Jimfs {
/**
* Returns a new {@link Configuration} instance with defaults for a Windows-like file system. If
* no changes are made to the configuration, the file system it creates will be identical to that
- * created by {@link #newWindowsLikeFileSystem()}.
+ * created by {@link #newWindowsLikeFileSystem()}. Legal roots and paths are described by
+ * {@link PathType#windows()}.
*
* <p>Example usage:
*
@@ -130,7 +153,8 @@ public final class Jimfs {
public static Configuration newWindowsLikeConfiguration() {
return newConfiguration(PathType.windows())
.addRoots("C:\\")
- .setWorkingDirectory("C:\\work");
+ .setWorkingDirectory("C:\\work")
+ .setSupportedFeatures(Feature.SYMBOLIC_LINKS);
}
/**
@@ -168,6 +192,7 @@ public final class Jimfs {
private String workingDirectory;
private AttributeViews attributes = AttributeViews.basic();
+ private final Set<Feature> supportedFeatures = new HashSet<>();
private Configuration(PathType pathType) {
this.pathType = checkNotNull(pathType);
@@ -213,6 +238,13 @@ public final class Jimfs {
}
/**
+ * Returns the configured set of optional features the file system should support.
+ */
+ public Set<Feature> getSupportedFeatures() {
+ return Collections.unmodifiableSet(supportedFeatures);
+ }
+
+ /**
* Sets the name for the created file system, which will be used as the host part of the URI
* that identifies the file system. For example, if the name is "foo" the file system's URI
* will be "jimfs://foo" and the URI of the path "/bar" on the file system will be
@@ -276,10 +308,37 @@ public final class Jimfs {
}
/**
+ * Sets the optional features the file system should support. Any supported features that were
+ * previously set are replaced.
+ */
+ public Configuration setSupportedFeatures(Feature... features) {
+ supportedFeatures.clear();
+ supportedFeatures.addAll(Arrays.asList(features));
+ return this;
+ }
+
+ /**
* Creates a new file system using this configuration.
*/
public FileSystem createFileSystem() {
return newFileSystem(URI.create(URI_SCHEME + "://" + getName()), this);
}
}
+
+ /**
+ * Optional features that may or may not be supported by a file system.
+ */
+ public static enum Feature {
+ /**
+ * Controls whether or not {@linkplain Files#createLink(Path, Path) hard links to regular files}
+ * are supported.
+ */
+ LINKS,
+
+ /**
+ * Controls whether or not {@linkplain Files#createSymbolicLink(Path, Path, FileAttribute[])
+ * symbolic links} are supported.
+ */
+ SYMBOLIC_LINKS
+ }
}
diff --git a/jimfs/src/main/java/com/google/jimfs/internal/FileSystemView.java b/jimfs/src/main/java/com/google/jimfs/internal/FileSystemView.java
index c229967..18ef445 100644
--- a/jimfs/src/main/java/com/google/jimfs/internal/FileSystemView.java
+++ b/jimfs/src/main/java/com/google/jimfs/internal/FileSystemView.java
@@ -25,6 +25,7 @@ import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
+import com.google.jimfs.Jimfs;
import com.google.jimfs.common.IoSupplier;
import java.io.IOException;
@@ -282,6 +283,7 @@ final class FileSystemView {
*/
public File createSymbolicLink(
JimfsPath path, JimfsPath target, FileAttribute<?>... attrs) throws IOException {
+ store.checkSupported(Jimfs.Feature.SYMBOLIC_LINKS);
return createFile(path, store.createSymbolicLink(target), false, attrs);
}
@@ -421,6 +423,8 @@ final class FileSystemView {
checkNotNull(existingView);
checkNotNull(existing);
+ store.checkSupported(Jimfs.Feature.LINKS);
+
if (!isSameFileSystem(existingView)) {
throw new FileSystemException(link.toString(), existing.toString(),
"can't link: source and target are in different file system instances");
diff --git a/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileStore.java b/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileStore.java
index d283391..e28f185 100644
--- a/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileStore.java
+++ b/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileStore.java
@@ -22,6 +22,7 @@ import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
+import com.google.jimfs.Jimfs;
import com.google.jimfs.attribute.AttributeStore;
import com.google.jimfs.common.IoSupplier;
@@ -32,6 +33,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileStoreAttributeView;
+import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -56,15 +58,18 @@ final class JimfsFileStore extends FileStore {
private final AttributeService attributes;
private final FileFactory factory;
+ private final ImmutableSet<Jimfs.Feature> supportedFeatures;
+
private final Lock readLock;
private final Lock writeLock;
- public JimfsFileStore(
- FileTree tree, FileFactory factory, RegularFileStorage storage, AttributeService attributes) {
+ public JimfsFileStore(FileTree tree, FileFactory factory, RegularFileStorage storage,
+ AttributeService attributes, Set<Jimfs.Feature> supportedFeatures) {
this.tree = checkNotNull(tree);
this.factory = checkNotNull(factory);
this.storage = checkNotNull(storage);
this.attributes = checkNotNull(attributes);
+ this.supportedFeatures = ImmutableSet.copyOf(supportedFeatures);
ReadWriteLock lock = new ReentrantReadWriteLock();
this.readLock = lock.readLock();
@@ -95,6 +100,24 @@ final class JimfsFileStore extends FileStore {
}
/**
+ * Returns whether or not the given feature is supported.
+ */
+ boolean supports(Jimfs.Feature feature) {
+ return supportedFeatures.contains(feature);
+ }
+
+ /**
+ * Checks that the given feature is supported.
+ *
+ * @throws UnsupportedOperationException if the feature is not supported
+ */
+ void checkSupported(Jimfs.Feature feature) {
+ if (!supports(feature)) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
* Returns the root directory with the given name or {@code null} if no such directory exists.
*/
@Nullable
diff --git a/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileSystems.java b/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileSystems.java
index f0fea63..2fa13a0 100644
--- a/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileSystems.java
+++ b/jimfs/src/main/java/com/google/jimfs/internal/JimfsFileSystems.java
@@ -72,7 +72,8 @@ final class JimfsFileSystems {
rootDir.asDirectoryTable().setRoot();
}
- return new JimfsFileStore(new FileTree(superRoot), fileFactory, storage, attributeService);
+ return new JimfsFileStore(new FileTree(superRoot), fileFactory, storage,
+ attributeService, config.getSupportedFeatures());
}
/**
diff --git a/jimfs/src/main/java/com/google/jimfs/path/PathType.java b/jimfs/src/main/java/com/google/jimfs/path/PathType.java
index 57bab32..5e51cea 100644
--- a/jimfs/src/main/java/com/google/jimfs/path/PathType.java
+++ b/jimfs/src/main/java/com/google/jimfs/path/PathType.java
@@ -39,7 +39,8 @@ public abstract class PathType {
/**
* Returns a Unix-style path type. "/" is both the root and the only separator. Any path starting
- * with "/" is considered absolute. Paths are case sensitive.
+ * with "/" is considered absolute. Paths are case sensitive. The nul character ('\0') is
+ * disallowed in paths.
*/
public static PathType unix() {
return UnixPathType.INSTANCE;