blob: e299cbdf1e01e54e0e534c77a180636945e26f20 [file] [log] [blame]
/*
* 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);
}
}