RelativePath.java revision 2571:10fc81ac75b4
1271440Sjkim/* 2271440Sjkim * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3271440Sjkim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4271440Sjkim * 5271440Sjkim * This code is free software; you can redistribute it and/or modify it 6271440Sjkim * under the terms of the GNU General Public License version 2 only, as 7271440Sjkim * published by the Free Software Foundation. Oracle designates this 8316303Sjkim * particular file as subject to the "Classpath" exception as provided 9316303Sjkim * by Oracle in the LICENSE file that accompanied this code. 10316303Sjkim * 11316303Sjkim * This code is distributed in the hope that it will be useful, but WITHOUT 12316303Sjkim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13271440Sjkim * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14271440Sjkim * version 2 for more details (a copy is included in the LICENSE file that 15316303Sjkim * accompanied this code). 16316303Sjkim * 17316303Sjkim * You should have received a copy of the GNU General Public License version 18316303Sjkim * 2 along with this work; if not, write to the Free Software Foundation, 19316303Sjkim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20316303Sjkim * 21316303Sjkim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22316303Sjkim * or visit www.oracle.com if you need additional information or have any 23316303Sjkim * questions. 24316303Sjkim */ 25316303Sjkim 26316303Sjkimpackage com.sun.tools.javac.file; 27316303Sjkim 28316303Sjkimimport java.io.File; 29316303Sjkimimport java.util.zip.ZipEntry; 30316303Sjkimimport java.util.zip.ZipFile; 31316303Sjkimimport javax.tools.JavaFileObject; 32316303Sjkim 33316303Sjkim/** 34316303Sjkim * Used to represent a platform-neutral path within a platform-specific 35316303Sjkim * container, such as a directory or zip file. 36316303Sjkim * Internally, the file separator is always '/'. 37316303Sjkim * 38316303Sjkim * <p><b>This is NOT part of any supported API. 39316303Sjkim * If you write code that depends on this, you do so at your own risk. 40316303Sjkim * This code and its internal interfaces are subject to change or 41316303Sjkim * deletion without notice.</b> 42316303Sjkim */ 43316303Sjkimpublic abstract class RelativePath implements Comparable<RelativePath> { 44316303Sjkim /** 45316303Sjkim * @param p must use '/' as an internal separator 46316303Sjkim */ 47316303Sjkim protected RelativePath(String p) { 48316303Sjkim path = p; 49316303Sjkim } 50316303Sjkim 51316303Sjkim public abstract RelativeDirectory dirname(); 52316303Sjkim 53316303Sjkim public abstract String basename(); 54316303Sjkim 55316303Sjkim public File getFile(File directory) { 56316303Sjkim if (path.length() == 0) 57316303Sjkim return directory; 58316303Sjkim return new File(directory, path.replace('/', File.separatorChar)); 59316303Sjkim } 60316303Sjkim 61316303Sjkim public int compareTo(RelativePath other) { 62316303Sjkim return path.compareTo(other.path); 63316303Sjkim } 64316303Sjkim 65316303Sjkim @Override 66316303Sjkim public boolean equals(Object other) { 67316303Sjkim if (!(other instanceof RelativePath)) 68316303Sjkim return false; 69316303Sjkim return path.equals(((RelativePath) other).path); 70316303Sjkim } 71316303Sjkim 72316303Sjkim @Override 73316303Sjkim public int hashCode() { 74316303Sjkim return path.hashCode(); 75316303Sjkim } 76316303Sjkim 77316303Sjkim @Override 78316303Sjkim public String toString() { 79316303Sjkim return "RelPath[" + path + "]"; 80316303Sjkim } 81316303Sjkim 82316303Sjkim public String getPath() { 83316303Sjkim return path; 84316303Sjkim } 85316303Sjkim 86316303Sjkim protected final String path; 87316303Sjkim 88316303Sjkim /** 89316303Sjkim * Used to represent a platform-neutral subdirectory within a platform-specific 90316303Sjkim * container, such as a directory or zip file. 91316303Sjkim * Internally, the file separator is always '/', and if the path is not empty, 92316303Sjkim * it always ends in a '/' as well. 93316303Sjkim */ 94316303Sjkim public static class RelativeDirectory extends RelativePath { 95316303Sjkim 96316303Sjkim static RelativeDirectory forPackage(CharSequence packageName) { 97316303Sjkim return new RelativeDirectory(packageName.toString().replace('.', '/')); 98316303Sjkim } 99316303Sjkim 100316303Sjkim /** 101316303Sjkim * @param p must use '/' as an internal separator 102316303Sjkim */ 103316303Sjkim public RelativeDirectory(String p) { 104316303Sjkim super(p.length() == 0 || p.endsWith("/") ? p : p + "/"); 105316303Sjkim } 106316303Sjkim 107316303Sjkim /** 108316303Sjkim * @param p must use '/' as an internal separator 109316303Sjkim */ 110316303Sjkim public RelativeDirectory(RelativeDirectory d, String p) { 111316303Sjkim this(d.path + p); 112316303Sjkim } 113316303Sjkim 114316303Sjkim @Override 115316303Sjkim public RelativeDirectory dirname() { 116316303Sjkim int l = path.length(); 117316303Sjkim if (l == 0) 118316303Sjkim return this; 119316303Sjkim int sep = path.lastIndexOf('/', l - 2); 120271440Sjkim return new RelativeDirectory(path.substring(0, sep + 1)); 121271440Sjkim } 122271440Sjkim 123271440Sjkim @Override 124271440Sjkim public String basename() { 125271440Sjkim int l = path.length(); 126271440Sjkim if (l == 0) 127271440Sjkim return path; 128271440Sjkim int sep = path.lastIndexOf('/', l - 2); 129271440Sjkim return path.substring(sep + 1, l - 1); 130271440Sjkim } 131271440Sjkim 132271440Sjkim /** 133271440Sjkim * Return true if this subdirectory "contains" the other path. 134271440Sjkim * A subdirectory path does not contain itself. 135316303Sjkim **/ 136316303Sjkim boolean contains(RelativePath other) { 137316303Sjkim return other.path.length() > path.length() && other.path.startsWith(path); 138316303Sjkim } 139316303Sjkim 140316303Sjkim @Override 141316303Sjkim public String toString() { 142316303Sjkim return "RelativeDirectory[" + path + "]"; 143316303Sjkim } 144316303Sjkim } 145316303Sjkim 146316303Sjkim /** 147316303Sjkim * Used to represent a platform-neutral file within a platform-specific 148271440Sjkim * container, such as a directory or zip file. 149271440Sjkim * Internally, the file separator is always '/'. It never ends in '/'. 150271440Sjkim */ 151316303Sjkim public static class RelativeFile extends RelativePath { 152271440Sjkim static RelativeFile forClass(CharSequence className, JavaFileObject.Kind kind) { 153271440Sjkim return new RelativeFile(className.toString().replace('.', '/') + kind.extension); 154271440Sjkim } 155271440Sjkim 156271440Sjkim public RelativeFile(String p) { 157271440Sjkim super(p); 158271440Sjkim if (p.endsWith("/")) 159271440Sjkim throw new IllegalArgumentException(p); 160271440Sjkim } 161271440Sjkim 162271440Sjkim /** 163271440Sjkim * @param p must use '/' as an internal separator 164316303Sjkim */ 165316303Sjkim public RelativeFile(RelativeDirectory d, String p) { 166316303Sjkim this(d.path + p); 167316303Sjkim } 168316303Sjkim 169316303Sjkim RelativeFile(RelativeDirectory d, RelativePath p) { 170316303Sjkim this(d, p.path); 171316303Sjkim } 172316303Sjkim 173316303Sjkim @Override 174271440Sjkim public RelativeDirectory dirname() { 175271440Sjkim int sep = path.lastIndexOf('/'); 176271440Sjkim return new RelativeDirectory(path.substring(0, sep + 1)); 177271440Sjkim } 178271440Sjkim 179271440Sjkim @Override 180271440Sjkim public String basename() { 181271440Sjkim int sep = path.lastIndexOf('/'); 182271440Sjkim return path.substring(sep + 1); 183271440Sjkim } 184271440Sjkim 185271440Sjkim ZipEntry getZipEntry(ZipFile zip) { 186271440Sjkim return zip.getEntry(path); 187271440Sjkim } 188271440Sjkim 189271440Sjkim @Override 190271440Sjkim public String toString() { 191271440Sjkim return "RelativeFile[" + path + "]"; 192271440Sjkim } 193271440Sjkim 194271440Sjkim } 195271440Sjkim 196271440Sjkim} 197271440Sjkim