source: proiecte/HadoopJUnit/hadoop-0.20.1/src/core/org/apache/hadoop/fs/Path.java @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 9.2 KB
Line 
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
19package org.apache.hadoop.fs;
20
21import java.net.*;
22import java.io.*;
23
24import org.apache.hadoop.conf.Configuration;
25
26/** Names a file or directory in a {@link FileSystem}.
27 * Path strings use slash as the directory separator.  A path string is
28 * absolute if it begins with a slash.
29 */
30public class Path implements Comparable {
31
32  /** The directory separator, a slash. */
33  public static final String SEPARATOR = "/";
34  public static final char SEPARATOR_CHAR = '/';
35 
36  public static final String CUR_DIR = ".";
37 
38  static final boolean WINDOWS
39    = System.getProperty("os.name").startsWith("Windows");
40
41  private URI uri;                                // a hierarchical uri
42
43  /** Resolve a child path against a parent path. */
44  public Path(String parent, String child) {
45    this(new Path(parent), new Path(child));
46  }
47
48  /** Resolve a child path against a parent path. */
49  public Path(Path parent, String child) {
50    this(parent, new Path(child));
51  }
52
53  /** Resolve a child path against a parent path. */
54  public Path(String parent, Path child) {
55    this(new Path(parent), child);
56  }
57
58  /** Resolve a child path against a parent path. */
59  public Path(Path parent, Path child) {
60    // Add a slash to parent's path so resolution is compatible with URI's
61    URI parentUri = parent.uri;
62    String parentPath = parentUri.getPath();
63    if (!(parentPath.equals("/") || parentPath.equals("")))
64      try {
65        parentUri = new URI(parentUri.getScheme(), parentUri.getAuthority(),
66                            parentUri.getPath()+"/", null, null);
67      } catch (URISyntaxException e) {
68        throw new IllegalArgumentException(e);
69      }
70    URI resolved = parentUri.resolve(child.uri);
71    initialize(resolved.getScheme(), resolved.getAuthority(),
72               normalizePath(resolved.getPath()));
73  }
74
75  private void checkPathArg( String path ) {
76    // disallow construction of a Path from an empty string
77    if ( path == null ) {
78      throw new IllegalArgumentException(
79          "Can not create a Path from a null string");
80    }
81    if( path.length() == 0 ) {
82       throw new IllegalArgumentException(
83           "Can not create a Path from an empty string");
84    }   
85  }
86 
87  /** Construct a path from a String.  Path strings are URIs, but with
88   * unescaped elements and some additional normalization. */
89  public Path(String pathString) {
90    checkPathArg( pathString );
91   
92    // We can't use 'new URI(String)' directly, since it assumes things are
93    // escaped, which we don't require of Paths.
94   
95    // add a slash in front of paths with Windows drive letters
96    if (hasWindowsDrive(pathString, false))
97      pathString = "/"+pathString;
98
99    // parse uri components
100    String scheme = null;
101    String authority = null;
102
103    int start = 0;
104
105    // parse uri scheme, if any
106    int colon = pathString.indexOf(':');
107    int slash = pathString.indexOf('/');
108    if ((colon != -1) &&
109        ((slash == -1) || (colon < slash))) {     // has a scheme
110      scheme = pathString.substring(0, colon);
111      start = colon+1;
112    }
113
114    // parse uri authority, if any
115    if (pathString.startsWith("//", start) &&
116        (pathString.length()-start > 2)) {       // has authority
117      int nextSlash = pathString.indexOf('/', start+2);
118      int authEnd = nextSlash > 0 ? nextSlash : pathString.length();
119      authority = pathString.substring(start+2, authEnd);
120      start = authEnd;
121    }
122
123    // uri path is the rest of the string -- query & fragment not supported
124    String path = pathString.substring(start, pathString.length());
125
126    initialize(scheme, authority, path);
127  }
128
129  /** Construct a Path from components. */
130  public Path(String scheme, String authority, String path) {
131    checkPathArg( path );
132    initialize(scheme, authority, path);
133  }
134
135  private void initialize(String scheme, String authority, String path) {
136    try {
137      this.uri = new URI(scheme, authority, normalizePath(path), null, null)
138        .normalize();
139    } catch (URISyntaxException e) {
140      throw new IllegalArgumentException(e);
141    }
142  }
143
144  private String normalizePath(String path) {
145    // remove double slashes & backslashes
146    path = path.replace("//", "/");
147    path = path.replace("\\", "/");
148   
149    // trim trailing slash from non-root path (ignoring windows drive)
150    int minLength = hasWindowsDrive(path, true) ? 4 : 1;
151    if (path.length() > minLength && path.endsWith("/")) {
152      path = path.substring(0, path.length()-1);
153    }
154   
155    return path;
156  }
157
158  private boolean hasWindowsDrive(String path, boolean slashed) {
159    if (!WINDOWS) return false;
160    int start = slashed ? 1 : 0;
161    return
162      path.length() >= start+2 &&
163      (slashed ? path.charAt(0) == '/' : true) &&
164      path.charAt(start+1) == ':' &&
165      ((path.charAt(start) >= 'A' && path.charAt(start) <= 'Z') ||
166       (path.charAt(start) >= 'a' && path.charAt(start) <= 'z'));
167  }
168
169
170  /** Convert this to a URI. */
171  public URI toUri() { return uri; }
172
173  /** Return the FileSystem that owns this Path. */
174  public FileSystem getFileSystem(Configuration conf) throws IOException {
175    return FileSystem.get(this.toUri(), conf);
176  }
177
178  /** True if the directory of this path is absolute. */
179  public boolean isAbsolute() {
180    int start = hasWindowsDrive(uri.getPath(), true) ? 3 : 0;
181    return uri.getPath().startsWith(SEPARATOR, start);
182  }
183
184  /** Returns the final component of this path.*/
185  public String getName() {
186    String path = uri.getPath();
187    int slash = path.lastIndexOf(SEPARATOR);
188    return path.substring(slash+1);
189  }
190
191  /** Returns the parent of a path or null if at root. */
192  public Path getParent() {
193    String path = uri.getPath();
194    int lastSlash = path.lastIndexOf('/');
195    int start = hasWindowsDrive(path, true) ? 3 : 0;
196    if ((path.length() == start) ||               // empty path
197        (lastSlash == start && path.length() == start+1)) { // at root
198      return null;
199    }
200    String parent;
201    if (lastSlash==-1) {
202      parent = CUR_DIR;
203    } else {
204      int end = hasWindowsDrive(path, true) ? 3 : 0;
205      parent = path.substring(0, lastSlash==end?end+1:lastSlash);
206    }
207    return new Path(uri.getScheme(), uri.getAuthority(), parent);
208  }
209
210  /** Adds a suffix to the final name in the path.*/
211  public Path suffix(String suffix) {
212    return new Path(getParent(), getName()+suffix);
213  }
214
215  public String toString() {
216    // we can't use uri.toString(), which escapes everything, because we want
217    // illegal characters unescaped in the string, for glob processing, etc.
218    StringBuffer buffer = new StringBuffer();
219    if (uri.getScheme() != null) {
220      buffer.append(uri.getScheme());
221      buffer.append(":");
222    }
223    if (uri.getAuthority() != null) {
224      buffer.append("//");
225      buffer.append(uri.getAuthority());
226    }
227    if (uri.getPath() != null) {
228      String path = uri.getPath();
229      if (path.indexOf('/')==0 &&
230          hasWindowsDrive(path, true) &&          // has windows drive
231          uri.getScheme() == null &&              // but no scheme
232          uri.getAuthority() == null)             // or authority
233        path = path.substring(1);                 // remove slash before drive
234      buffer.append(path);
235    }
236    return buffer.toString();
237  }
238
239  public boolean equals(Object o) {
240    if (!(o instanceof Path)) {
241      return false;
242    }
243    Path that = (Path)o;
244    return this.uri.equals(that.uri);
245  }
246
247  public int hashCode() {
248    return uri.hashCode();
249  }
250
251  public int compareTo(Object o) {
252    Path that = (Path)o;
253    return this.uri.compareTo(that.uri);
254  }
255 
256  /** Return the number of elements in this path. */
257  public int depth() {
258    String path = uri.getPath();
259    int depth = 0;
260    int slash = path.length()==1 && path.charAt(0)=='/' ? -1 : 0;
261    while (slash != -1) {
262      depth++;
263      slash = path.indexOf(SEPARATOR, slash+1);
264    }
265    return depth;
266  }
267
268  /** Returns a qualified path object. */
269  public Path makeQualified(FileSystem fs) {
270    Path path = this;
271    if (!isAbsolute()) {
272      path = new Path(fs.getWorkingDirectory(), this);
273    }
274
275    URI pathUri = path.toUri();
276    URI fsUri = fs.getUri();
277     
278    String scheme = pathUri.getScheme();
279    String authority = pathUri.getAuthority();
280
281    if (scheme != null &&
282        (authority != null || fsUri.getAuthority() == null))
283      return path;
284
285    if (scheme == null) {
286      scheme = fsUri.getScheme();
287    }
288
289    if (authority == null) {
290      authority = fsUri.getAuthority();
291      if (authority == null) {
292        authority = "";
293      }
294    }
295
296    return new Path(scheme+":"+"//"+authority + pathUri.getPath());
297  }
298}
Note: See TracBrowser for help on using the repository browser.