示例#1
0
 /**
  * Normalize the given path. The following transformation takes place:
  *
  * <ol>
  *   <li>All `.' segments are removed.
  *   <li>Each `..' segment which can be paired with a prior non-`..' segment is removed along with
  *       the preceding segment.
  *   <li>A `.' segment is added to the front if the first segment contains a colon (`:'). This is
  *       a deviation from the RFC, which prevents confusion between the path and the scheme.
  * </ol>
  *
  * <p>The resulting URI will be free of `.' and `..' segments, barring those that were prepended
  * or which couldn't be paired, respectively.
  *
  * @param relativePath the relative path to be normalized.
  * @return the normalized path.
  */
 private String normalizePath(String relativePath) {
   /*
      This follows the algorithm in section 5.2.4. of RFC3986,
      but doesn't modify the input buffer.
   */
   StringBuilder input = new StringBuilder(relativePath);
   StringBuilder output = new StringBuilder();
   int start = 0;
   while (start < input.length()) {
     /* A */
     if (input.indexOf("../", start) == start) {
       start += 3;
       continue;
     }
     if (input.indexOf("./", start) == start) {
       start += 2;
       continue;
     }
     /* B */
     if (input.indexOf("/./", start) == start) {
       start += 2;
       continue;
     }
     if (input.indexOf("/.", start) == start && input.charAt(start + 2) != '.') {
       start += 1;
       input.setCharAt(start, '/');
       continue;
     }
     /* C */
     if (input.indexOf("/../", start) == start) {
       start += 3;
       removeLastSegment(output);
       continue;
     }
     if (input.indexOf("/..", start) == start) {
       start += 2;
       input.setCharAt(start, '/');
       removeLastSegment(output);
       continue;
     }
     /* D */
     if (start == input.length() - 1 && input.indexOf(".", start) == start) {
       input.delete(0, 1);
       continue;
     }
     if (start == input.length() - 2 && input.indexOf("..", start) == start) {
       input.delete(0, 2);
       continue;
     }
     /* E */
     int indexOfSlash = input.indexOf("/", start);
     while (indexOfSlash == start) {
       output.append("/");
       ++start;
       indexOfSlash = input.indexOf("/", start);
     }
     if (indexOfSlash == -1) indexOfSlash = input.length();
     output.append(input.substring(start, indexOfSlash));
     start = indexOfSlash;
   }
   return output.toString();
 }