Android Path Relative Get getWindowsRelativePath(String basedir, String path)

Here you can find the source of getWindowsRelativePath(String basedir, String path)

Description

get Windows Relative Path

License

Open Source License

Declaration

public static String getWindowsRelativePath(String basedir, String path) 

Method Source Code

/*//from ww w  .j  av  a2  s.  co m
 * Copyright (c) 2002-2012 Alibaba Group Holding Limited.
 * 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.
 */

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import com.alibaba.antx.util.scanner.DefaultScannerHandler;
import com.alibaba.antx.util.scanner.DirectoryScanner;
import com.alibaba.antx.util.scanner.Scanner;
import com.alibaba.antx.util.scanner.ScannerException;

public class Main{
    private static final char COLON_CHAR = ':';
    private static final String UNC_PREFIX = "//";
    private static final String SLASH = "/";
    private static final char SLASH_CHAR = '/';
    private static final char BACKSLASH_CHAR = '\\';
    /** ??????????"." */
    public static final String CURRENT_DIR = ".";
    /** ?????????".." */
    public static final String UP_LEVEL_DIR = "..";
    
    public static String getWindowsRelativePath(String basedir, String path) {
        return getRelativePath(basedir, path, true);
    }
    
    public static String getRelativePath(String basedir, String path) {
        return getRelativePath(basedir, path, isWindows());
    }
    
    private static String getRelativePath(String basedir, String path,
            boolean isWindows) {
        // ????????basedir???????????
        basedir = normalizePath(basedir, isWindows);

        if (basedir == null) {
            return null;
        }

        String basePrefix = getSystemDependentPrefix(basedir, isWindows);

        if (basePrefix == null || basePrefix.length() == 0
                && !basedir.startsWith(SLASH)) {
            return null; // basedir????????
        }

        // ????????path
        path = getPathBasedOn(basedir, path, isWindows);

        if (path == null) {
            return null;
        }

        String prefix = getSystemDependentPrefix(path, isWindows);

        // ??path?basedir???????????????????????basedir??????
        // ????????path???????
        if (!basePrefix.equals(prefix)) {
            return path;
        }

        // ???path???"/"
        boolean endsWithSlash = path.endsWith(SLASH);

        // ?"/"??basedir?path
        String[] baseParts = StringUtil.split(
                basedir.substring(basePrefix.length()), SLASH);
        String[] parts = StringUtil.split(path.substring(prefix.length()),
                SLASH);
        StringBuffer buffer = new StringBuffer();
        int i = 0;

        if (isWindows) {
            while (i < baseParts.length && i < parts.length
                    && baseParts[i].equalsIgnoreCase(parts[i])) {
                i++;
            }
        } else {
            while (i < baseParts.length && i < parts.length
                    && baseParts[i].equals(parts[i])) {
                i++;
            }
        }

        if (i < baseParts.length && i < parts.length) {
            for (int j = i; j < baseParts.length; j++) {
                buffer.append(UP_LEVEL_DIR).append(SLASH_CHAR);
            }
        }

        for (; i < parts.length; i++) {
            buffer.append(parts[i]);

            if (i < parts.length - 1) {
                buffer.append(SLASH_CHAR);
            }
        }

        if (buffer.length() == 0) {
            buffer.append(CURRENT_DIR);
        }

        String relpath = buffer.toString();

        if (endsWithSlash && !relpath.endsWith(SLASH)) {
            relpath += SLASH;
        }

        return relpath;
    }
    private static boolean isWindows() {
        return System.getProperty("os.name").startsWith("Windows");
    }
    
    public static String normalizePath(String path) {
        return normalizePath(path, isWindows());
    }
    
