001 /*
002 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package com.sun.tools.javac.file;
027
028 import java.io.File;
029 import java.io.FileInputStream;
030 import java.io.FileOutputStream;
031 import java.io.IOException;
032 import java.io.InputStream;
033 import java.io.OutputStream;
034 import java.io.OutputStreamWriter;
035 import java.io.Writer;
036 import java.net.URI;
037 import java.net.URISyntaxException;
038 import java.nio.ByteBuffer;
039 import java.nio.CharBuffer;
040 import java.nio.charset.CharsetDecoder;
041 import javax.tools.JavaFileObject;
042
043 /**
044 * A subclass of JavaFileObject representing regular files.
045 */
046 class RegularFileObject extends BaseFileObject {
047
048 /** Have the parent directories been created?
049 */
050 private boolean hasParents = false;
051 private String name;
052 final File f;
053
054 public RegularFileObject(JavacFileManager fileManager, File f) {
055 this(fileManager, f.getName(), f);
056 }
057
058 public RegularFileObject(JavacFileManager fileManager, String name, File f) {
059 super(fileManager);
060 if (f.isDirectory()) {
061 throw new IllegalArgumentException("directories not supported");
062 }
063 this.name = name;
064 this.f = f;
065 }
066
067 public InputStream openInputStream() throws IOException {
068 return new FileInputStream(f);
069 }
070
071 protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
072 return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
073 }
074
075 public OutputStream openOutputStream() throws IOException {
076 ensureParentDirectoriesExist();
077 return new FileOutputStream(f);
078 }
079
080 public Writer openWriter() throws IOException {
081 ensureParentDirectoriesExist();
082 return new OutputStreamWriter(new FileOutputStream(f), fileManager.getEncodingName());
083 }
084
085 @Override
086 protected String inferBinaryName(Iterable<? extends File> path) {
087 String fPath = f.getPath();
088 //System.err.println("RegularFileObject " + file + " " +r.getPath());
089 for (File dir: path) {
090 //System.err.println("dir: " + dir);
091 String dPath = dir.getPath();
092 if (dPath.length() == 0)
093 dPath = System.getProperty("user.dir");
094 if (!dPath.endsWith(File.separator))
095 dPath += File.separator;
096 if (fPath.regionMatches(true, 0, dPath, 0, dPath.length())
097 && new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) {
098 String relativeName = fPath.substring(dPath.length());
099 return removeExtension(relativeName).replace(File.separatorChar, '.');
100 }
101 }
102 return null;
103 }
104
105 private void ensureParentDirectoriesExist() throws IOException {
106 if (!hasParents) {
107 File parent = f.getParentFile();
108 if (parent != null && !parent.exists()) {
109 if (!parent.mkdirs()) {
110 if (!parent.exists() || !parent.isDirectory()) {
111 throw new IOException("could not create parent directories");
112 }
113 }
114 }
115 hasParents = true;
116 }
117 }
118
119 @Deprecated
120 public String getName() {
121 return name;
122 }
123
124 public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
125 cn.getClass();
126 // null check
127 if (kind == Kind.OTHER && getKind() != kind) {
128 return false;
129 }
130 String n = cn + kind.extension;
131 if (name.equals(n)) {
132 return true;
133 }
134 if (name.equalsIgnoreCase(n)) {
135 try {
136 // allow for Windows
137 return f.getCanonicalFile().getName().equals(n);
138 } catch (IOException e) {
139 }
140 }
141 return false;
142 }
143
144 @Deprecated
145 public String getPath() {
146 return f.getPath();
147 }
148
149 public long getLastModified() {
150 return f.lastModified();
151 }
152
153 public boolean delete() {
154 return f.delete();
155 }
156
157 public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
158 CharBuffer cb = fileManager.getCachedContent(this);
159 if (cb == null) {
160 InputStream in = new FileInputStream(f);
161 try {
162 ByteBuffer bb = fileManager.makeByteBuffer(in);
163 JavaFileObject prev = fileManager.log.useSource(this);
164 try {
165 cb = fileManager.decode(bb, ignoreEncodingErrors);
166 } finally {
167 fileManager.log.useSource(prev);
168 }
169 fileManager.recycleByteBuffer(bb);
170 if (!ignoreEncodingErrors) {
171 fileManager.cache(this, cb);
172 }
173 } finally {
174 in.close();
175 }
176 }
177 return cb;
178 }
179
180 @Override
181 public boolean equals(Object other) {
182 if (!(other instanceof RegularFileObject)) {
183 return false;
184 }
185 RegularFileObject o = (RegularFileObject) other;
186 try {
187 return f.equals(o.f) || f.getCanonicalFile().equals(o.f.getCanonicalFile());
188 } catch (IOException e) {
189 return false;
190 }
191 }
192
193 @Override
194 public int hashCode() {
195 return f.hashCode();
196 }
197
198 public URI toUri() {
199 try {
200 String path = f.getAbsolutePath().replace(File.separatorChar, '/');
201 return new URI("file://" + path).normalize();
202 } catch (URISyntaxException ex) {
203 return f.toURI();
204 }
205 }
206 }