private static String doNormalize()

in impl/src/main/java/org/apache/myfaces/util/lang/FilenameUtils.java [363:475]


    private static String doNormalize(final String filename, final char separator, final boolean keepSeparator)
    {
        if (filename == null)
        {
            return null;
        }
        int size = filename.length();
        if (size == 0)
        {
            return filename;
        }
        final int prefix = getPrefixLength(filename);
        if (prefix < 0)
        {
            return null;
        }

        final char[] array = new char[size + 2];  // +1 for possible extra slash, +2 for arraycopy
        filename.getChars(0, filename.length(), array, 0);

        // fix separators throughout
        final char otherSeparator = separator == SYSTEM_SEPARATOR ? OTHER_SEPARATOR : SYSTEM_SEPARATOR;
        for (int i = 0; i < array.length; i++)
        {
            if (array[i] == otherSeparator)
            {
                array[i] = separator;
            }
        }

        // add extra separator on the end to simplify code below
        boolean lastIsDirectory = true;
        if (array[size - 1] != separator)
        {
            array[size++] = separator;
            lastIsDirectory = false;
        }

        // adjoining slashes
        for (int i = prefix + 1; i < size; i++)
        {
            if (array[i] == separator && array[i - 1] == separator)
            {
                System.arraycopy(array, i, array, i - 1, size - i);
                size--;
                i--;
            }
        }

        // dot slash
        for (int i = prefix + 1; i < size; i++)
        {
            if (array[i] == separator && array[i - 1] == '.'
                    && (i == prefix + 1 || array[i - 2] == separator))
            {
                if (i == size - 1)
                {
                    lastIsDirectory = true;
                }
                System.arraycopy(array, i + 1, array, i - 1, size - i);
                size -= 2;
                i--;
            }
        }

        // double dot slash
        outer:
        for (int i = prefix + 2; i < size; i++)
        {
            if (array[i] == separator && array[i - 1] == '.' && array[i - 2] == '.'
                    && (i == prefix + 2 || array[i - 3] == separator))
            {
                if (i == prefix + 2)
                {
                    return null;
                }
                if (i == size - 1)
                {
                    lastIsDirectory = true;
                }
                int j;
                for (j = i - 4; j >= prefix; j--)
                {
                    if (array[j] == separator)
                    {
                        // remove b/../ from a/b/../c
                        System.arraycopy(array, i + 1, array, j + 1, size - i);
                        size -= i - j;
                        i = j + 1;
                        continue outer;
                    }
                }
                // remove a/../ from a/../c
                System.arraycopy(array, i + 1, array, prefix, size - i);
                size -= i + 1 - prefix;
                i = prefix + 1;
            }
        }

        if (size <= 0)
        {  // should never be less than 0
            return "";
        }
        if (size <= prefix)
        {  // should never be less than prefix
            return new String(array, 0, size);
        }
        if (lastIsDirectory && keepSeparator)
        {
            return new String(array, 0, size);  // keep trailing separator
        }
        return new String(array, 0, size - 1);  // lose trailing separator
    }