aboutsummaryrefslogtreecommitdiff
path: root/jimfs/src/main/java/com/google/common/jimfs/JimfsFileStore.java
diff options
context:
space:
mode:
Diffstat (limited to 'jimfs/src/main/java/com/google/common/jimfs/JimfsFileStore.java')
-rw-r--r--jimfs/src/main/java/com/google/common/jimfs/JimfsFileStore.java267
1 files changed, 267 insertions, 0 deletions
diff --git a/jimfs/src/main/java/com/google/common/jimfs/JimfsFileStore.java b/jimfs/src/main/java/com/google/common/jimfs/JimfsFileStore.java
new file mode 100644
index 0000000..910d231
--- /dev/null
+++ b/jimfs/src/main/java/com/google/common/jimfs/JimfsFileStore.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Licensed 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 com.google.common.jimfs;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+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 java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.LinkOption;
+import java.nio.file.NoSuchFileException;
+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;
+import org.checkerframework.checker.nullness.compatqual.NullableDecl;
+
+/**
+ * {@link FileStore} implementation which provides methods for file creation, lookup and attribute
+ * handling.
+ *
+ * <p>Most of these methods are actually implemented in another class: {@link FileTree} for lookup,
+ * {@link FileFactory} for creating and copying files and {@link AttributeService} for attribute
+ * handling. This class merely provides a single API through which to access the functionality of
+ * those classes.
+ *
+ * @author Colin Decker
+ */
+final class JimfsFileStore extends FileStore {
+
+ private final FileTree tree;
+ private final HeapDisk disk;
+ private final AttributeService attributes;
+ private final FileFactory factory;
+ private final ImmutableSet<Feature> supportedFeatures;
+ private final FileSystemState state;
+
+ private final Lock readLock;
+ private final Lock writeLock;
+
+ public JimfsFileStore(
+ FileTree tree,
+ FileFactory factory,
+ HeapDisk disk,
+ AttributeService attributes,
+ ImmutableSet<Feature> supportedFeatures,
+ FileSystemState state) {
+ this.tree = checkNotNull(tree);
+ this.factory = checkNotNull(factory);
+ this.disk = checkNotNull(disk);
+ this.attributes = checkNotNull(attributes);
+ this.supportedFeatures = checkNotNull(supportedFeatures);
+ this.state = checkNotNull(state);
+
+ ReadWriteLock lock = new ReentrantReadWriteLock();
+ this.readLock = lock.readLock();
+ this.writeLock = lock.writeLock();
+ }
+
+ // internal use methods
+
+ /** Returns the file system state object. */
+ FileSystemState state() {
+ return state;
+ }
+
+ /** Returns the read lock for this store. */
+ Lock readLock() {
+ return readLock;
+ }
+
+ /** Returns the write lock for this store. */
+ Lock writeLock() {
+ return writeLock;
+ }
+
+ /** Returns the names of the root directories in this store. */
+ ImmutableSortedSet<Name> getRootDirectoryNames() {
+ state.checkOpen();
+ return tree.getRootDirectoryNames();
+ }
+
+ /** Returns the root directory with the given name or {@code null} if no such directory exists. */
+ @NullableDecl
+ Directory getRoot(Name name) {
+ DirectoryEntry entry = tree.getRoot(name);
+ return entry == null ? null : (Directory) entry.file();
+ }
+
+ /** Returns whether or not the given feature is supported by this file store. */
+ boolean supportsFeature(Feature feature) {
+ return supportedFeatures.contains(feature);
+ }
+
+ /**
+ * Looks up the file at the given path using the given link options. If the path is relative, the
+ * lookup is relative to the given working directory.
+ *
+ * @throws NoSuchFileException if an element of the path other than the final element does not
+ * resolve to a directory or symbolic link (e.g. it doesn't exist or is a regular file)
+ * @throws IOException if a symbolic link cycle is detected or the depth of symbolic link
+ * recursion otherwise exceeds a threshold
+ */
+ DirectoryEntry lookUp(File workingDirectory, JimfsPath path, Set<? super LinkOption> options)
+ throws IOException {
+ state.checkOpen();
+ return tree.lookUp(workingDirectory, path, options);
+ }
+
+ /** Returns a supplier that creates a new regular file. */
+ Supplier<RegularFile> regularFileCreator() {
+ state.checkOpen();
+ return factory.regularFileCreator();
+ }
+
+ /** Returns a supplier that creates a new directory. */
+ Supplier<Directory> directoryCreator() {
+ state.checkOpen();
+ return factory.directoryCreator();
+ }
+
+ /** Returns a supplier that creates a new symbolic link with the given target. */
+ Supplier<SymbolicLink> symbolicLinkCreator(JimfsPath target) {
+ state.checkOpen();
+ return factory.symbolicLinkCreator(target);
+ }
+
+ /**
+ * Creates a copy of the given file, copying its attributes as well according to the given {@code
+ * attributeCopyOption}.
+ */
+ File copyWithoutContent(File file, AttributeCopyOption attributeCopyOption) throws IOException {
+ File copy = factory.copyWithoutContent(file);
+ setInitialAttributes(copy);
+ attributes.copyAttributes(file, copy, attributeCopyOption);
+ return copy;
+ }
+
+ /**
+ * Sets initial attributes on the given file. Sets default attributes first, then attempts to set
+ * the given user-provided attributes.
+ */
+ void setInitialAttributes(File file, FileAttribute<?>... attrs) {
+ state.checkOpen();
+ attributes.setInitialAttributes(file, attrs);
+ }
+
+ /**
+ * Returns an attribute view of the given type for the given file lookup callback, or {@code null}
+ * if the view type is not supported.
+ */
+ @NullableDecl
+ <V extends FileAttributeView> V getFileAttributeView(FileLookup lookup, Class<V> type) {
+ state.checkOpen();
+ return attributes.getFileAttributeView(lookup, type);
+ }
+
+ /**
+ * Returns a map containing the attributes described by the given string mapped to their values.
+ */
+ ImmutableMap<String, Object> readAttributes(File file, String attributes) {
+ state.checkOpen();
+ return this.attributes.readAttributes(file, attributes);
+ }
+
+ /**
+ * Returns attributes of the given file as an object of the given type.
+ *
+ * @throws UnsupportedOperationException if the given attributes type is not supported
+ */
+ <A extends BasicFileAttributes> A readAttributes(File file, Class<A> type) {
+ state.checkOpen();
+ return attributes.readAttributes(file, type);
+ }
+
+ /** Sets the given attribute to the given value for the given file. */
+ void setAttribute(File file, String attribute, Object value) {
+ state.checkOpen();
+ // TODO(cgdecker): Change attribute stuff to avoid the sad boolean parameter
+ attributes.setAttribute(file, attribute, value, false);
+ }
+
+ /** Returns the file attribute views supported by this store. */
+ ImmutableSet<String> supportedFileAttributeViews() {
+ state.checkOpen();
+ return attributes.supportedFileAttributeViews();
+ }
+
+ // methods implementing the FileStore API
+
+ @Override
+ public String name() {
+ return "jimfs";
+ }
+
+ @Override
+ public String type() {
+ return "jimfs";
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ @Override
+ public long getTotalSpace() throws IOException {
+ state.checkOpen();
+ return disk.getTotalSpace();
+ }
+
+ @Override
+ public long getUsableSpace() throws IOException {
+ state.checkOpen();
+ return getUnallocatedSpace();
+ }
+
+ @Override
+ public long getUnallocatedSpace() throws IOException {
+ state.checkOpen();
+ return disk.getUnallocatedSpace();
+ }
+
+ @Override
+ public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
+ state.checkOpen();
+ return attributes.supportsFileAttributeView(type);
+ }
+
+ @Override
+ public boolean supportsFileAttributeView(String name) {
+ state.checkOpen();
+ return attributes.supportedFileAttributeViews().contains(name);
+ }
+
+ @Override
+ public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
+ state.checkOpen();
+ return null; // no supported views
+ }
+
+ @Override
+ public Object getAttribute(String attribute) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+}