Path.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:9k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.fs;
  19. import java.net.*;
  20. import java.io.*;
  21. import org.apache.hadoop.conf.Configuration;
  22. /** Names a file or directory in a {@link FileSystem}.
  23.  * Path strings use slash as the directory separator.  A path string is
  24.  * absolute if it begins with a slash.
  25.  */
  26. public class Path implements Comparable {
  27.   /** The directory separator, a slash. */
  28.   public static final String SEPARATOR = "/";
  29.   public static final char SEPARATOR_CHAR = '/';
  30.   
  31.   public static final String CUR_DIR = ".";
  32.   
  33.   static final boolean WINDOWS
  34.     = System.getProperty("os.name").startsWith("Windows");
  35.   private URI uri;                                // a hierarchical uri
  36.   /** Resolve a child path against a parent path. */
  37.   public Path(String parent, String child) {
  38.     this(new Path(parent), new Path(child));
  39.   }
  40.   /** Resolve a child path against a parent path. */
  41.   public Path(Path parent, String child) {
  42.     this(parent, new Path(child));
  43.   }
  44.   /** Resolve a child path against a parent path. */
  45.   public Path(String parent, Path child) {
  46.     this(new Path(parent), child);
  47.   }
  48.   /** Resolve a child path against a parent path. */
  49.   public Path(Path parent, Path child) {
  50.     // Add a slash to parent's path so resolution is compatible with URI's
  51.     URI parentUri = parent.uri;
  52.     String parentPath = parentUri.getPath();
  53.     if (!(parentPath.equals("/") || parentPath.equals("")))
  54.       try {
  55.         parentUri = new URI(parentUri.getScheme(), parentUri.getAuthority(),
  56.                             parentUri.getPath()+"/", null, null);
  57.       } catch (URISyntaxException e) {
  58.         throw new IllegalArgumentException(e);
  59.       }
  60.     URI resolved = parentUri.resolve(child.uri);
  61.     initialize(resolved.getScheme(), resolved.getAuthority(),
  62.                normalizePath(resolved.getPath()));
  63.   }
  64.   private void checkPathArg( String path ) {
  65.     // disallow construction of a Path from an empty string
  66.     if ( path == null ) {
  67.       throw new IllegalArgumentException(
  68.           "Can not create a Path from a null string");
  69.     }
  70.     if( path.length() == 0 ) {
  71.        throw new IllegalArgumentException(
  72.            "Can not create a Path from an empty string");
  73.     }   
  74.   }
  75.   
  76.   /** Construct a path from a String.  Path strings are URIs, but with
  77.    * unescaped elements and some additional normalization. */
  78.   public Path(String pathString) {
  79.     checkPathArg( pathString );
  80.     
  81.     // We can't use 'new URI(String)' directly, since it assumes things are
  82.     // escaped, which we don't require of Paths. 
  83.     
  84.     // add a slash in front of paths with Windows drive letters
  85.     if (hasWindowsDrive(pathString, false))
  86.       pathString = "/"+pathString;
  87.     // parse uri components
  88.     String scheme = null;
  89.     String authority = null;
  90.     int start = 0;
  91.     // parse uri scheme, if any
  92.     int colon = pathString.indexOf(':');
  93.     int slash = pathString.indexOf('/');
  94.     if ((colon != -1) &&
  95.         ((slash == -1) || (colon < slash))) {     // has a scheme
  96.       scheme = pathString.substring(0, colon);
  97.       start = colon+1;
  98.     }
  99.     // parse uri authority, if any
  100.     if (pathString.startsWith("//", start) &&
  101.         (pathString.length()-start > 2)) {       // has authority
  102.       int nextSlash = pathString.indexOf('/', start+2);
  103.       int authEnd = nextSlash > 0 ? nextSlash : pathString.length();
  104.       authority = pathString.substring(start+2, authEnd);
  105.       start = authEnd;
  106.     }
  107.     // uri path is the rest of the string -- query & fragment not supported
  108.     String path = pathString.substring(start, pathString.length());
  109.     initialize(scheme, authority, path);
  110.   }
  111.   /** Construct a Path from components. */
  112.   public Path(String scheme, String authority, String path) {
  113.     checkPathArg( path );
  114.     initialize(scheme, authority, path);
  115.   }
  116.   private void initialize(String scheme, String authority, String path) {
  117.     try {
  118.       this.uri = new URI(scheme, authority, normalizePath(path), null, null)
  119.         .normalize();
  120.     } catch (URISyntaxException e) {
  121.       throw new IllegalArgumentException(e);
  122.     }
  123.   }
  124.   private String normalizePath(String path) {
  125.     // remove double slashes & backslashes
  126.     path = path.replace("//", "/");
  127.     path = path.replace("\", "/");
  128.     
  129.     // trim trailing slash from non-root path (ignoring windows drive)
  130.     int minLength = hasWindowsDrive(path, true) ? 4 : 1;
  131.     if (path.length() > minLength && path.endsWith("/")) {
  132.       path = path.substring(0, path.length()-1);
  133.     }
  134.     
  135.     return path;
  136.   }
  137.   private boolean hasWindowsDrive(String path, boolean slashed) {
  138.     if (!WINDOWS) return false;
  139.     int start = slashed ? 1 : 0;
  140.     return
  141.       path.length() >= start+2 &&
  142.       (slashed ? path.charAt(0) == '/' : true) &&
  143.       path.charAt(start+1) == ':' &&
  144.       ((path.charAt(start) >= 'A' && path.charAt(start) <= 'Z') ||
  145.        (path.charAt(start) >= 'a' && path.charAt(start) <= 'z'));
  146.   }
  147.   /** Convert this to a URI. */
  148.   public URI toUri() { return uri; }
  149.   /** Return the FileSystem that owns this Path. */
  150.   public FileSystem getFileSystem(Configuration conf) throws IOException {
  151.     return FileSystem.get(this.toUri(), conf);
  152.   }
  153.   /** True if the directory of this path is absolute. */
  154.   public boolean isAbsolute() {
  155.     int start = hasWindowsDrive(uri.getPath(), true) ? 3 : 0;
  156.     return uri.getPath().startsWith(SEPARATOR, start);
  157.   }
  158.   /** Returns the final component of this path.*/
  159.   public String getName() {
  160.     String path = uri.getPath();
  161.     int slash = path.lastIndexOf(SEPARATOR);
  162.     return path.substring(slash+1);
  163.   }
  164.   /** Returns the parent of a path or null if at root. */
  165.   public Path getParent() {
  166.     String path = uri.getPath();
  167.     int lastSlash = path.lastIndexOf('/');
  168.     int start = hasWindowsDrive(path, true) ? 3 : 0;
  169.     if ((path.length() == start) ||               // empty path
  170.         (lastSlash == start && path.length() == start+1)) { // at root
  171.       return null;
  172.     }
  173.     String parent;
  174.     if (lastSlash==-1) {
  175.       parent = CUR_DIR;
  176.     } else {
  177.       int end = hasWindowsDrive(path, true) ? 3 : 0;
  178.       parent = path.substring(0, lastSlash==end?end+1:lastSlash);
  179.     }
  180.     return new Path(uri.getScheme(), uri.getAuthority(), parent);
  181.   }
  182.   /** Adds a suffix to the final name in the path.*/
  183.   public Path suffix(String suffix) {
  184.     return new Path(getParent(), getName()+suffix);
  185.   }
  186.   public String toString() {
  187.     // we can't use uri.toString(), which escapes everything, because we want
  188.     // illegal characters unescaped in the string, for glob processing, etc.
  189.     StringBuffer buffer = new StringBuffer();
  190.     if (uri.getScheme() != null) {
  191.       buffer.append(uri.getScheme());
  192.       buffer.append(":");
  193.     }
  194.     if (uri.getAuthority() != null) {
  195.       buffer.append("//");
  196.       buffer.append(uri.getAuthority());
  197.     }
  198.     if (uri.getPath() != null) {
  199.       String path = uri.getPath();
  200.       if (path.indexOf('/')==0 &&
  201.           hasWindowsDrive(path, true) &&          // has windows drive
  202.           uri.getScheme() == null &&              // but no scheme
  203.           uri.getAuthority() == null)             // or authority
  204.         path = path.substring(1);                 // remove slash before drive
  205.       buffer.append(path);
  206.     }
  207.     return buffer.toString();
  208.   }
  209.   public boolean equals(Object o) {
  210.     if (!(o instanceof Path)) {
  211.       return false;
  212.     }
  213.     Path that = (Path)o;
  214.     return this.uri.equals(that.uri);
  215.   }
  216.   public int hashCode() {
  217.     return uri.hashCode();
  218.   }
  219.   public int compareTo(Object o) {
  220.     Path that = (Path)o;
  221.     return this.uri.compareTo(that.uri);
  222.   }
  223.   
  224.   /** Return the number of elements in this path. */
  225.   public int depth() {
  226.     String path = uri.getPath();
  227.     int depth = 0;
  228.     int slash = path.length()==1 && path.charAt(0)=='/' ? -1 : 0;
  229.     while (slash != -1) {
  230.       depth++;
  231.       slash = path.indexOf(SEPARATOR, slash+1);
  232.     }
  233.     return depth;
  234.   }
  235.   /** Returns a qualified path object. */
  236.   public Path makeQualified(FileSystem fs) {
  237.     Path path = this;
  238.     if (!isAbsolute()) {
  239.       path = new Path(fs.getWorkingDirectory(), this);
  240.     }
  241.     URI pathUri = path.toUri();
  242.     URI fsUri = fs.getUri();
  243.       
  244.     String scheme = pathUri.getScheme();
  245.     String authority = pathUri.getAuthority();
  246.     if (scheme != null &&
  247.         (authority != null || fsUri.getAuthority() == null))
  248.       return path;
  249.     if (scheme == null) {
  250.       scheme = fsUri.getScheme();
  251.     }
  252.     if (authority == null) {
  253.       authority = fsUri.getAuthority();
  254.       if (authority == null) {
  255.         authority = "";
  256.       }
  257.     }
  258.     return new Path(scheme+":"+"//"+authority + pathUri.getPath());
  259.   }
  260. }