001: /*
002: * Copyright 2005-2006 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 javax.tools;
027:
028: import java.io.Closeable;
029: import java.io.Flushable;
030: import java.io.IOException;
031: import java.util.Iterator;
032: import java.util.Set;
033: import static javax.tools.JavaFileObject.Kind;
034:
035: /**
036: * File manager for tools operating on Java™ programming language
037: * source and class files. In this context, <em>file</em> means an
038: * abstraction of regular files and other sources of data.
039: *
040: * <p>When constructing new JavaFileObjects, the file manager must
041: * determine where to create them. For example, if a file manager
042: * manages regular files on a file system, it would most likely have a
043: * current/working directory to use as default location when creating
044: * or finding files. A number of hints can be provided to a file
045: * manager as to where to create files. Any file manager might choose
046: * to ignore these hints.
047: *
048: * <p>Some methods in this interface use class names. Such class
049: * names must be given in the Java Virtual Machine internal form of
050: * fully qualified class and interface names. For convenience '.'
051: * and '/' are interchangeable. The internal form is defined in
052: * chapter four of the
053: * <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/jvms-maintenance.html">Java
054: * Virtual Machine Specification</a>.
055:
056: * <blockquote><p>
057: * <i>Discussion:</i> this means that the names
058: * "java/lang.package-info", "java/lang/package-info",
059: * "java.lang.package-info", are valid and equivalent. Compare to
060: * binary name as defined in the
061: * <a href="http://java.sun.com/docs/books/jls/">Java Language
062: * Specification (JLS)</a> section 13.1 "The Form of a Binary".
063: * </p></blockquote>
064: *
065: * <p>The case of names is significant. All names should be treated
066: * as case-sensitive. For example, some file systems have
067: * case-insensitive, case-aware file names. File objects representing
068: * such files should take care to preserve case by using {@link
069: * java.io.File#getCanonicalFile} or similar means. If the system is
070: * not case-aware, file objects must use other means to preserve case.
071: *
072: * <p><em><a name="relative_name">Relative names</a>:</em> some
073: * methods in this interface use relative names. A relative name is a
074: * non-null, non-empty sequence of path segments separated by '/'.
075: * '.' or '..' are invalid path segments. A valid relative name must
076: * match the "path-rootless" rule of <a
077: * href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>,
078: * section 3.3. Informally, this should be true:
079: *
080: * <!-- URI.create(relativeName).normalize().getPath().equals(relativeName) -->
081: * <pre> URI.{@linkplain java.net.URI#create create}(relativeName).{@linkplain java.net.URI#normalize normalize}().{@linkplain java.net.URI#getPath getPath}().equals(relativeName)</pre>
082: *
083: * <p>All methods in this interface might throw a SecurityException.
084: *
085: * <p>An object of this interface is not required to support
086: * multi-threaded access, that is, be synchronized. However, it must
087: * support concurrent access to different file objects created by this
088: * object.
089: *
090: * <p><em>Implementation note:</em> a consequence of this requirement
091: * is that a trivial implementation of output to a {@linkplain
092: * java.util.jar.JarOutputStream} is not a sufficient implementation.
093: * That is, rather than creating a JavaFileObject that returns the
094: * JarOutputStream directly, the contents must be cached until closed
095: * and then written to the JarOutputStream.
096: *
097: * <p>Unless explicitly allowed, all methods in this interface might
098: * throw a NullPointerException if given a {@code null} argument.
099: *
100: * @author Peter von der Ahé
101: * @author Jonathan Gibbons
102: * @see JavaFileObject
103: * @see FileObject
104: * @since 1.6
105: */
106: public interface JavaFileManager extends Closeable, Flushable,
107: OptionChecker {
108:
109: /**
110: * Interface for locations of file objects. Used by file managers
111: * to determine where to place or search for file objects.
112: */
113: interface Location {
114: /**
115: * Gets the name of this location.
116: *
117: * @return a name
118: */
119: String getName();
120:
121: /**
122: * Determines if this is an output location. An output
123: * location is a location that is conventionally used for
124: * output.
125: *
126: * @return true if this is an output location, false otherwise
127: */
128: boolean isOutputLocation();
129: }
130:
131: /**
132: * Gets a class loader for loading plug-ins from the given
133: * location. For example, to load annotation processors, a
134: * compiler will request a class loader for the {@link
135: * StandardLocation#ANNOTATION_PROCESSOR_PATH
136: * ANNOTATION_PROCESSOR_PATH} location.
137: *
138: * @param location a location
139: * @return a class loader for the given location; or {@code null}
140: * if loading plug-ins from the given location is disabled or if
141: * the location is not known
142: * @throws SecurityException if a class loader can not be created
143: * in the current security context
144: * @throws IllegalStateException if {@link #close} has been called
145: * and this file manager cannot be reopened
146: */
147: ClassLoader getClassLoader(Location location);
148:
149: /**
150: * Lists all file objects matching the given criteria in the given
151: * location. List file objects in "subpackages" if recurse is
152: * true.
153: *
154: * <p>Note: even if the given location is unknown to this file
155: * manager, it may not return {@code null}. Also, an unknown
156: * location may not cause an exception.
157: *
158: * @param location a location
159: * @param packageName a package name
160: * @param kinds return objects only of these kinds
161: * @param recurse if true include "subpackages"
162: * @return an Iterable of file objects matching the given criteria
163: * @throws IOException if an I/O error occurred, or if {@link
164: * #close} has been called and this file manager cannot be
165: * reopened
166: * @throws IllegalStateException if {@link #close} has been called
167: * and this file manager cannot be reopened
168: */
169: Iterable<JavaFileObject> list(Location location,
170: String packageName, Set<Kind> kinds, boolean recurse)
171: throws IOException;
172:
173: /**
174: * Infers a binary name of a file object based on a location. The
175: * binary name returned might not be a valid JLS binary name.
176: *
177: * @param location a location
178: * @param file a file object
179: * @return a binary name or {@code null} the file object is not
180: * found in the given location
181: * @throws IllegalStateException if {@link #close} has been called
182: * and this file manager cannot be reopened
183: */
184: String inferBinaryName(Location location, JavaFileObject file);
185:
186: /**
187: * Compares two file objects and return true if they represent the
188: * same underlying object.
189: *
190: * @param a a file object
191: * @param b a file object
192: * @return true if the given file objects represent the same
193: * underlying object
194: *
195: * @throws IllegalArgumentException if either of the arguments
196: * were created with another file manager and this file manager
197: * does not support foreign file objects
198: */
199: boolean isSameFile(FileObject a, FileObject b);
200:
201: /**
202: * Handles one option. If {@code current} is an option to this
203: * file manager it will consume any arguments to that option from
204: * {@code remaining} and return true, otherwise return false.
205: *
206: * @param current current option
207: * @param remaining remaining options
208: * @return true if this option was handled by this file manager,
209: * false otherwise
210: * @throws IllegalArgumentException if this option to this file
211: * manager is used incorrectly
212: * @throws IllegalStateException if {@link #close} has been called
213: * and this file manager cannot be reopened
214: */
215: boolean handleOption(String current, Iterator<String> remaining);
216:
217: /**
218: * Determines if a location is known to this file manager.
219: *
220: * @param location a location
221: * @return true if the location is known
222: */
223: boolean hasLocation(Location location);
224:
225: /**
226: * Gets a {@linkplain JavaFileObject file object} for input
227: * representing the specified class of the specified kind in the
228: * given location.
229: *
230: * @param location a location
231: * @param className the name of a class
232: * @param kind the kind of file, must be one of {@link
233: * JavaFileObject.Kind#SOURCE SOURCE} or {@link
234: * JavaFileObject.Kind#CLASS CLASS}
235: * @return a file object, might return {@code null} if the
236: * file does not exist
237: * @throws IllegalArgumentException if the location is not known
238: * to this file manager and the file manager does not support
239: * unknown locations, or if the kind is not valid
240: * @throws IOException if an I/O error occurred, or if {@link
241: * #close} has been called and this file manager cannot be
242: * reopened
243: * @throws IllegalStateException if {@link #close} has been called
244: * and this file manager cannot be reopened
245: */
246: JavaFileObject getJavaFileForInput(Location location,
247: String className, Kind kind) throws IOException;
248:
249: /**
250: * Gets a {@linkplain JavaFileObject file object} for output
251: * representing the specified class of the specified kind in the
252: * given location.
253: *
254: * <p>Optionally, this file manager might consider the sibling as
255: * a hint for where to place the output. The exact semantics of
256: * this hint is unspecified. Sun's compiler, javac, for
257: * example, will place class files in the same directories as
258: * originating source files unless a class file output directory
259: * is provided. To facilitate this behavior, javac might provide
260: * the originating source file as sibling when calling this
261: * method.
262: *
263: * @param location a location
264: * @param className the name of a class
265: * @param kind the kind of file, must be one of {@link
266: * JavaFileObject.Kind#SOURCE SOURCE} or {@link
267: * JavaFileObject.Kind#CLASS CLASS}
268: * @param sibling a file object to be used as hint for placement;
269: * might be {@code null}
270: * @return a file object for output
271: * @throws IllegalArgumentException if sibling is not known to
272: * this file manager, or if the location is not known to this file
273: * manager and the file manager does not support unknown
274: * locations, or if the kind is not valid
275: * @throws IOException if an I/O error occurred, or if {@link
276: * #close} has been called and this file manager cannot be
277: * reopened
278: * @throws IllegalStateException {@link #close} has been called
279: * and this file manager cannot be reopened
280: */
281: JavaFileObject getJavaFileForOutput(Location location,
282: String className, Kind kind, FileObject sibling)
283: throws IOException;
284:
285: /**
286: * Gets a {@linkplain FileObject file object} for input
287: * representing the specified <a href="JavaFileManager.html#relative_name">relative
288: * name</a> in the specified package in the given location.
289: *
290: * <p>If the returned object represents a {@linkplain
291: * JavaFileObject.Kind#SOURCE source} or {@linkplain
292: * JavaFileObject.Kind#CLASS class} file, it must be an instance
293: * of {@link JavaFileObject}.
294: *
295: * <p>Informally, the file object returned by this method is
296: * located in the concatenation of the location, package name, and
297: * relative name. For example, to locate the properties file
298: * "resources/compiler.properties" in the package
299: * "com.sun.tools.javac" in the {@linkplain
300: * StandardLocation#SOURCE_PATH SOURCE_PATH} location, this method
301: * might be called like so:
302: *
303: * <pre>getFileForInput(SOURCE_PATH, "com.sun.tools.javac", "resources/compiler.properties");</pre>
304: *
305: * <p>If the call was executed on Windows, with SOURCE_PATH set to
306: * <code>"C:\Documents and Settings\UncleBob\src\share\classes"</code>,
307: * a valid result would be a file object representing the file
308: * <code>"C:\Documents and Settings\UncleBob\src\share\classes\com\sun\tools\javac\resources\compiler.properties"</code>.
309: *
310: * @param location a location
311: * @param packageName a package name
312: * @param relativeName a relative name
313: * @return a file object, might return {@code null} if the file
314: * does not exist
315: * @throws IllegalArgumentException if the location is not known
316: * to this file manager and the file manager does not support
317: * unknown locations, or if {@code relativeName} is not valid
318: * @throws IOException if an I/O error occurred, or if {@link
319: * #close} has been called and this file manager cannot be
320: * reopened
321: * @throws IllegalStateException if {@link #close} has been called
322: * and this file manager cannot be reopened
323: */
324: FileObject getFileForInput(Location location, String packageName,
325: String relativeName) throws IOException;
326:
327: /**
328: * Gets a {@linkplain FileObject file object} for output
329: * representing the specified <a href="JavaFileManager.html#relative_name">relative
330: * name</a> in the specified package in the given location.
331: *
332: * <p>Optionally, this file manager might consider the sibling as
333: * a hint for where to place the output. The exact semantics of
334: * this hint is unspecified. Sun's compiler, javac, for
335: * example, will place class files in the same directories as
336: * originating source files unless a class file output directory
337: * is provided. To facilitate this behavior, javac might provide
338: * the originating source file as sibling when calling this
339: * method.
340: *
341: * <p>If the returned object represents a {@linkplain
342: * JavaFileObject.Kind#SOURCE source} or {@linkplain
343: * JavaFileObject.Kind#CLASS class} file, it must be an instance
344: * of {@link JavaFileObject}.
345: *
346: * <p>Informally, the file object returned by this method is
347: * located in the concatenation of the location, package name, and
348: * relative name or next to the sibling argument. See {@link
349: * #getFileForInput getFileForInput} for an example.
350: *
351: * @param location a location
352: * @param packageName a package name
353: * @param relativeName a relative name
354: * @param sibling a file object to be used as hint for placement;
355: * might be {@code null}
356: * @return a file object
357: * @throws IllegalArgumentException if sibling is not known to
358: * this file manager, or if the location is not known to this file
359: * manager and the file manager does not support unknown
360: * locations, or if {@code relativeName} is not valid
361: * @throws IOException if an I/O error occurred, or if {@link
362: * #close} has been called and this file manager cannot be
363: * reopened
364: * @throws IllegalStateException if {@link #close} has been called
365: * and this file manager cannot be reopened
366: */
367: FileObject getFileForOutput(Location location, String packageName,
368: String relativeName, FileObject sibling) throws IOException;
369:
370: /**
371: * Flushes any resources opened for output by this file manager
372: * directly or indirectly. Flushing a closed file manager has no
373: * effect.
374: *
375: * @throws IOException if an I/O error occurred
376: * @see #close
377: */
378: void flush() throws IOException;
379:
380: /**
381: * Releases any resources opened by this file manager directly or
382: * indirectly. This might render this file manager useless and
383: * the effect of subsequent calls to methods on this object or any
384: * objects obtained through this object is undefined unless
385: * explicitly allowed. However, closing a file manager which has
386: * already been closed has no effect.
387: *
388: * @throws IOException if an I/O error occurred
389: * @see #flush
390: */
391: void close() throws IOException;
392: }
|