RelativePath.java revision 3392:04fcbc7234a4
119573Sjoerg/* 219573Sjoerg * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. 319573Sjoerg * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 419573Sjoerg * 519573Sjoerg * This code is free software; you can redistribute it and/or modify it 619573Sjoerg * under the terms of the GNU General Public License version 2 only, as 719573Sjoerg * published by the Free Software Foundation. Oracle designates this 819573Sjoerg * particular file as subject to the "Classpath" exception as provided 919573Sjoerg * by Oracle in the LICENSE file that accompanied this code. 1019573Sjoerg * 1119573Sjoerg * This code is distributed in the hope that it will be useful, but WITHOUT 1219573Sjoerg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1319573Sjoerg * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1419573Sjoerg * version 2 for more details (a copy is included in the LICENSE file that 1519573Sjoerg * accompanied this code). 1619573Sjoerg * 1719573Sjoerg * You should have received a copy of the GNU General Public License version 1819573Sjoerg * 2 along with this work; if not, write to the Free Software Foundation, 1919573Sjoerg * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2019573Sjoerg * 2119573Sjoerg * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2219573Sjoerg * or visit www.oracle.com if you need additional information or have any 2319573Sjoerg * questions. 2450479Speter */ 2519573Sjoerg 2619573Sjoergpackage com.sun.tools.javac.file; 2719573Sjoerg 2821243Sjkhimport java.nio.file.FileSystem; 2919573Sjoergimport java.nio.file.InvalidPathException; 3019573Sjoergimport java.nio.file.Path; 3119573Sjoergimport java.util.zip.ZipEntry; 3219573Sjoergimport java.util.zip.ZipFile; 3366834Sphk 3419573Sjoergimport javax.tools.JavaFileObject; 3519573Sjoerg 3619573Sjoerg/** 3719573Sjoerg * Used to represent a platform-neutral path within a platform-specific 3819573Sjoerg * container, such as a directory or zip file. 3919573Sjoerg * Internally, the file separator is always '/'. 4019573Sjoerg * 4119573Sjoerg * <p><b>This is NOT part of any supported API. 4219573Sjoerg * If you write code that depends on this, you do so at your own risk. 4319573Sjoerg * This code and its internal interfaces are subject to change or 4419573Sjoerg * deletion without notice.</b> 4519573Sjoerg */ 4619573Sjoergpublic abstract class RelativePath implements Comparable<RelativePath> { 4719573Sjoerg /** 4819573Sjoerg * @param p must use '/' as an internal separator 4919573Sjoerg */ 5019573Sjoerg protected RelativePath(String p) { 5119573Sjoerg path = p; 5219573Sjoerg } 53156160Sjhb 54156118Sjhb public abstract RelativeDirectory dirname(); 55156118Sjhb 56156118Sjhb public abstract String basename(); 57156118Sjhb 58156118Sjhb public Path resolveAgainst(Path directory) throws /*unchecked*/ InvalidPathException { 59156118Sjhb String sep = directory.getFileSystem().getSeparator(); 60156118Sjhb return directory.resolve(path.replace("/", sep)); 61156118Sjhb } 62156118Sjhb 63156118Sjhb public Path resolveAgainst(FileSystem fs) throws /*unchecked*/ InvalidPathException { 64156118Sjhb String sep = fs.getSeparator(); 65156118Sjhb Path root = fs.getRootDirectories().iterator().next(); 66156118Sjhb return root.resolve(path.replace("/", sep)); 67156118Sjhb } 68156118Sjhb 69156118Sjhb @Override 70156118Sjhb public int compareTo(RelativePath other) { 71156118Sjhb return path.compareTo(other.path); 72156118Sjhb } 73156118Sjhb 74156118Sjhb @Override 75156118Sjhb public boolean equals(Object other) { 76156118Sjhb if (!(other instanceof RelativePath)) 77156118Sjhb return false; 78156118Sjhb return path.equals(((RelativePath) other).path); 79156118Sjhb } 80156118Sjhb 81156118Sjhb @Override 82156118Sjhb public int hashCode() { 83156118Sjhb return path.hashCode(); 84156118Sjhb } 85156118Sjhb 86156118Sjhb @Override 87156118Sjhb public String toString() { 88156118Sjhb return "RelPath[" + path + "]"; 89156118Sjhb } 90156118Sjhb 91156118Sjhb public String getPath() { 92156118Sjhb return path; 93156118Sjhb } 94156118Sjhb 95156118Sjhb protected final String path; 96156118Sjhb 97156118Sjhb /** 98156118Sjhb * Used to represent a platform-neutral subdirectory within a platform-specific 99156118Sjhb * container, such as a directory or zip file. 100156118Sjhb * Internally, the file separator is always '/', and if the path is not empty, 101156118Sjhb * it always ends in a '/' as well. 102156118Sjhb */ 103156118Sjhb public static class RelativeDirectory extends RelativePath { 104156118Sjhb 105156118Sjhb static RelativeDirectory forPackage(CharSequence packageName) { 106156757Sthompsa return new RelativeDirectory(packageName.toString().replace('.', '/')); 107156757Sthompsa } 108156757Sthompsa 109156757Sthompsa /** 110156757Sthompsa * @param p must use '/' as an internal separator 111156118Sjhb */ 112156118Sjhb public RelativeDirectory(String p) { 113156118Sjhb super(p.length() == 0 || p.endsWith("/") ? p : p + "/"); 114156118Sjhb } 115156118Sjhb 116156118Sjhb /** 117156118Sjhb * @param p must use '/' as an internal separator 118156118Sjhb */ 119156118Sjhb public RelativeDirectory(RelativeDirectory d, String p) { 120156160Sjhb this(d.path + p); 121156118Sjhb } 12219573Sjoerg 12319573Sjoerg @Override 12419573Sjoerg public RelativeDirectory dirname() { 12519573Sjoerg int l = path.length(); 12619573Sjoerg if (l == 0) 12719573Sjoerg return this; 12819573Sjoerg int sep = path.lastIndexOf('/', l - 2); 12919573Sjoerg return new RelativeDirectory(path.substring(0, sep + 1)); 13019573Sjoerg } 13119573Sjoerg 13219573Sjoerg @Override 13319573Sjoerg public String basename() { 13419573Sjoerg int l = path.length(); 13519573Sjoerg if (l == 0) 13619573Sjoerg return path; 13719573Sjoerg int sep = path.lastIndexOf('/', l - 2); 13819573Sjoerg return path.substring(sep + 1, l - 1); 13919573Sjoerg } 14019573Sjoerg 14119573Sjoerg /** 14219573Sjoerg * Return true if this subdirectory "contains" the other path. 14319573Sjoerg * A subdirectory path does not contain itself. 14419573Sjoerg **/ 14519573Sjoerg boolean contains(RelativePath other) { 14619573Sjoerg return other.path.length() > path.length() && other.path.startsWith(path); 14719573Sjoerg } 14819573Sjoerg 14919573Sjoerg @Override 15019573Sjoerg public String toString() { 15119573Sjoerg return "RelativeDirectory[" + path + "]"; 15219573Sjoerg } 15319573Sjoerg } 15419573Sjoerg 15519573Sjoerg /** 15619573Sjoerg * Used to represent a platform-neutral file within a platform-specific 15719573Sjoerg * container, such as a directory or zip file. 15819573Sjoerg * Internally, the file separator is always '/'. It never ends in '/'. 15919573Sjoerg */ 16019573Sjoerg public static class RelativeFile extends RelativePath { 16119573Sjoerg static RelativeFile forClass(CharSequence className, JavaFileObject.Kind kind) { 16219573Sjoerg return new RelativeFile(className.toString().replace('.', '/') + kind.extension); 16319573Sjoerg } 16419573Sjoerg 165 public RelativeFile(String p) { 166 super(p); 167 if (p.endsWith("/")) 168 throw new IllegalArgumentException(p); 169 } 170 171 /** 172 * @param p must use '/' as an internal separator 173 */ 174 public RelativeFile(RelativeDirectory d, String p) { 175 this(d.path + p); 176 } 177 178 RelativeFile(RelativeDirectory d, RelativePath p) { 179 this(d, p.path); 180 } 181 182 @Override 183 public RelativeDirectory dirname() { 184 int sep = path.lastIndexOf('/'); 185 return new RelativeDirectory(path.substring(0, sep + 1)); 186 } 187 188 @Override 189 public String basename() { 190 int sep = path.lastIndexOf('/'); 191 return path.substring(sep + 1); 192 } 193 194 ZipEntry getZipEntry(ZipFile zip) { 195 return zip.getEntry(path); 196 } 197 198 @Override 199 public String toString() { 200 return "RelativeFile[" + path + "]"; 201 } 202 203 } 204 205} 206