diff options
Diffstat (limited to 'jimfs/src/main/java/com/google/common/jimfs/Options.java')
-rw-r--r-- | jimfs/src/main/java/com/google/common/jimfs/Options.java | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/jimfs/src/main/java/com/google/common/jimfs/Options.java b/jimfs/src/main/java/com/google/common/jimfs/Options.java new file mode 100644 index 0000000..a575b88 --- /dev/null +++ b/jimfs/src/main/java/com/google/common/jimfs/Options.java @@ -0,0 +1,149 @@ +/* + * 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 static java.nio.file.StandardCopyOption.ATOMIC_MOVE; +import static java.nio.file.StandardOpenOption.APPEND; +import static java.nio.file.StandardOpenOption.CREATE; +import static java.nio.file.StandardOpenOption.READ; +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; +import static java.nio.file.StandardOpenOption.WRITE; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import java.nio.file.CopyOption; +import java.nio.file.LinkOption; +import java.nio.file.OpenOption; +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; + +/** + * Utility methods for normalizing user-provided options arrays and sets to canonical immutable sets + * of options. + * + * @author Colin Decker + */ +final class Options { + + private Options() {} + + /** Immutable set containing LinkOption.NOFOLLOW_LINKS. */ + public static final ImmutableSet<LinkOption> NOFOLLOW_LINKS = + ImmutableSet.of(LinkOption.NOFOLLOW_LINKS); + + /** Immutable empty LinkOption set. */ + public static final ImmutableSet<LinkOption> FOLLOW_LINKS = ImmutableSet.of(); + + private static final ImmutableSet<OpenOption> DEFAULT_READ = ImmutableSet.<OpenOption>of(READ); + + private static final ImmutableSet<OpenOption> DEFAULT_READ_NOFOLLOW_LINKS = + ImmutableSet.<OpenOption>of(READ, LinkOption.NOFOLLOW_LINKS); + + private static final ImmutableSet<OpenOption> DEFAULT_WRITE = + ImmutableSet.<OpenOption>of(WRITE, CREATE, TRUNCATE_EXISTING); + + /** Returns an immutable set of link options. */ + public static ImmutableSet<LinkOption> getLinkOptions(LinkOption... options) { + return options.length == 0 ? FOLLOW_LINKS : NOFOLLOW_LINKS; + } + + /** Returns an immutable set of open options for opening a new file channel. */ + public static ImmutableSet<OpenOption> getOptionsForChannel(Set<? extends OpenOption> options) { + if (options.isEmpty()) { + return DEFAULT_READ; + } + + boolean append = options.contains(APPEND); + boolean write = append || options.contains(WRITE); + boolean read = !write || options.contains(READ); + + if (read) { + if (append) { + throw new UnsupportedOperationException("'READ' + 'APPEND' not allowed"); + } + + if (!write) { + // ignore all write related options + return options.contains(LinkOption.NOFOLLOW_LINKS) + ? DEFAULT_READ_NOFOLLOW_LINKS + : DEFAULT_READ; + } + } + + // options contains write or append and may also contain read + // it does not contain both read and append + return addWrite(options); + } + + /** Returns an immutable set of open options for opening a new input stream. */ + @SuppressWarnings("unchecked") // safe covariant cast + public static ImmutableSet<OpenOption> getOptionsForInputStream(OpenOption... options) { + boolean nofollowLinks = false; + for (OpenOption option : options) { + if (checkNotNull(option) != READ) { + if (option == LinkOption.NOFOLLOW_LINKS) { + nofollowLinks = true; + } else { + throw new UnsupportedOperationException("'" + option + "' not allowed"); + } + } + } + + // just return the link options for finding the file, nothing else is needed + return (ImmutableSet<OpenOption>) + (ImmutableSet<?>) (nofollowLinks ? NOFOLLOW_LINKS : FOLLOW_LINKS); + } + + /** Returns an immutable set of open options for opening a new output stream. */ + public static ImmutableSet<OpenOption> getOptionsForOutputStream(OpenOption... options) { + if (options.length == 0) { + return DEFAULT_WRITE; + } + + ImmutableSet<OpenOption> result = addWrite(Arrays.asList(options)); + if (result.contains(READ)) { + throw new UnsupportedOperationException("'READ' not allowed"); + } + return result; + } + + /** + * Returns an {@link ImmutableSet} copy of the given {@code options}, adding {@link + * StandardOpenOption#WRITE} if it isn't already present. + */ + private static ImmutableSet<OpenOption> addWrite(Collection<? extends OpenOption> options) { + return options.contains(WRITE) + ? ImmutableSet.copyOf(options) + : ImmutableSet.<OpenOption>builder().add(WRITE).addAll(options).build(); + } + + /** Returns an immutable set of the given options for a move. */ + public static ImmutableSet<CopyOption> getMoveOptions(CopyOption... options) { + return ImmutableSet.copyOf(Lists.asList(LinkOption.NOFOLLOW_LINKS, options)); + } + + /** Returns an immutable set of the given options for a copy. */ + public static ImmutableSet<CopyOption> getCopyOptions(CopyOption... options) { + ImmutableSet<CopyOption> result = ImmutableSet.copyOf(options); + if (result.contains(ATOMIC_MOVE)) { + throw new UnsupportedOperationException("'ATOMIC_MOVE' not allowed"); + } + return result; + } +} |