예제 #1
0
 public static Path coerceToPathOrNull(Object path) {
   if (path instanceof Path) return (Path) path;
   if (path instanceof URL) return URLPath.valueOf((URL) path);
   /* #ifdef use:java.net.URI */
   if (path instanceof URI) return URIPath.valueOf((URI) path);
   /* #endif */
   if (path instanceof File) return FilePath.valueOf((File) path);
   String str;
   if (path instanceof gnu.lists.FString) // FIXME: || UntypedAtomic
   str = path.toString();
   else if (!(path instanceof String)) return null;
   else str = (String) path;
   if (Path.uriSchemeSpecified(str)) return URIPath.valueOf(str);
   else return FilePath.valueOf(str);
 }
예제 #2
0
/** A generalized path/location, including File and URIs. */
public abstract class Path
/* #ifdef JAVA6 */
// implements javax.tools.FileObject
/* #endif */
{
  /**
   * This is equivalent to the System {@code "user.dir} property. However, the getProperty is
   * tracked dynamically and resolved as needed.
   */
  public static final FilePath userDirPath = FilePath.valueOf(new File("."));

  public static Path defaultPath = userDirPath;

  /* #ifdef JAVA2 */
  private static ThreadLocal<Path> pathLocation = new ThreadLocal<Path>();
  /* #endif */

  protected Path() {}

  public static Path currentPath() {
    /* #ifdef JAVA2 */
    Path path = pathLocation.get();
    if (path != null) return path;
    /* #endif */
    return defaultPath;
  }

  public static void setCurrentPath(Path path) {
    /* #ifdef JAVA2 */
    pathLocation.set(path);
    /* #else */
    // defaultPath = path;
    /* #endif */
  }

  public static Path coerceToPathOrNull(Object path) {
    if (path instanceof Path) return (Path) path;
    if (path instanceof URL) return URLPath.valueOf((URL) path);
    /* #ifdef use:java.net.URI */
    if (path instanceof URI) return URIPath.valueOf((URI) path);
    /* #endif */
    if (path instanceof File) return FilePath.valueOf((File) path);
    String str;
    if (path instanceof gnu.lists.FString) // FIXME: || UntypedAtomic
    str = path.toString();
    else if (!(path instanceof String)) return null;
    else str = (String) path;
    if (Path.uriSchemeSpecified(str)) return URIPath.valueOf(str);
    else return FilePath.valueOf(str);
  }

  public static Path valueOf(Object arg) {
    Path path = coerceToPathOrNull(arg);
    if (path == null) throw new WrongType((String) null, WrongType.ARG_CAST, arg, "path");
    return path;
  }

  public static URL toURL(String str) {
    try {
      if (!Path.uriSchemeSpecified(str)) {
        Path cur = currentPath();
        Path path = cur.resolve(str);
        if (path.isAbsolute()) return path.toURL();
        str = path.toString();
      }
      return new URL(str);
    } catch (Throwable ex) {
      throw WrappedException.wrapIfNeeded(ex);
    }
  }

  /**
   * Helper routine to get the scheme part of a URI. The scheme part is "http:" or "file:" or "ftp:"
   * most commonly. This functions searches for the first ':' that doesn't follow a '/'.
   *
   * @return The length of the scheme component, not counting the colon, (or alternatively the index
   *     of the colon), or -1 if the is no scheme.
   */
  public static int uriSchemeLength(String uri) {
    int len = uri.length();
    for (int i = 0; i < len; i++) {
      char ch = uri.charAt(i);
      if (ch == ':') return i;
      if (i == 0
          ? !Character.isLetter(ch)
          : (!Character.isLetterOrDigit(ch) && ch != '+' && ch != '-' && ch != '.')) return -1;
    }
    return -1;
  }

  /**
   * Tests if a URL has a scheme. For convenience, we treat a 1-character "scheme" as an
   * MS-DOS-style "drive letter" - i.e. not a scheme.
   */
  public static boolean uriSchemeSpecified(String name) {
    int ulen = uriSchemeLength(name);
    if (ulen == 1 && File.separatorChar == '\\') {
      char drive = name.charAt(0);
      return !((drive >= 'a' && drive <= 'z') || (drive >= 'A' && drive <= 'Z'));
    }
    return ulen > 0;
  }

  public abstract boolean isAbsolute();

  /**
   * Does this path name a directory? The default implementation returns true only if the path ends
   * with '/' or the separatorChar.
   */
  public boolean isDirectory() {
    String str = toString();
    int len = str.length();
    if (len > 0) {
      char last = str.charAt(len - 1);
      if (last == '/' || last == File.separatorChar) return true;
    }
    return false;
  }

  public boolean delete() {
    return false;
  }

  public boolean exists() {
    return getLastModified() != 0;
  }

  public abstract long getLastModified();

  public long getContentLength() {
    return -1;
  }

  public abstract String getScheme();

  public String getAuthority() {
    return null;
  }

  public String getUserInfo() {
    return null;
  }

  public String getHost() {
    return null;
  }

  public abstract String getPath();

  public Path getDirectory() {
    if (isDirectory()) return this;
    else return resolve("");
  }

  public Path getParent() {
    return resolve(isDirectory() ? ".." : "");
  }

  public String getLast() {
    String p = getPath();
    if (p == null) return null;
    int len = p.length();
    int end = len;
    for (int i = len; ; ) {
      if (--i <= 0) return "";
      char c = p.charAt(i);
      if (c == '/' || (this instanceof FilePath && c == File.separatorChar)) {
        if (i + 1 == len) end = i;
        else return p.substring(i + 1, end);
      }
    }
  }

  public String getExtension() {
    String p = getPath();
    if (p == null) return null;
    int len = p.length();
    for (int i = len; ; ) {
      if (--i <= 0) return null;
      char c = p.charAt(i);
      boolean sawDot = false;
      if (c == '.') {
        c = p.charAt(i - 1);
        sawDot = true;
      }
      if (c == '/' || (this instanceof FilePath && c == File.separatorChar)) return null;
      if (sawDot) return p.substring(i + 1);
    }
  }

  public int getPort() {
    return -1;
  }

  public String getQuery() {
    return null;
  }

  public String getFragment() {
    return null;
  }

  public abstract URL toURL();

  /* #ifdef use:java.net.URI */
  public abstract URI toUri();
  /* @deprecated */
  public final URI toURI() {
    return toUri();
  }
  /* #else */
  // public String toUri () { return toURIString(); }
  // /* @deprecated */
  // public final String toURI () { return toUri(); }
  /* #endif */
  public String toURIString() {
    return toUri().toString();
  }

  public Path resolve(Path relative) {
    if (relative.isAbsolute()) return relative;
    return resolve(relative.toString());
  }

  public abstract Path resolve(String relative);

  public static InputStream openInputStream(Object uri) throws IOException {
    return Path.valueOf(uri).openInputStream();
  }

  public abstract InputStream openInputStream() throws IOException;

  public abstract OutputStream openOutputStream() throws IOException;

  public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
    throw new UnsupportedOperationException(); // FIXME
  }

  public Writer openWriter() throws IOException {
    return new OutputStreamWriter(openOutputStream());
  }

  /* #ifdef use:java.lang.CharSequence */
  public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
    throw new UnsupportedOperationException(); // FIXME
  }
  /* #endif */

  /**
   * Convert an absolute URI to one relatve to a given base. This goes beyond
   * java.net.URI.relativize in that if the arguments have a common prefix, it can create a relative
   * URI using "../" steps.
   */
  public static String relativize(String in, String base)
      throws java.net.URISyntaxException, java.io.IOException {
    String baseStr = base;
    String inStr = in;
    /* #ifdef use:java.net.URI */
    baseStr = new URI(baseStr).normalize().toString();
    inStr = URLPath.valueOf(in).toURI().normalize().toString();
    /* #endif */
    int baseLen = baseStr.length();
    int inLen = inStr.length();
    int i = 0;
    int sl = 0;
    int colon = 0;
    for (; i < baseLen && i < inLen; i++) {
      char cb = baseStr.charAt(i);
      char ci = inStr.charAt(i);
      if (cb != ci) break;
      if (cb == '/') sl = i;
      if (cb == ':') colon = i;
    }
    if (colon > 0 && (sl > colon + 2 || baseLen <= colon + 2 || baseStr.charAt(colon + 2) != '/')
    /*
    && (colon + 2 != CLASS_RESOURCE_URI_PREFIX_LENGTH
        || ! inStr.substring(0, colon + 2).equals(CLASS_RESOURCE_URI_PREFIX)
        || getClassLoaderForURI(base) == getClassLoaderForURI(in))
    */
    ) {
      baseStr = baseStr.substring(sl + 1);
      inStr = inStr.substring(sl + 1);
    } else return in;
    /* #ifdef JAVA5 */
    StringBuilder sbuf = new StringBuilder();
    /* #else */
    // StringBuffer sbuf = new StringBuffer();
    /* #endif */
    sl = 0;
    for (i = baseLen = baseStr.length(); --i >= 0; )
      if (baseStr.charAt(i) == '/') // sep?
      sbuf.append("../");
    sbuf.append(inStr);
    return sbuf.toString();
  }

  public String getName() {
    return toString();
  }

  public Path getAbsolute() {
    if (this == Path.userDirPath) return resolve("");
    else return currentPath().resolve(this);
  }

  public Path getCanonical() {
    return getAbsolute();
  }
}