Java Is Relative Path isRelativePath(String candidatePath)

Here you can find the source of isRelativePath(String candidatePath)

Description

Determines if the supplied volume binding path contains a relative path.

License

Apache License

Parameter

Parameter Description
candidatePath the candidate volume binding path

Return

true if the candidate path is considered to be a relative path

Declaration

static boolean isRelativePath(String candidatePath) 

Method Source Code

//package com.java2s;
//License from project: Apache License 

import java.util.regex.Pattern;

public class Main {
    /**//from ww  w.  j  a v  a  2s.  com
     * A dot representing the current working directory
     */
    private static final String DOT = ".";
    /**
     * A tilde representing the current user's home directory
     */
    private static final String TILDE = "~";
    /**
     * The current runtime platform file separator, '/' for *nix, '\' for Windows
     */
    private static final String RUNTIME_SEP = System.getProperty("file.separator");
    /**
     * Windows file separator: '\'
     */
    private static final String WINDOWS_SEP = "\\";
    /**
     * Unix file separator '/'
     */
    private static final String UNIX_SEP = "/";
    /**
     * Matches a windows drive letter followed by a colon and backwards slash.  For example, will match:
     * 'C:\' or 'x:\'.
     */
    private static final Pattern WINDOWS_DRIVE_PATTERN = Pattern.compile("^[A-Za-z]:\\\\.*");

    /**
     * Determines if the supplied volume binding path contains a relative path.  This is subtle, because volume
     * bindings may specify a named volume per the discussion below.
     * <h3>Discussion:</h3>
     * <p>
     * Volumes may be defined inside of {@code service} blocks <a href="https://docs.docker.com/compose/compose-file/compose-file-v2/#volumes-volume_driver">
     * as documented here</a>:
     * </p>
     * <pre>
     * volumes:
     * # Just specify a path and let the Engine create a volume
     * - /var/lib/mysql
     *
     * # Specify an absolute path mapping
     * - /opt/data:/var/lib/mysql
     *
     * # Path on the host, relative to the Compose file
     * - ./cache:/tmp/cache
     *
     * # User-relative path
     * - ~/configs:/etc/configs/:ro
     *
     * # Named volume
     * - datavolume:/var/lib/mysql"
     * </pre>
     * <p>
     * Volume binding paths that begin with {@code ./}, {@code ../}, or {@code ~} clearly represent a relative path.
     * However, binding paths that do not begin with those characters may represent a <em>named volume</em>.  For
     * example, the binding string {@code rel:/path/to/container/mountpoint} refers to the <em>named volume</em> {@code
     * rel}. Because it is desirable to fully support relative paths for volumes provided in a run configuration, this
     * method attempts to resolve the ambiguity between a <em>named volume</em> and a <em>relative path</em>.
     * </p>
     * <p>
     * Therefore, volume binding strings will be considered to contain a relative path when any of the following
     * conditions are true:
     * <ul>
     *     <li>the volume binding path begins with {@code ./}, {@code ../}, or {@code ~}</li>
     *     <li>the volume binding path contains the character {@code /} <em>and</em> {@code /} is not at index 0 of
     *         the volume binding path</li>
     * </ul>
     * </p>
     * <p>
     * If the binding string {@code rel:/path/to/container/mountpoint} is intended to represent {@code rel} as a
     * <em>relative path</em> and not as a <em>named volume</em>, then the binding string should be modified to contain
     * a forward slash like so: {@code rel/:/path/to/container/mountpoint}.  Another option would be to prefix {@code
     * rel} with a {@code ./} like so: {@code ./rel:/path/to/container/mountpoint}
     * </p>
     *
     *
     * @param candidatePath the candidate volume binding path
     * @return true if the candidate path is considered to be a relative path
     */
    static boolean isRelativePath(String candidatePath) {

        // java.io.File considers Windows paths to be absolute _only_ if they start with a drive letter.  That is,
        // a Windows path '\foo\bar\baz' is _not_ considered absolute by File#isAbsolute.  This block differs from
        // java.io.File in that it considers Windows paths to be absolute if they begin with the file separator _or_ a
        // drive letter
        if (candidatePath.startsWith(UNIX_SEP) || candidatePath.startsWith(WINDOWS_SEP)
                || WINDOWS_DRIVE_PATTERN.matcher(candidatePath).matches()) {
            return false;
        }

        // './' or '../'
        if (candidatePath.startsWith(DOT + RUNTIME_SEP) || candidatePath.startsWith(DOT + DOT + RUNTIME_SEP)) {
            return true;
        }

        if (candidatePath.contains(UNIX_SEP) || candidatePath.contains(WINDOWS_SEP)) {
            return true;
        }

        if (isUserHomeRelativePath(candidatePath)) {
            return true;
        }

        return false;
    }

    /**
     * Returns true if the supplied path begins with {@code ~}.  This means that the path should be resolved relative
     * to the user's home directory.
     *
     * @param candidatePath the candidate path that may represent a path under the user's home directory
     * @return true if the path begins with {@code ~}
     */
    static boolean isUserHomeRelativePath(String candidatePath) {
        return candidatePath.startsWith(TILDE);
    }
}

Related

  1. isRelative(File target_)
  2. isRelative(final String path)
  3. isRelative(String path)
  4. isRelativePath(final String filePath)
  5. isRelativePath(String fileName)
  6. isRelativePath(String path)
  7. isRelativePath(String path)
  8. isRelativePath(String path)