core/play/src/main/java/play/core/Paths.java
public static String relative(String startPath, String targetPath) {
    // If the start and target path's are the same then link to the current directory
    if (startPath.equals(targetPath)) {
      return CURRENT_DIR;
    }

    String[] start = toSegments(canonical(startPath));
    String[] target = toSegments(canonical(targetPath));

    // If start path has no trailing separator (a "file" path), then drop file segment
    if (!startPath.endsWith(SEPARATOR)) start = Arrays.copyOfRange(start, 0, start.length - 1);

    // If target path has no trailing separator, then drop file segment, but keep a reference to add
    // it later
    String targetFile = "";
    if (!targetPath.endsWith(SEPARATOR)) {
      targetFile = target[target.length - 1];
      target = Arrays.copyOfRange(target, 0, target.length - 1);
    }

    // Work out how much of the filepath is shared by start and path.
    String[] common = commonPrefix(start, target);
    String[] parents = toParentDirs(start.length - common.length);

    int relativeStartIdx = common.length;
    String[] relativeDirs = Arrays.copyOfRange(target, relativeStartIdx, target.length);
    String[] relativePath = Arrays.copyOf(parents, parents.length + relativeDirs.length);
    System.arraycopy(relativeDirs, 0, relativePath, parents.length, relativeDirs.length);

    // If this is not a sibling reference append a trailing / to path
    String trailingSep = "";
    if (relativePath.length > 0) trailingSep = SEPARATOR;

    return Arrays.stream(relativePath).collect(Collectors.joining(SEPARATOR))
        + trailingSep
        + targetFile;
  }
public static String relative(String startPath, String targetPath) {
    // If the start and target path's are the same then link to the current directory
    if (startPath.equals(targetPath)) {
      return CURRENT_DIR;
    }

    String[] start = toSegments(canonical(startPath));
    String[] target = toSegments(canonical(targetPath));

    // If start path has no trailing separator (a "file" path), then drop file segment
    if (!startPath.endsWith(SEPARATOR)) start = Arrays.copyOfRange(start, 0, start.length - 1);

    // If target path has no trailing separator, then drop file segment, but keep a reference to add
    // it later
    String targetFile = "";
    if (!targetPath.endsWith(SEPARATOR)) {
      targetFile = target[target.length - 1];
      target = Arrays.copyOfRange(target, 0, target.length - 1);
    }

    // Work out how much of the filepath is shared by start and path.
    String[] common = commonPrefix(start, target);
    String[] parents = toParentDirs(start.length - common.length);

    int relativeStartIdx = common.length;
    String[] relativeDirs = Arrays.copyOfRange(target, relativeStartIdx, target.length);
    String[] relativePath = Arrays.copyOf(parents, parents.length + relativeDirs.length);
    System.arraycopy(relativeDirs, 0, relativePath, parents.length, relativeDirs.length);

    // If this is not a sibling reference append a trailing / to path
    String trailingSep = "";
    if (relativePath.length > 0) trailingSep = SEPARATOR;

    return Arrays.stream(relativePath).collect(Collectors.joining(SEPARATOR))
        + trailingSep
        + targetFile;
  }
Create a path to targetPath that's relative to the given startPath.