/* * Copyright 2015 Time Warner Cable, 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.twcable.jackalope.impl.common; import com.google.common.base.Strings; /** * Utilities for manipulating path strings. */ public final class Paths { public final static String SEPARATOR = "/"; private Paths() { } /** * Returns the first non-root segment of the path. * * @param path The path * @return The first segment of the path */ public static String head(String path) { path = stripRoot(path); return path.contains(SEPARATOR) ? path.substring(0, path.indexOf(SEPARATOR)) : path; } /** * Returns the segments of the path after the first non-root segment. * * @param path The path * @return The segments of the path after the first */ public static String tail(String path) { path = stripRoot(path); return path.contains(SEPARATOR) ? path.substring(path.indexOf(SEPARATOR) + 1) : ""; } /** * Returns the segments of the path before the last segment * * @param path The path * @return The segments of the path before the last segment */ public static String parent(String path) { String prefix = isAbsolute(path) && !isRoot(path) ? "/" : ""; path = stripRoot(path); return prefix + (path.contains(SEPARATOR) ? path.substring(0, path.lastIndexOf(SEPARATOR)) : ""); } /** * Returns the last non-root segment of the path * * @param path The path * @return The last segment of the path */ public static String basename(String path) { return path.contains(SEPARATOR) ? path.substring(path.lastIndexOf(SEPARATOR) + 1) : path; } /** * Returns true if the first path is an ancestor of the second path * * @param first The first path * @param second The second path * @return True if the first path is an ancestor of the second path */ public static boolean ancestorOf(String first, String second) { return !Strings.isNullOrEmpty(first) && !first.equals(second) && second.startsWith(first); } /** * Returns true if the first path is an ancestor of the second path * * @param first The first path * @param second The second path * @return True if the first path is an ancestor of the second path */ public static boolean selfOrAncestorOf(String first, String second) { return (!Strings.isNullOrEmpty(first) && first.equals(second)) || ancestorOf(first, second); } /** * Returns the number of segments in the path * * @param path The path * @return The number of segments in the path. Returns 0 if the path is empty or the root path. */ public static int depth(String path) { path = stripRoot(path); return !Strings.isNullOrEmpty(path) ? path.split(SEPARATOR).length : 0; } /** * Returns true it the path is an absolute path (i.e. starts with '/') * * @param path The path * @return True it the path is an absolute path (i.e. starts with '/') */ public static boolean isAbsolute(String path) { return path.startsWith("/"); } /** * Returns true it the path is the root path (i.e. '/') * * @param path The path * @return True it the path is the root path (i.e. '/') */ public static boolean isRoot(String path) { return path.equals("/"); } /** * Resolves the second path using the first path as context. * * @param first The path to be used as the context * @param second The target path * @return If the second path is absolute, it is returned. Otherwise, the return path is constructed by appending * the second (child) path to the first (parent) path. */ //TODO: Normalize the paths public static String resolve(String first, String second) { return isAbsolute(second) ? second : Strings.isNullOrEmpty(first) || isRoot(first) ? first + second : first + SEPARATOR + second; } /** * Returns the path with the root element removed * * @param path The path to be modified * @return The path with the root element removed. */ private static String stripRoot(String path) { return isAbsolute(path) ? path.substring(1) : path; } }