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
}