/* * Copyright 2016-present Facebook, 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.facebook.buck.io; import com.facebook.buck.event.BuckEventBus; import com.facebook.buck.util.sha1.Sha1HashCode; import com.google.common.hash.HashCode; import com.google.common.hash.Hashing; import com.google.common.io.ByteSource; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; /** * Default implementation of {@link ProjectFilesystemDelegate} that talks to the filesystem via * standard Java APIs. */ public final class DefaultProjectFilesystemDelegate implements ProjectFilesystemDelegate { private final Path root; public DefaultProjectFilesystemDelegate(Path root) { this.root = root; } @Override public void ensureConcreteFilesExist(BuckEventBus eventBus) { return; } @Override public Sha1HashCode computeSha1(Path pathRelativeToProjectRootOrJustAbsolute) throws IOException { final Path fileToHash = getPathForRelativePath(pathRelativeToProjectRootOrJustAbsolute); // Normally, we would just use `Files.hash(fileToHash.toFile(), Hashing.sha1())`, but if // fileToHash is backed by Jimfs, its toFile() method throws an UnsupportedOperationException. // Creating the input stream via java.nio.file.Files.newInputStream() avoids this issue. ByteSource source = new ByteSource() { @Override public InputStream openStream() throws IOException { // No need to wrap with BufferedInputStream because ByteSource uses ByteStreams.copy(), // which already buffers. return Files.newInputStream(fileToHash); } }; HashCode hashCode = source.hash(Hashing.sha1()); return Sha1HashCode.fromHashCode(hashCode); } @Override public Path getPathForRelativePath(Path pathRelativeToProjectRoot) { // We often create {@link Path} instances using // {@link java.nio.file.Paths#get(String, String...)}, but there's no guarantee that the // underlying {@link FileSystem} is the default one. if (pathRelativeToProjectRoot.getFileSystem().equals(root.getFileSystem())) { return root.resolve(pathRelativeToProjectRoot); } return root.resolve(pathRelativeToProjectRoot.toString()); } @Override public boolean isExecutable(Path child) { child = getPathForRelativePath(child); return Files.isExecutable(child); } @Override public boolean isSymlink(Path path) { return Files.isSymbolicLink(getPathForRelativePath(path)); } @Override public boolean exists(Path pathRelativeToProjectRoot, LinkOption... options) { return Files.exists(getPathForRelativePath(pathRelativeToProjectRoot), options); } }