All Downloads are FREE. Search and download functionalities are using the official Maven repository.

juzu.impl.router.Path Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
/*
 * Copyright 2013 eXo Platform SAS
 *
 * 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.
 */

package juzu.impl.router;

import juzu.io.UndeclaredIOException;
import juzu.impl.common.PercentCodec;

import java.io.IOException;

/** @author Julien Viet */
class Path {

  static Path parse(String path) throws UndeclaredIOException {
    try {
      Data data = new Data(path);
      return new Path(data, 0);
    }
    catch (IOException e) {
      throw new UndeclaredIOException(e);
    }
  }

  private static final class Data {

    /** . */
    private final String value;

    /** . */
    private final boolean[] escaped;

    private Data(String rawValue) throws IOException, IllegalArgumentException {
      int len = rawValue.length();
      StringBuilder buffer = new StringBuilder();
      boolean[] escaped = new boolean[len];
      int count = 0;

      //
      int i = 0;
      while (i < len) {
        int delta = PercentCodec.RFC3986_PATH.decodeChar(rawValue, i, len, buffer);
        escaped[count++] = delta > 1;
        i += delta;
      }

      //
      this.value = buffer.toString();
      this.escaped = escaped;
    }

    boolean isEscaped(int index) {
      if (index < 0) {
        throw new IndexOutOfBoundsException("No negative index accepted");
      }
      if (index >= value.length()) {
        throw new IndexOutOfBoundsException("Index can't be greater than length");
      }
      return escaped[index];
    }
  }

  /** . */
  private final Data data;

  /** . */
  private final int offset;

  /** . */
  private final String value;

  private Path(Data data, int offset) {
    this.data = data;
    this.offset = offset;
    this.value = data.value.substring(offset);
  }

  String getValue() {
    return value;
  }

  boolean isEscaped(int index) {
    return data.isEscaped(innerIndex(index));
  }

  char charAt(int pos) {
    return value.charAt(pos);
  }

  int length() {
    return value.length();
  }

  int indexOf(int c, int index) {
    return value.indexOf(c, index);
  }

  Path subPath(int index) {
    if (index < 0) {
      throw new IndexOutOfBoundsException("No negative index accepted");
    }
    else if (index == 0) {
      return this;
    }
    else {
      int i = offset + index;
      if (i > data.value.length()) {
        throw new IndexOutOfBoundsException("Index can't be greater than length");
      }
      return new Path(data, i);
    }
  }

  /**
   * Convert the specified index to the internal index.
   *
   * @param outterIndex the outter index
   * @return the inner index value
   * @throws IndexOutOfBoundsException if the outter index is not correct
   */
  private int innerIndex(int outterIndex) throws IndexOutOfBoundsException {
    if (outterIndex < 0) {
      throw new IndexOutOfBoundsException("No negative index accepted");
    }
    int pos = offset + outterIndex;
    if (pos > data.value.length()) {
      throw new IndexOutOfBoundsException("Index can't be greater than length");
    }
    return pos;
  }

  @Override
  public String toString() {
    return "Path[" + value + "]";
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy