All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.robtimus.filesystems.memory.MemoryFileSystemProvider Maven / Gradle / Ivy

There is a newer version: 2.1
Show newest version
/*
 * MemoryFileSystemProvider.java
 * Copyright 2016 Rob Spoor
 *
 * 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.github.robtimus.filesystems.memory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderMismatchException;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.spi.FileSystemProvider;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import com.github.robtimus.filesystems.LinkOptionSupport;
import com.github.robtimus.filesystems.Messages;

/**
 * A provider for in-memory file systems.
 *
 * @author Rob Spoor
 */
public final class MemoryFileSystemProvider extends FileSystemProvider {

    private final MemoryFileSystem fs;

    /**
     * Creates a new in-memory file system provider.
     */
    public MemoryFileSystemProvider() {
        this(MemoryFileStore.INSTANCE);
    }

    // package private for test purposes
    MemoryFileSystemProvider(MemoryFileStore fileStore) {
        fs = new MemoryFileSystem(this, fileStore);
    }

    /**
     * Returns the URI scheme that identifies this provider: {@code memory}.
     */
    @Override
    public String getScheme() {
        return "memory"; //$NON-NLS-1$
    }

    /**
     * Constructs a new {@code FileSystem} object identified by a URI.
     * 

* Because there is only one single in-memory file system that is created automatically, this method will always throw a * {@link FileSystemAlreadyExistsException}. */ @Override public FileSystem newFileSystem(URI uri, Map env) throws IOException { checkURI(uri); throw new FileSystemAlreadyExistsException(); } /** * Returns the single in-memory file system. *

* The URI must have a {@link URI#getScheme() scheme} equal to {@link #getScheme()}. */ @Override public FileSystem getFileSystem(URI uri) { checkURI(uri); return fs; } /** * Return a {@code Path} object by converting the given {@link URI}. *

* The URI must have a {@link URI#getScheme() scheme} equal to {@link #getScheme()}. * Its scheme specific part will be used as the path (either relative or absolute) for the returned {@code Path} object. */ @Override public Path getPath(URI uri) { checkURI(uri); return fs.getPath(uri.getSchemeSpecificPart()); } private void checkURI(URI uri) { if (!uri.isAbsolute()) { throw Messages.uri().notAbsolute(uri); } if (!getScheme().equalsIgnoreCase(uri.getScheme())) { throw Messages.uri().invalidScheme(uri, getScheme()); } } @Override public InputStream newInputStream(Path path, OpenOption... options) throws IOException { return toMemoryPath(path).newInputStream(options); } @Override public OutputStream newOutputStream(Path path, OpenOption... options) throws IOException { return toMemoryPath(path).newOutputStream(options); } @Override public FileChannel newFileChannel(Path path, Set options, FileAttribute... attrs) throws IOException { return toMemoryPath(path).newFileChannel(options, attrs); } @Override public SeekableByteChannel newByteChannel(Path path, Set options, FileAttribute... attrs) throws IOException { return toMemoryPath(path).newByteChannel(options, attrs); } @Override public DirectoryStream newDirectoryStream(Path dir, Filter filter) throws IOException { return toMemoryPath(dir).newDirectoryStream(filter); } @Override public void createDirectory(Path dir, FileAttribute... attrs) throws IOException { toMemoryPath(dir).createDirectory(attrs); } @Override public void createSymbolicLink(Path link, Path target, FileAttribute... attrs) throws IOException { toMemoryPath(link).createSymbolicLink(toMemoryPath(target), attrs); } @Override public void createLink(Path link, Path existing) throws IOException { toMemoryPath(link).createLink(toMemoryPath(existing)); } @Override public void delete(Path path) throws IOException { toMemoryPath(path).delete(); } @Override public boolean deleteIfExists(Path path) throws IOException { return toMemoryPath(path).deleteIfExists(); } @Override public Path readSymbolicLink(Path link) throws IOException { return toMemoryPath(link).readSymbolicLink(); } @Override public void copy(Path source, Path target, CopyOption... options) throws IOException { toMemoryPath(source).copy(toMemoryPath(target), options); } @Override public void move(Path source, Path target, CopyOption... options) throws IOException { toMemoryPath(source).move(toMemoryPath(target), options); } @Override public boolean isSameFile(Path path, Path path2) throws IOException { return toMemoryPath(path).isSameFile(path2); } @Override public boolean isHidden(Path path) throws IOException { return toMemoryPath(path).isHidden(); } @Override public FileStore getFileStore(Path path) throws IOException { return toMemoryPath(path).getFileStore(); } @Override public void checkAccess(Path path, AccessMode... modes) throws IOException { toMemoryPath(path).checkAccess(modes); } /** * Returns a file attribute view of a given type. * This method works in exactly the manner specified by the {@link Files#getFileAttributeView(Path, Class, LinkOption...)} method. *

* This provider supports {@link BasicFileAttributeView} and {@link MemoryFileAttributeView}. * All other classes will result in a {@code null} return value. */ @Override public V getFileAttributeView(Path path, Class type, LinkOption... options) { Objects.requireNonNull(type); if (type == BasicFileAttributeView.class) { boolean followLinks = LinkOptionSupport.followLinks(options); return type.cast(new AttributeView("basic", toMemoryPath(path), followLinks)); //$NON-NLS-1$ } if (type == MemoryFileAttributeView.class) { boolean followLinks = LinkOptionSupport.followLinks(options); return type.cast(new AttributeView("memory", toMemoryPath(path), followLinks)); //$NON-NLS-1$ } return null; } private static final class AttributeView implements MemoryFileAttributeView { private final String name; private final MemoryPath path; private final boolean followLinks; private AttributeView(String name, MemoryPath path, boolean followLinks) { this.name = Objects.requireNonNull(name); this.path = Objects.requireNonNull(path); this.followLinks = followLinks; } @Override public String name() { return name; } @Override public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) throws IOException { path.setTimes(lastModifiedTime, lastAccessTime, createTime, followLinks); } @Override public MemoryFileAttributes readAttributes() throws IOException { return path.readAttributes(followLinks); } @Override public void setReadOnly(boolean value) throws IOException { path.setReadOnly(value, followLinks); } @Override public void setHidden(boolean value) throws IOException { path.setHidden(value, followLinks); } } /** * Reads a file's attributes as a bulk operation. * This method works in exactly the manner specified by the {@link Files#readAttributes(Path, Class, LinkOption...)} method. *

* This provider supports {@link BasicFileAttributes} and {@link MemoryFileAttributes}. * All other classes will result in an {@link UnsupportedOperationException} to be thrown. */ @Override public A readAttributes(Path path, Class type, LinkOption... options) throws IOException { if (type == BasicFileAttributes.class || type == MemoryFileAttributes.class) { boolean followLinks = LinkOptionSupport.followLinks(options); return type.cast(toMemoryPath(path).readAttributes(followLinks)); } throw Messages.fileSystemProvider().unsupportedFileAttributesType(type); } /** * Reads a set of file attributes as a bulk operation. * This method works in exactly the manner specified by the {@link Files#readAttributes(Path, String, LinkOption...)} method. *

* This provider supports views {@code basic} and {@code memory}, where {@code basic} will be used if no view is given. * All other views will result in an {@link UnsupportedOperationException} to be thrown. */ @Override public Map readAttributes(Path path, String attributes, LinkOption... options) throws IOException { boolean followLinks = LinkOptionSupport.followLinks(options); return toMemoryPath(path).readAttributes(attributes, followLinks); } /** * Sets the value of a file attribute. * This method works in exactly the manner specified by the {@link Files#setAttribute(Path, String, Object, LinkOption...)} method. *

* This provider supports views {@code basic} and {@code memory}, where {@code basic} will be used if no view is given. * All other views will result in an {@link UnsupportedOperationException} to be thrown. */ @Override public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException { boolean followLinks = LinkOptionSupport.followLinks(options); toMemoryPath(path).setAttribute(attribute, value, followLinks); } /** * Returns the content of an existing file. This method is shorthand for the following:

     * URI uri = URI.create("memory:" + path);
     * return getContent(Paths.get(uri));
* * @param path The path to the file to return the content of. * @return The content of the given file. * @throws NullPointerException If the given path is {@code null}. * @throws IllegalArgumentException If the path does not lead to a valid URI. * @throws IOException If an I/O error occurs. * @see #getContent(Path) * @since 1.1 */ public static byte[] getContent(String path) throws IOException { Objects.requireNonNull(path); URI uri = URI.create("memory:" + path); //$NON-NLS-1$ return getContent(Paths.get(uri)); } /** * Returns the content of an existing file. *

* This method works like {@link Files#readAllBytes(Path)} but is more optimized for in-memory paths. * * @param path The path to the file to return the content of. * @return The content of the given file. * @throws NullPointerException If the given path is {@code null}. * @throws ProviderMismatchException If the given path is not an in-memory path. * @throws IOException If an I/O error occurs. * @since 1.1 */ public static byte[] getContent(Path path) throws IOException { return toMemoryPath(path).getContent(); } /** * Sets the content of a file. If the file does not exist it will be created. This method is shorthand for the following:

     * URI uri = URI.create("memory:" + path);
     * setContents(Paths.get(uri), content);
* * @param path The path to the file to set the content of. * @param content The new content for the file. * @throws NullPointerException If the given path or content is {@code null}. * @throws IllegalArgumentException If the path does not lead to a valid URI. * @throws IOException If an I/O error occurs. * @see #setContent(Path, byte[]) * @since 1.1 */ public static void setContent(String path, byte[] content) throws IOException { Objects.requireNonNull(path); URI uri = URI.create("memory:" + path); //$NON-NLS-1$ setContent(Paths.get(uri), content); } /** * Sets the content of a file. If the file does not exist it will be created. *

* This method works like {@link Files#write(Path, byte[], OpenOption...)} with no options given but is more optimized for in-memory paths. * It does perform the necessary access checks on the file and/or its parent directory. * * @param path The path to the file to set the content of. * @param content The new content for the file. * @throws NullPointerException If the given path or content is {@code null}. * @throws ProviderMismatchException If the given path is not an in-memory path. * @throws IOException If an I/O error occurs. * @since 1.1 */ public static void setContent(Path path, byte[] content) throws IOException { Objects.requireNonNull(content); toMemoryPath(path).setContent(content); } private static MemoryPath toMemoryPath(Path path) { Objects.requireNonNull(path); if (path instanceof MemoryPath) { return (MemoryPath) path; } throw new ProviderMismatchException(); } /** * Clears all stored in-memory files and directories. Afterwards only the root directory will exist. * * @since 1.1 */ public static void clear() { MemoryFileStore.INSTANCE.clear(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy