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&nbsp;3986</a>,
078     * section&nbsp;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&eacute;
101     * @author Jonathan Gibbons
102     * @see JavaFileObject
103     * @see FileObject
104     * @since 1.6
105     */
106    public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
107    
108        /**
109         * Interface for locations of file objects.  Used by file managers
110         * to determine where to place or search for file objects.
111         */
112        interface Location {
113            /**
114             * Gets the name of this location.
115             *
116             * @return a name
117             */
118            String getName();
119    
120            /**
121             * Determines if this is an output location.  An output
122             * location is a location that is conventionally used for
123             * output.
124             *
125             * @return true if this is an output location, false otherwise
126             */
127            boolean isOutputLocation();
128        }
129    
130        /**
131         * Gets a class loader for loading plug-ins from the given
132         * location.  For example, to load annotation processors, a
133         * compiler will request a class loader for the {@link
134         * StandardLocation#ANNOTATION_PROCESSOR_PATH
135         * ANNOTATION_PROCESSOR_PATH} location.
136         *
137         * @param location a location
138         * @return a class loader for the given location; or {@code null}
139         * if loading plug-ins from the given location is disabled or if
140         * the location is not known
141         * @throws SecurityException if a class loader can not be created
142         * in the current security context
143         * @throws IllegalStateException if {@link #close} has been called
144         * and this file manager cannot be reopened
145         */
146        ClassLoader getClassLoader(Location location);
147    
148        /**
149         * Lists all file objects matching the given criteria in the given
150         * location.  List file objects in "subpackages" if recurse is
151         * true.
152         *
153         * <p>Note: even if the given location is unknown to this file
154         * manager, it may not return {@code null}.  Also, an unknown
155         * location may not cause an exception.
156         *
157         * @param location     a location
158         * @param packageName  a package name
159         * @param kinds        return objects only of these kinds
160         * @param recurse      if true include "subpackages"
161         * @return an Iterable of file objects matching the given criteria
162         * @throws IOException if an I/O error occurred, or if {@link
163         * #close} has been called and this file manager cannot be
164         * reopened
165         * @throws IllegalStateException if {@link #close} has been called
166         * and this file manager cannot be reopened
167         */
168        Iterable<JavaFileObject> list(Location location,
169                                      String packageName,
170                                      Set<Kind> kinds,
171                                      boolean recurse)
172            throws IOException;
173    
174        /**
175         * Infers a binary name of a file object based on a location.  The
176         * binary name returned might not be a valid JLS binary name.
177         *
178         * @param location a location
179         * @param file a file object
180         * @return a binary name or {@code null} the file object is not
181         * found in the given location
182         * @throws IllegalStateException if {@link #close} has been called
183         * and this file manager cannot be reopened
184         */
185        String inferBinaryName(Location location, JavaFileObject file);
186    
187        /**
188         * Compares two file objects and return true if they represent the
189         * same underlying object.
190         *
191         * @param a a file object
192         * @param b a file object
193         * @return true if the given file objects represent the same
194         * underlying object
195         *
196         * @throws IllegalArgumentException if either of the arguments
197         * were created with another file manager and this file manager
198         * does not support foreign file objects
199         */
200        boolean isSameFile(FileObject a, FileObject b);
201    
202        /**
203         * Handles one option.  If {@code current} is an option to this
204         * file manager it will consume any arguments to that option from
205         * {@code remaining} and return true, otherwise return false.
206         *
207         * @param current current option
208         * @param remaining remaining options
209         * @return true if this option was handled by this file manager,
210         * false otherwise
211         * @throws IllegalArgumentException if this option to this file
212         * manager is used incorrectly
213         * @throws IllegalStateException if {@link #close} has been called
214         * and this file manager cannot be reopened
215         */
216        boolean handleOption(String current, Iterator<String> remaining);
217    
218        /**
219         * Determines if a location is known to this file manager.
220         *
221         * @param location a location
222         * @return true if the location is known
223         */
224        boolean hasLocation(Location location);
225    
226        /**
227         * Gets a {@linkplain JavaFileObject file object} for input
228         * representing the specified class of the specified kind in the
229         * given location.
230         *
231         * @param location a location
232         * @param className the name of a class
233         * @param kind the kind of file, must be one of {@link
234         * JavaFileObject.Kind#SOURCE SOURCE} or {@link
235         * JavaFileObject.Kind#CLASS CLASS}
236         * @return a file object, might return {@code null} if the
237         * file does not exist
238         * @throws IllegalArgumentException if the location is not known
239         * to this file manager and the file manager does not support
240         * unknown locations, or if the kind is not valid
241         * @throws IOException if an I/O error occurred, or if {@link
242         * #close} has been called and this file manager cannot be
243         * reopened
244         * @throws IllegalStateException if {@link #close} has been called
245         * and this file manager cannot be reopened
246         */
247        JavaFileObject getJavaFileForInput(Location location,
248                                           String className,
249                                           Kind kind)
250            throws IOException;
251    
252        /**
253         * Gets a {@linkplain JavaFileObject file object} for output
254         * representing the specified class of the specified kind in the
255         * given location.
256         *
257         * <p>Optionally, this file manager might consider the sibling as
258         * a hint for where to place the output.  The exact semantics of
259         * this hint is unspecified.  Sun's compiler, javac, for
260         * example, will place class files in the same directories as
261         * originating source files unless a class file output directory
262         * is provided.  To facilitate this behavior, javac might provide
263         * the originating source file as sibling when calling this
264         * method.
265         *
266         * @param location a location
267         * @param className the name of a class
268         * @param kind the kind of file, must be one of {@link
269         * JavaFileObject.Kind#SOURCE SOURCE} or {@link
270         * JavaFileObject.Kind#CLASS CLASS}
271         * @param sibling a file object to be used as hint for placement;
272         * might be {@code null}
273         * @return a file object for output
274         * @throws IllegalArgumentException if sibling is not known to
275         * this file manager, or if the location is not known to this file
276         * manager and the file manager does not support unknown
277         * locations, or if the kind is not valid
278         * @throws IOException if an I/O error occurred, or if {@link
279         * #close} has been called and this file manager cannot be
280         * reopened
281         * @throws IllegalStateException {@link #close} has been called
282         * and this file manager cannot be reopened
283         */
284        JavaFileObject getJavaFileForOutput(Location location,
285                                            String className,
286                                            Kind kind,
287                                            FileObject sibling)
288            throws IOException;
289    
290        /**
291         * Gets a {@linkplain FileObject file object} for input
292         * representing the specified <a href="JavaFileManager.html#relative_name">relative
293         * name</a> in the specified package in the given location.
294         *
295         * <p>If the returned object represents a {@linkplain
296         * JavaFileObject.Kind#SOURCE source} or {@linkplain
297         * JavaFileObject.Kind#CLASS class} file, it must be an instance
298         * of {@link JavaFileObject}.
299         *
300         * <p>Informally, the file object returned by this method is
301         * located in the concatenation of the location, package name, and
302         * relative name.  For example, to locate the properties file
303         * "resources/compiler.properties" in the package
304         * "com.sun.tools.javac" in the {@linkplain
305         * StandardLocation#SOURCE_PATH SOURCE_PATH} location, this method
306         * might be called like so:
307         *
308         * <pre>getFileForInput(SOURCE_PATH, "com.sun.tools.javac", "resources/compiler.properties");</pre>
309         *
310         * <p>If the call was executed on Windows, with SOURCE_PATH set to
311         * <code>"C:\Documents&nbsp;and&nbsp;Settings\UncleBob\src\share\classes"</code>,
312         * a valid result would be a file object representing the file
313         * <code>"C:\Documents&nbsp;and&nbsp;Settings\UncleBob\src\share\classes\com\sun\tools\javac\resources\compiler.properties"</code>.
314         *
315         * @param location a location
316         * @param packageName a package name
317         * @param relativeName a relative name
318         * @return a file object, might return {@code null} if the file
319         * does not exist
320         * @throws IllegalArgumentException if the location is not known
321         * to this file manager and the file manager does not support
322         * unknown locations, or if {@code relativeName} is not valid
323         * @throws IOException if an I/O error occurred, or if {@link
324         * #close} has been called and this file manager cannot be
325         * reopened
326         * @throws IllegalStateException if {@link #close} has been called
327         * and this file manager cannot be reopened
328         */
329        FileObject getFileForInput(Location location,
330                                   String packageName,
331                                   String relativeName)
332            throws IOException;
333    
334        /**
335         * Gets a {@linkplain FileObject file object} for output
336         * representing the specified <a href="JavaFileManager.html#relative_name">relative
337         * name</a> in the specified package in the given location.
338         *
339         * <p>Optionally, this file manager might consider the sibling as
340         * a hint for where to place the output.  The exact semantics of
341         * this hint is unspecified.  Sun's compiler, javac, for
342         * example, will place class files in the same directories as
343         * originating source files unless a class file output directory
344         * is provided.  To facilitate this behavior, javac might provide
345         * the originating source file as sibling when calling this
346         * method.
347         *
348         * <p>If the returned object represents a {@linkplain
349         * JavaFileObject.Kind#SOURCE source} or {@linkplain
350         * JavaFileObject.Kind#CLASS class} file, it must be an instance
351         * of {@link JavaFileObject}.
352         *
353         * <p>Informally, the file object returned by this method is
354         * located in the concatenation of the location, package name, and
355         * relative name or next to the sibling argument.  See {@link
356         * #getFileForInput getFileForInput} for an example.
357         *
358         * @param location a location
359         * @param packageName a package name
360         * @param relativeName a relative name
361         * @param sibling a file object to be used as hint for placement;
362         * might be {@code null}
363         * @return a file object
364         * @throws IllegalArgumentException if sibling is not known to
365         * this file manager, or if the location is not known to this file
366         * manager and the file manager does not support unknown
367         * locations, or if {@code relativeName} is not valid
368         * @throws IOException if an I/O error occurred, or if {@link
369         * #close} has been called and this file manager cannot be
370         * reopened
371         * @throws IllegalStateException if {@link #close} has been called
372         * and this file manager cannot be reopened
373         */
374        FileObject getFileForOutput(Location location,
375                                    String packageName,
376                                    String relativeName,
377                                    FileObject sibling)
378            throws IOException;
379    
380        /**
381         * Flushes any resources opened for output by this file manager
382         * directly or indirectly.  Flushing a closed file manager has no
383         * effect.
384         *
385         * @throws IOException if an I/O error occurred
386         * @see #close
387         */
388        void flush() throws IOException;
389    
390        /**
391         * Releases any resources opened by this file manager directly or
392         * indirectly.  This might render this file manager useless and
393         * the effect of subsequent calls to methods on this object or any
394         * objects obtained through this object is undefined unless
395         * explicitly allowed.  However, closing a file manager which has
396         * already been closed has no effect.
397         *
398         * @throws IOException if an I/O error occurred
399         * @see #flush
400         */
401        void close() throws IOException;
402    }