    private static String normalizePath(String path, boolean isWindows) {
        if (path == null) {
            return null;
        }

        path = path.trim();

        // ?"\\"??????"/"?????????
        path = path.replace(BACKSLASH_CHAR, SLASH_CHAR);

        // ?????????????????windows?????????"C:"??"//hostname"
        String prefix = getSystemDependentPrefix(path, isWindows);

        if (prefix == null) {
            return null;
        }

        path = path.substring(prefix.length());

        // ????????prefix???"/"??????????????prefix.length > 0
        if (prefix.length() > 0 || path.startsWith(SLASH)) {
            prefix += SLASH_CHAR;
        }

        // ???path???"/"
        boolean endsWithSlash = path.endsWith(SLASH);

        // ??????"."?".."
        StringTokenizer tokenizer = new StringTokenizer(path, "/");
        StringBuffer buffer = new StringBuffer(prefix.length()
                + path.length());
        int level = 0;

        buffer.append(prefix);

        while (tokenizer.hasMoreTokens()) {
            String element = tokenizer.nextToken();

            // ??"."
            if (CURRENT_DIR.equals(element)) {
                continue;
            }

            // ??".."
            if (UP_LEVEL_DIR.equals(element)) {
                if (level == 0) {
                    // ??prefix?????????????????????????
                    // ??null??????????
                    if (prefix.length() > 0) {
                        return null;
                    }

                    buffer.append(UP_LEVEL_DIR).append(SLASH_CHAR);
                } else {
                    level--;

                    boolean found = false;

                    for (int i = buffer.length() - 2; i >= prefix.length(); i--) {
                        if (buffer.charAt(i) == SLASH_CHAR) {
                            buffer.setLength(i + 1);
                            found = true;
                            break;
                        }
                    }

                    if (!found) {
                        buffer.setLength(prefix.length());
                    }
                }

                continue;
            }

            // ???path
            buffer.append(element).append(SLASH_CHAR);
            level++;
        }

        // ????????????"./"
        if (buffer.length() == 0) {
            buffer.append(CURRENT_DIR).append(SLASH_CHAR);
        }

        // ????????"/"
        if (!endsWithSlash && buffer.length() > prefix.length()
                && buffer.charAt(buffer.length() - 1) == SLASH_CHAR) {
            buffer.setLength(buffer.length() - 1);
        }

        return buffer.toString();
    }
    
    private static String getSystemDependentPrefix(String path,
            boolean isWindows) {
        if (isWindows) {
            // ??UNC??
            if (path.startsWith(UNC_PREFIX)) {
                // ????UNC???"//"
                if (path.length() == UNC_PREFIX.length()) {
                    return null;
                }

                // ???????//hostname/subpath???//hostname
                int index = path.indexOf(SLASH, UNC_PREFIX.length());

                if (index != -1) {
                    return path.substring(0, index);
                } else {
                    return path;
                }
            }

            // ??Windows??????"c:/..."
            if (path.length() > 1 && path.charAt(1) == COLON_CHAR) {
                return path.substring(0, 2).toUpperCase();
            }
        }

        return "";
    }
    
    public static String getPathBasedOn(String basedir, String path) {
        return getPathBasedOn(basedir, path, isWindows());
    }
    
    private static String getPathBasedOn(String basedir, String path,
            boolean isWindows) {
        /*
         * ------------------------------------------- * ??????path??????????????????
         * * ???????????????normalize?????? *
         * -------------------------------------------
         */
        if (path == null) {
            return null;
        }

        path = path.trim();

        // ?"\\"??????"/"?????????
        path = path.replace(BACKSLASH_CHAR, SLASH_CHAR);

        // ?????????????????windows?????????"C:"??"//hostname"
        String prefix = getSystemDependentPrefix(path, isWindows);

        if (prefix == null) {
            return null;
        }

        // ??????????????
        if (prefix.length() > 0 || path.length() > prefix.length()
                && path.charAt(prefix.length()) == SLASH_CHAR) {
            return normalizePath(path, isWindows);
        }

        /*
         * ------------------------------------------- * ???????path?????????????
         * * ???basedir????? * -------------------------------------------
         */
        if (basedir == null) {
            return null;
        }

        StringBuffer buffer = new StringBuffer();

        buffer.append(basedir.trim());

        // ???????"/"????????UNC prefix??
        if (basedir.length() > 0 && path.length() > 0
                && basedir.charAt(basedir.length() - 1) != SLASH_CHAR) {
            buffer.append(SLASH_CHAR);
        }

        buffer.append(path);

        return normalizePath(buffer.toString(), isWindows);
    }
}

Related

  1. convertToRelativePath(String absolutePath, String relativeTo)
  2. getPathRelativeTo(File fileChild, File fileRoot)
  3. getRelativeFileName(File file, File basedir)
  4. getRelativePath(File parent, File file)
  5. relativePathFromBase(File file, File basedir)
  6. getParentRelativeTo(File fileChild, File fileRoot)