com.google.devtools.build.lib.bazel.repository.StripPrefixedPath.java Source code

Java tutorial

Introduction

Here is the source code for com.google.devtools.build.lib.bazel.repository.StripPrefixedPath.java

Source

// Copyright 2014 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.devtools.build.lib.bazel.repository;

import com.google.common.base.Optional;
import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;

/**
 * Utility class for removing a prefix from an archive's path.
 */
@ThreadSafety.Immutable
public final class StripPrefixedPath {
    private final PathFragment pathFragment;
    private final boolean found;
    private final boolean skip;

    /**
     * If a prefix is given, it will be removed from the entry's path. This also turns absolute paths
     * into relative paths (e.g., /usr/bin/bash will become usr/bin/bash, same as unzip's default
     * behavior) and normalizes the paths (foo/../bar////baz will become bar/baz). Note that this
     * could cause collisions, if a zip file had one entry for bin/some-binary and another entry for
     * /bin/some-binary.
     *
     * Note that the prefix is stripped to move the files up one level, so if you have an entry
     * "foo/../bar" and a prefix of "foo", the result will be "bar" not "../bar".
     */
    public static StripPrefixedPath maybeDeprefix(String entry, Optional<String> prefix) {
        Preconditions.checkNotNull(entry);
        PathFragment entryPath = relativize(entry);
        if (!prefix.isPresent()) {
            return new StripPrefixedPath(entryPath, false, false);
        }

        PathFragment prefixPath = relativize(prefix.get());
        boolean found = false;
        boolean skip = false;
        if (entryPath.startsWith(prefixPath)) {
            found = true;
            entryPath = entryPath.relativeTo(prefixPath);
            if (entryPath.getPathString().isEmpty()) {
                skip = true;
            }
        } else {
            skip = true;
        }
        return new StripPrefixedPath(entryPath, found, skip);
    }

    /**
     * Normalize the path and, if it is absolute, make it relative (e.g., /foo/bar becomes foo/bar).
     */
    private static PathFragment relativize(String path) {
        PathFragment entryPath = new PathFragment(path).normalize();
        if (entryPath.isAbsolute()) {
            entryPath = new PathFragment(
                    entryPath.getSafePathString().substring(entryPath.windowsVolume().length() + 1));
        }
        return entryPath;
    }

    private StripPrefixedPath(PathFragment pathFragment, boolean found, boolean skip) {
        this.pathFragment = pathFragment;
        this.found = found;
        this.skip = skip;
    }

    public PathFragment getPathFragment() {
        return pathFragment;
    }

    public boolean foundPrefix() {
        return found;
    }

    public boolean skip() {
        return skip;
    }

}