| /* |
| * Copyright 2016 The Bazel Authors. All rights reserved. |
| * |
| * 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.idea.blaze.base.model.primitives; |
| |
| import com.google.common.base.Objects; |
| import com.intellij.openapi.util.io.FileUtil; |
| import java.io.File; |
| import java.io.Serializable; |
| import javax.annotation.Nullable; |
| |
| /** |
| * An absolute or relative path returned from Blaze. If it is a relative path, it is relative to the |
| * execution root. |
| */ |
| public final class ExecutionRootPath implements Serializable { |
| public static final long serialVersionUID = 3L; |
| |
| private final File path; |
| |
| public ExecutionRootPath(String path) { |
| this.path = new File(path); |
| } |
| |
| public ExecutionRootPath(File path) { |
| this.path = path; |
| } |
| |
| public File getAbsoluteOrRelativeFile() { |
| return path; |
| } |
| |
| public boolean isAbsolute() { |
| return path.isAbsolute(); |
| } |
| |
| public File getFileRootedAt(File absoluteRoot) { |
| if (path.isAbsolute()) { |
| return path; |
| } |
| return new File(absoluteRoot, path.getPath()); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } |
| if (o == null || getClass() != o.getClass()) { |
| return false; |
| } |
| ExecutionRootPath that = (ExecutionRootPath) o; |
| return Objects.equal(path, that.path); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hashCode(path); |
| } |
| |
| @Override |
| public String toString() { |
| return "ExecutionRootPath{" + "path='" + path + '\'' + '}'; |
| } |
| |
| /** |
| * Returns the relative {@link ExecutionRootPath} if {@code root} is an ancestor of {@code path} |
| * otherwise returns null. |
| */ |
| @Nullable |
| public static ExecutionRootPath createAncestorRelativePath(File root, File path) { |
| // We cannot find the relative path between an absolute and relative path. |
| // The underlying code will make the relative path absolute |
| // by rooting it at the current working directory which is almost never what you want. |
| if (root.isAbsolute() != path.isAbsolute()) { |
| return null; |
| } |
| if (!isAncestor(root.getPath(), path.getPath(), /* strict */ false)) { |
| return null; |
| } |
| String relativePath = |
| FileUtil.getRelativePath( |
| root.getAbsolutePath(), path.getAbsolutePath(), File.separatorChar); |
| if (relativePath == null) { |
| return null; |
| } |
| return new ExecutionRootPath(new File(relativePath)); |
| } |
| |
| /** |
| * @param possibleParent |
| * @param possibleChild |
| * @param strict if {@code false} then this method returns {@code true} if {@code possibleParent} |
| * equals to {@code possibleChild}. |
| */ |
| public static boolean isAncestor( |
| ExecutionRootPath possibleParent, ExecutionRootPath possibleChild, boolean strict) { |
| return isAncestor( |
| possibleParent.getAbsoluteOrRelativeFile().getPath(), |
| possibleChild.getAbsoluteOrRelativeFile().getPath(), |
| strict); |
| } |
| |
| /** |
| * @param possibleParentPath |
| * @param possibleChild |
| * @param strict if {@code false} then this method returns {@code true} if {@code possibleParent} |
| * equals to {@code possibleChild}. |
| */ |
| public static boolean isAncestor( |
| String possibleParentPath, ExecutionRootPath possibleChild, boolean strict) { |
| return isAncestor( |
| possibleParentPath, possibleChild.getAbsoluteOrRelativeFile().getPath(), strict); |
| } |
| |
| /** |
| * @param possibleParent |
| * @param possibleChildPath |
| * @param strict if {@code false} then this method returns {@code true} if {@code possibleParent} |
| * equals to {@code possibleChild}. |
| */ |
| public static boolean isAncestor( |
| ExecutionRootPath possibleParent, String possibleChildPath, boolean strict) { |
| return isAncestor( |
| possibleParent.getAbsoluteOrRelativeFile().getPath(), possibleChildPath, strict); |
| } |
| |
| /** |
| * @param possibleParentPath |
| * @param possibleChildPath |
| * @param strict if {@code false} then this method returns {@code true} if {@code possibleParent} |
| * equals to {@code possibleChild}. |
| */ |
| public static boolean isAncestor( |
| String possibleParentPath, String possibleChildPath, boolean strict) { |
| return FileUtil.isAncestor(possibleParentPath, possibleChildPath, strict); |
| } |
| } |