Java Stack Usage normalizeAbsolutePath(String curDir)

Here you can find the source of normalizeAbsolutePath(String curDir)

Description

Given an absolute path (starting with '/'), normalize it so that there are no ".."

License

Open Source License

Parameter

Parameter Description
curDir The non-normalized path.

Return

The normalized path.

Declaration

public static String normalizeAbsolutePath(String curDir) 

Method Source Code

//package com.java2s;
/*******************************************************************************
 * Copyright (c) 2011 Arapiki Solutions Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:/*from   w  w w  . j  a  v  a 2s.c om*/
 *    "Peter Smith <psmith@arapiki.com>" - initial API and 
 *        implementation and/or initial documentation
 *******************************************************************************/

import java.util.EmptyStackException;

import java.util.Stack;

public class Main {
    /**
     * Given an absolute path (starting with '/'), normalize it so that there
     * are no ".." or "." components, and no excess / characters. Note that unlike
     * File.getCanonicalPath(), we do not access the underlying file system
     * (this allows us to process content on a different machine from which the
     * path actually exists).
     * 
     * @param curDir The non-normalized path.
     * @return The normalized path.
     */
    public static String normalizeAbsolutePath(String curDir) {

        /*
         * This algorithm involves scanning through a StringBuffer (buf) and
         * keep track of the various '/' characters found (these delineate the
         * various path components). There are several cases to handle: 1)
         * Component "." is found - simply delete it and keep scanning. 2)
         * Component "/" is found - this is an excessive /, and can also be
         * deleted. 3) Component ".." is found - we need to backtrack and delete
         * the previous component as well.
         * 
         * We use two pointers (thisIndex, nextIndex) to track the start and end
         * of each component. We also use a Stack (slashStack) to record the
         * positions of all previous / characters, in case we need to backtrack.
         */
        if (curDir == null) {
            return null;
        }
        StringBuffer buf = new StringBuffer(curDir);
        int maxIndex = buf.length();
        int thisIndex = buf.indexOf("/");
        Stack<Integer> slashStack = new Stack<Integer>();

        /*
         * While not at the end of the string yet, keep looking for more
         * components.
         */
        while ((thisIndex != -1) && (thisIndex != maxIndex)) {

            /*
             * Find the next / character. If there aren't any more, use the end
             * of string. This will allow us to find the next "component"
             * (between slashes).
             */
            int nextIndex = buf.indexOf("/", thisIndex + 1);
            if (nextIndex == -1) {
                nextIndex = maxIndex;
            }
            String pathPart = buf.substring(thisIndex, nextIndex);

            /* a path component of "/." or "/" should be removed */
            if (pathPart.equals("/.") || pathPart.equals("/")) {
                buf.delete(thisIndex, nextIndex);
                maxIndex -= (nextIndex - thisIndex);

                /* a path component of "/.." involves going backwards */
            } else if (pathPart.equals("/..")) {

                /*
                 * Find the index of the previous component's starting point by
                 * popping the stack. If we go off the end of the stack, use
                 * index 0 instead. This allows for paths like "/../.." that are
                 * still legal in Linux.
                 */
                int lastIndex;
                try {
                    lastIndex = slashStack.pop();
                } catch (EmptyStackException ex) {
                    lastIndex = 0;
                }
                buf.delete(lastIndex, nextIndex);
                maxIndex -= (nextIndex - lastIndex);
                thisIndex = lastIndex;

            } else {
                /*
                 * normal case - record the slash position (in case we see a
                 * future ..) and move on
                 */
                slashStack.push(Integer.valueOf(thisIndex));
                thisIndex = nextIndex;
            }
        }
        /*
         * Return the normalized string. Note the special cases of "/.." that
         * should result in "/".
         */
        if (buf.length() == 0) {
            return "/";
        } else {
            return buf.toString();
        }
    }
}

Related

  1. getPermutationsRec(List permutations, byte[] order, List> remaining, int index)
  2. getPostOrder(List inOrderList)
  3. getRelativePath(Stack pathStack)
  4. getSyllables(String pinyin)
  5. isDoubleQuote(Stack bufStack)
  6. removeBackets(String cont)
  7. removeDotSegments(String relativePath)
  8. removeParenthesis(String text)
  9. resolveOneLineExpression(String line, String space, List target)