summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2012-11-20 04:04:17 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2012-11-20 04:04:17 +0000
commit2779d6fe0f5dd175c54f7e415753b0224c593c03 (patch)
tree787591ededd6b2b9fc052fc9aeac272e505bbe4a
parentc54ec9a581cb50d3ee475b11a294c56ff6e15208 (diff)
downloadclasspath-2779d6fe0f5dd175c54f7e415753b0224c593c03.tar.gz
Add JavaFileManager and JavaFileObject, along with methods that use them in Filer and any dependent classes.
2012-11-19 Andrew John Hughes <gnu_andrew@member.fsf.org> * javax/annotation/processing/Filer.java: (createClassFile(CharSequence,Element...): Added. (createResource(JavaFileManager.Location, CharSequence, CharSequence, Element...)): Likewise. (createSourceFile(CharSequence,Element...): Likewise. (getResource(JavaFileManager.Location, CharSequence, CharSequence)): Likewise. * javax/annotation/processing/FilerException.java: New class. (FilerException(String)): Implemented. * javax/tools/JavaFileManager.java: New interface. (Location): New member interface. (Location.getName()): Added. (Location.isOutputLocation()): Likewise. (close()): Likewise. (flush()): Likewise. (getClassLoader(Location)): Likewise. (getFileForInput(Location,String,String)): Likewise. (getFileForOutput(Location,String,String,FileObject)): Likewise. (getJavaFileForInput(Location,String, JavaFileObject.Kind)): Likewise. (getJavaFileForOutput(Location,String, JavaFileObject.Kind,FileObject)): Likewise. (handleOption(String,Iterator)): Likewise. (hasLocation(Location)): Likewise. (inferBinaryName(Location,JavaFileObject)): Likewise. (isSameFile(FileObject,FileObject)): Likewise. (list(Location,String,Set,boolean)): Likewise. * javax/tools/JavaFileObject.java: New interface. (Kind): New inner enum. (CLASS): Added. (HTML): Likewise. (OTHER): Likewise. (SOURCE): Likewise. (Kind.extension): New public field. (Kind.Kind(String)): Implemented. (getKind()): Added. (isNameCompatible(String,Kind)): Likewise. * javax/tools/OptionChecker.java: New interface. (isSupportedOption(String)): Added. * javax/tools/StandardLocation.java: New enum. (ANNOTATION_PROCESSOR_PATH): Added. (CLASS_OUTPUT): Likewise. (CLASS_PATH): Likewise. (PLATFORM_CLASS_PATH): Likewise. (SOURCE_OUTPUT): Likewise. (SOURCE_PATH): Likewise. (locCache): Likewise. (getName()): Implemented. (locationFor(String)): Implemented. Signed-off-by: Andrew John Hughes <gnu_andrew@member.fsf.org>
-rw-r--r--ChangeLog59
-rw-r--r--javax/annotation/processing/Filer.java123
-rw-r--r--javax/annotation/processing/FilerException.java73
-rw-r--r--javax/tools/JavaFileManager.java351
-rw-r--r--javax/tools/JavaFileObject.java99
-rw-r--r--javax/tools/OptionChecker.java59
-rw-r--r--javax/tools/StandardLocation.java118
7 files changed, 882 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index f5413b444..29167c9a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,62 @@
+2012-11-19 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * javax/annotation/processing/Filer.java:
+ (createClassFile(CharSequence,Element...): Added.
+ (createResource(JavaFileManager.Location, CharSequence,
+ CharSequence, Element...)): Likewise.
+ (createSourceFile(CharSequence,Element...): Likewise.
+ (getResource(JavaFileManager.Location, CharSequence,
+ CharSequence)): Likewise.
+ * javax/annotation/processing/FilerException.java:
+ New class.
+ (FilerException(String)): Implemented.
+ * javax/tools/JavaFileManager.java:
+ New interface.
+ (Location): New member interface.
+ (Location.getName()): Added.
+ (Location.isOutputLocation()): Likewise.
+ (close()): Likewise.
+ (flush()): Likewise.
+ (getClassLoader(Location)): Likewise.
+ (getFileForInput(Location,String,String)):
+ Likewise.
+ (getFileForOutput(Location,String,String,FileObject)):
+ Likewise.
+ (getJavaFileForInput(Location,String,
+ JavaFileObject.Kind)): Likewise.
+ (getJavaFileForOutput(Location,String,
+ JavaFileObject.Kind,FileObject)): Likewise.
+ (handleOption(String,Iterator)): Likewise.
+ (hasLocation(Location)): Likewise.
+ (inferBinaryName(Location,JavaFileObject)): Likewise.
+ (isSameFile(FileObject,FileObject)): Likewise.
+ (list(Location,String,Set,boolean)): Likewise.
+ * javax/tools/JavaFileObject.java:
+ New interface.
+ (Kind): New inner enum.
+ (CLASS): Added.
+ (HTML): Likewise.
+ (OTHER): Likewise.
+ (SOURCE): Likewise.
+ (Kind.extension): New public field.
+ (Kind.Kind(String)): Implemented.
+ (getKind()): Added.
+ (isNameCompatible(String,Kind)): Likewise.
+ * javax/tools/OptionChecker.java:
+ New interface.
+ (isSupportedOption(String)): Added.
+ * javax/tools/StandardLocation.java:
+ New enum.
+ (ANNOTATION_PROCESSOR_PATH): Added.
+ (CLASS_OUTPUT): Likewise.
+ (CLASS_PATH): Likewise.
+ (PLATFORM_CLASS_PATH): Likewise.
+ (SOURCE_OUTPUT): Likewise.
+ (SOURCE_PATH): Likewise.
+ (locCache): Likewise.
+ (getName()): Implemented.
+ (locationFor(String)): Implemented.
+
2012-11-13 Andrew John Hughes <gnu_andrew@member.fsf.org>
* javax/annotation/processing/ProcessingEnvironment.java:
diff --git a/javax/annotation/processing/Filer.java b/javax/annotation/processing/Filer.java
index 4da90ca63..8f648245f 100644
--- a/javax/annotation/processing/Filer.java
+++ b/javax/annotation/processing/Filer.java
@@ -37,6 +37,14 @@ exception statement from your version. */
package javax.annotation.processing;
+import java.io.IOException;
+
+import javax.lang.model.element.Element;
+
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.FileObject;
+
/**
* <p>This interface supports the creation of new files by the
* annotation processor. Creating files via this interface means
@@ -88,4 +96,119 @@ package javax.annotation.processing;
*/
public interface Filer
{
+
+ /**
+ * Returns a {@link JavaFileObject} for writing a class
+ * file. The name and location of the created file are
+ * based on the specified type name. The location used
+ * is relative to the root location for class files.
+ * A class file may be created for a package by appending
+ * the suffix {@code ".package-info"} to the name. The
+ * contents of the class file should be compatible with
+ * source version being used for this run of the annotation
+ * processor.
+ *
+ * @param name the name of the type (or package if
+ * the {@code ".package-info"} suffix) to create
+ * a class file for.
+ * @param elements program elements associated with this class
+ * file. May be {@code null} or incomplete.
+ * @return access to the new class file via a {@link JavaFileObject}.
+ * @throws FilerException if the same pathname has already been used,
+ * the same type has already been created or
+ * the name is invalid.
+ * @throws IOException if an I/O error occurs.
+ */
+ JavaFileObject createClassFile(CharSequence name, Element... elements)
+ throws IOException;
+
+ /**
+ * <p>Returns a {@link FileObject} for writing a resource file.
+ * The name and location of the created file are determined
+ * by combining the given location (either that used by class
+ * files, source files or another location supported by the
+ * implementation), the name of a package in which the resource
+ * should live (if any), and the specified name.</p>
+ * <p>Files created by this method are not registered for annotation
+ * processing.</p>
+ *
+ * @param location the location to use for the resource. Can be
+ * {@link javax.tools.StandardLocation#CLASS_OUTPUT},
+ * {@link javax.tools.StandardLocation#SOURCE_OUTPUT},
+ * or another location supported by the implementation.
+ * @param pkg the package which should contain the resource, or the
+ * empty string if one is not used.
+ * @param relName the final path components of the file name, which will
+ * be relative to the location and (if specified) the package.
+ * @param elements program elements associated with this resource
+ * file. May be {@code null} or incomplete.
+ * @return access to the new resource file via a {@link FileObject}.
+ * @throws FilerException if the same pathname has already been used.
+ * @throws IOException if an I/O error occurs.
+ * @throws IllegalArgumentException if the location specified is not supported,
+ * or {@code relName} is not relative.
+ */
+ FileObject createResource(JavaFileManager.Location location,
+ CharSequence pkg, CharSequence relName,
+ Element... elements)
+ throws IOException;
+
+ /**
+ * <p>Returns a {@link JavaFileObject} for writing a source
+ * file. The name and location of the created file are
+ * based on the specified type name. If more than one
+ * type is being declared, the top-level one should be used.
+ * The location used is relative to the root location for
+ * source files. A source file may be created for a package by
+ * appending the suffix {@code ".package-info"} to the name. The
+ * contents of the source file should be compatible with
+ * source version being used for this run of the annotation
+ * processor.</p>
+ * <p>The character set used by the {@link java.io.OutputStream}
+ * of the returned object is determined by the implementation,
+ * and may be set using either the platform default or by an
+ * option passed to the annotation processing tool. To override
+ * this, users can wrap the stream in an
+ * {@link java.io.OutputStreamWriter}.</p>
+ *
+ * @param name the fully-qualified name of the type (or package if
+ * the {@code ".package-info"} suffix) to create
+ * a source file for.
+ * @param elements program elements associated with this source
+ * file. May be {@code null} or incomplete.
+ * @return access to the new source file via a {@link JavaFileObject}.
+ * @throws FilerException if the same pathname has already been used,
+ * the same type has already been created or
+ * the name is invalid.
+ * @throws IOException if an I/O error occurs.
+ */
+ JavaFileObject createSourceFile(CharSequence name, Element... elements)
+ throws IOException;
+
+ /**
+ * Returns a {@link FileObject} for reading a resource file.
+ * The name and location of the file to read are determined
+ * by combining the given location (either that used by class
+ * files, source files or another location supported by the
+ * implementation), the name of a package in which the resource
+ * lives (if any), and the specified name.
+ *
+ * @param location the location to use for the resource. Can be
+ * {@link javax.tools.StandardLocation#CLASS_OUTPUT},
+ * {@link javax.tools.StandardLocation#SOURCE_OUTPUT},
+ * or another location supported by the implementation.
+ * @param pkg the package which contains the resource, or the
+ * empty string if one is not used.
+ * @param relName the final path components of the file name, which will
+ * be relative to the location and (if specified) the package.
+ * @return access to the new resource file via a {@link FileObject}.
+ * @throws FilerException if the same pathname is open for writing.
+ * @throws IOException if an I/O error occurs.
+ * @throws IllegalArgumentException if the location specified is not supported,
+ * or {@code relName} is not relative.
+ */
+ FileObject getResource(JavaFileManager.Location location,
+ CharSequence pkg, CharSequence relName)
+ throws IOException;
+
}
diff --git a/javax/annotation/processing/FilerException.java b/javax/annotation/processing/FilerException.java
new file mode 100644
index 000000000..fd00665e3
--- /dev/null
+++ b/javax/annotation/processing/FilerException.java
@@ -0,0 +1,73 @@
+/* FilerException.java -- Attempt to violate a Filer guarantee.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.annotation.processing;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a {@link Filer} detects an attempt to violate one
+ * of its guarantees. This may be an attempt to create the same
+ * file multiple times, an attempt to create multiple files of the
+ * same type or an attempt to create a file for a type with an
+ * invalid name.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+public class FilerException
+ extends IOException
+{
+
+ /**
+ * Compatible with OpenJDK 1.6+
+ */
+ private static final long serialVersionUID = 8426423106453163293L;
+
+ /**
+ * Constructs a new {@code FilerException} with the specified
+ * message. The message should contain the name of the file
+ * attempting to be opened.
+ *
+ * @param message the reason for the exception, or {@code null}.
+ */
+ public FilerException(String message)
+ {
+ super(message);
+ }
+
+}
diff --git a/javax/tools/JavaFileManager.java b/javax/tools/JavaFileManager.java
new file mode 100644
index 000000000..990962c95
--- /dev/null
+++ b/javax/tools/JavaFileManager.java
@@ -0,0 +1,351 @@
+/* JavaFileManager.java -- File manager for source & class file tools.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.tools;
+
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * <p>File manager for tools which operate on source and class files.
+ * In this context, the term {@code file} is used to refer to the abstract
+ * concept of a data source, rather than specifically a regular file on
+ * a filesystem.</p>
+ * <p>The file manager determines where to create new {@link FileObject}s.
+ * It may have a default directory where files are created. The user may
+ * provide hints as to how to perform file creation, but the file manager
+ * may choose to ignore these.</p>
+ * <p>For methods in this interface which use class names, these must
+ * be given in the internal virtual machine form of fully qualified
+ * class and interface names. The use of '/' and '.' are interchangeable,
+ * making {@code java.lang.Object}, {@code java/lang.Object} and
+ * {@code java/lang/Object} all equivalent.</p>
+ * <p>All names should be treated as being case-sensitive. If the underlying
+ * system is not case-aware, steps should be taken to handle this in the
+ * implementation, such as the use of {@link java.io.File#getCanonicalFile()}
+ * to preserve case.</p>
+ * <p>For methods in this interface which use relative names, these are
+ * path separated by {@code '/'} and do not include the
+ * segments {@code '.'} and {@code '..'}, so that they may only
+ * refer to subdirectories. A valid relative name must match
+ * the "path-rootless" rule of RFC 3986, section 3.3. The construction
+ * {@code URI.create(name).normalize().getPath().equals(name)} should hold.</p>
+ * <p>All methods may throw a {@link SecurityException}. All methods may
+ * throw a {@link NullPointerException} if an argument is null, unless
+ * otherwise specified. It is not required that the implementation support
+ * concurrent access to the file manager, but the file objects created by
+ * it should be thread-safe.</p>
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+public interface JavaFileManager
+ extends Closeable, Flushable, OptionChecker
+{
+
+ /**
+ * Interface for obtaining the location of {@link FileObject}s.
+ * Used by the file manager to know where to create or locate them.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+ public static interface Location
+ {
+ /**
+ * Returns the name of this location.
+ *
+ * @return the name.
+ */
+ String getName();
+
+ /**
+ * Returns true if this location is used for output.
+ *
+ * @return true if the location is used for output.
+ */
+ boolean isOutputLocation();
+ }
+
+ /**
+ * Closes the file manager and releases any resources in
+ * use. Calling {@code close()} on an already closed
+ * file manager has no effect. The effect of calling
+ * other methods on a closed file manager is undefined,
+ * unless specified in the documentation of that method.
+ *
+ * @throws IOException if an I/O error occurs.
+ * @see #flush()
+ */
+ void close() throws IOException;
+
+ /**
+ * Flushes data to any resources controlled by this file
+ * manager. Flushing a closed file manager has no effect.
+ *
+ * @throws IOException if an I/O error occurs.
+ * @see #close()
+ */
+ void flush() throws IOException;
+
+ /**
+ * Returns the class loader that is responsible for loading
+ * class files from the specified location. For example,
+ * {@code getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_PATH)}
+ * will return the class loader which is used to load
+ * annotation processors.
+ *
+ * @param location the location to retrieve the class loader for.
+ * @return the class loader for class files in that location, or
+ * {@code null} if the location is unknown or class loading
+ * from that location is disabled.
+ * @throws SecurityException if the class loader is not retrievable
+ * under the current security manager.
+ * @throws IllegalStateException if {@link #close()} has been called
+ * and the file manager can't be reopened.
+ */
+ ClassLoader getClassLoader(Location location);
+
+ /**
+ * <p>Returns a file object for reading a file. If this
+ * is a source or class file, the returned instance
+ * must be a {@link JavaFileObject}. The file name is
+ * constructed as a concatenation of the location, the
+ * package name and the relative file name.</p>
+ * <p>For example, for the call
+ * {@ocode getFileForInput(StandardLocation.SOURCE_PATH,
+ * "gnu.classpath.util", "CoolCode.java")}, assuming
+ * that the source path is set to
+ * {@code "/home/bob/sources"}, the returned file object
+ * would represent the file
+ * {@code "/home/bob/sources/gnu/classpath/util/CoolCode.java"}.</p>
+ *
+ * @param location the base location for the file.
+ * @param pkg the package the file will be read from.
+ * @param relName the path to the file, relative to {@code location+pkg}.
+ * @return a file object or may return {@code null} if the file does not exist.
+ * @throws IllegalArgumentException if the location is unknown and unknown locations
+ * are not supported, or if the relative name is invalid.
+ * @throws IOException if an I/O error occurs, or the file manager
+ * has been closed and can't be reopened.
+ * @throws IllegalStateException if the file manager has been closed and can't be reopened.
+ */
+ FileObject getFileForInput(Location location, String pkg, String relName)
+ throws IOException;
+
+ /**
+ * <p>Returns a file object for writing a file. If this
+ * is a source or class file, the returned instance
+ * must be a {@link JavaFileObject}. The file name is
+ * constructed as a concatenation of the location, the
+ * package name and the relative file name.</p>
+ * <p>For example, for the call
+ * {@ocode getFileForOutput(StandardLocation.SOURCE_OUTPUT,
+ * "gnu.classpath.util", "GenSyms.java")}, assuming
+ * that the source output is set to
+ * {@code "/home/bob/generated"}, the returned file object
+ * would represent the file
+ * {@code "/home/bob/generated/gnu/classpath/util/GenSyms.java"}.</p>
+ * <p>The file manager may optionally use the supplied
+ * sibling as a hint as to where to place the output file.
+ * The exact semantics of this hint are left to the implementation.
+ * As an example, the compiler places class files in the same location
+ * as the corresponding source file, if no destination is specified.
+ * To facilitate this, the source file location may be passed as
+ * a hint to the file manager.</p>
+ *
+ * @param location the base location for the file.
+ * @param pkg the package in which the file will be stored.
+ * @param relName the path to the file, relative to {@code location+pkg}.
+ * @param sibling an optional hint as to where to place the output file.
+ * May be {@code null}.
+ * @return a file object.
+ * @throws IllegalArgumentException if the location is unknown and unknown locations
+ * are not supported, if the relative name is invalid or
+ * if the sibling is not known to this file manager.
+ * @throws IOException if an I/O error occurs, or the file manager
+ * has been closed and can't be reopened.
+ * @throws IllegalStateException if the file manager has been closed and can't be reopened.
+ */
+ FileObject getFileForOutput(Location location, String pkg, String relName,
+ FileObject sibling)
+ throws IOException;
+
+ /**
+ * <p>Returns a {@link JavaFileObject} for reading
+ * a source file or class file. The file name is
+ * constructed as a concatenation of the location
+ * and the information provided by the type name
+ * and the kind of the file.</p>
+ * <p>For example, for the call
+ * {@ocode getJavaFileForInput(StandardLocation.SOURCE_PATH,
+ * "gnu.classpath.util.CoolCode", JavaFileObject.Kind.SOURCE)},
+ * assuming that the source path is set to
+ * {@code "/home/bob/sources"}, the returned file object
+ * would represent the file
+ * {@code "/home/bob/sources/gnu/classpath/util/CoolCode.java"}.</p>
+ *
+ * @param location the base location for the file.
+ * @param className the name of the class.
+ * @param kind the kind of file, either {@link JavaFileObject.Kind.SOURCE} or
+ * {@link JavaFileObject.Kind.CLASS}.
+ * @return a file object or may return {@code null} if the file does not exist.
+ * @throws IllegalArgumentException if the location is unknown and unknown locations
+ * are not supported, or if the kind is invalid.
+ * @throws IOException if an I/O error occurs, or the file manager
+ * has been closed and can't be reopened.
+ * @throws IllegalStateException if the file manager has been closed and can't be reopened.
+ */
+ JavaFileObject getJavaFileForInput(Location location, String className, JavaFileObject.Kind kind)
+ throws IOException;
+
+ /**
+ * <p>Returns a {@link JavaFileObject} for writing a
+ * source or class file. The file name is
+ * constructed as a concatenation of the location and
+ * the information provided by the type name and the
+ * kind of the file.</p>
+ * <p>For example, for the call
+ * {@ocode getJavaFileForOutput(StandardLocation.CLASS_OUTPUT,
+ * "gnu.classpath.util.CoolCode", JavaFileObject.Kind.CLASS)}, assuming
+ * that the class output is set to
+ * {@code "/home/bob/build"}, the returned file object
+ * would represent the file
+ * {@code "/home/bob/build/gnu/classpath/util/GenSyms.class"}.</p>
+ * <p>The file manager may optionally use the supplied
+ * sibling as a hint as to where to place the output file.
+ * The exact semantics of this hint are left to the implementation.
+ * As an example, the compiler places class files in the same location
+ * as the corresponding source file, if no destination is specified.
+ * To facilitate this, the source file location may be passed as
+ * a hint to the file manager.</p>
+ *
+ * @param location the base location for the file.
+ * @param className the name of the class.
+ * @param kind the kind of file, either {@link JavaFileObject.Kind.SOURCE} or
+ * {@link JavaFileObject.Kind.CLASS}.
+ * @param sibling an optional hint as to where to place the output file.
+ * May be {@code null}.
+ * @return a file object.
+ * @throws IllegalArgumentException if the location is unknown and unknown locations
+ * are not supported, if the kind is invalid or
+ * if the sibling is not known to this file manager.
+ * @throws IOException if an I/O error occurs, or the file manager
+ * has been closed and can't be reopened.
+ * @throws IllegalStateException if the file manager has been closed and can't be reopened.
+ */
+ JavaFileObject getJavaFileForOutput(Location location, String className,
+ JavaFileObject.Kind kind, FileObject sibling)
+ throws IOException;
+
+ /**
+ * Processes one option. If the specified option
+ * is supported by this file manager, it will read
+ * any necessary arguments to the option from the
+ * iterator and then return {@code true}. Otherwise, it
+ * will return {@code false}.
+ *
+ * @param option the option to process.
+ * @param remaining the remaining arguments/options.
+ * @return true if the option was handled.
+ * @throws IllegalArgumentException if the option is used incorrectly.
+ * @throws IllegalStateException if the file manager has been closed and can't be reopened.
+ */
+ boolean handleOption(String option, Iterator<String> remaining);
+
+ /**
+ * Returns {@code true} if the specified location
+ * is known to this file manager.
+ *
+ * @param location the location to check.
+ * @return true if the location is known.
+ */
+ boolean hasLocation(Location location);
+
+ /**
+ * Infers a binary name for the given file object,
+ * based on its location. The returned name may
+ * not be a valid binary name, according to the
+ * Java language specification.
+ *
+ * @param location the location to use as a basis.
+ * @param file the file object.
+ * @return a binary name or {@code null} if the file
+ * object is not found in the given location.
+ * @throws IllegalStateException if the file manager has been closed and can't be reopened.
+ */
+ String inferBinaryName(Location location, JavaFileObject file);
+
+ /**
+ * Returns true if the two given file objects represent
+ * the same file.
+ *
+ * @param x the first object.
+ * @param y the second object.
+ * @return true if {@code x} and {@code y} represent the
+ * same file.
+ * @throws IllegalArgumentException if either {@code x} or
+ * {@code y} were created by a foreign file manager and
+ * this file manager does not support such comparisons.
+ */
+ boolean isSameFile(FileObject x, FileObject y);
+
+ /**
+ * Lists all file objects matching the given criteria in the
+ * specified location. If {@code recurse} is true, the list
+ * will include those found in subpackages. Note that a file
+ * manager may not return a {@code null} list or throw an
+ * exception if the location is unknown.
+ *
+ * @param location the location to search.
+ * @param pkg the name of the package to search.
+ * @param kinds the kinds of object to return.
+ * @param recurse {@code true} if subpackages should be searched.
+ * @return an {@link Iterable} over the matching file object.
+ * @throws IOException if an I/O error occurs, or the file manager
+ * has been closed and can't be reopened.
+ * @throws IllegalStateException if the file manager has been closed and can't be reopened.
+ */
+ Iterable<JavaFileObject> list(Location location, String pkg,
+ Set<JavaFileObject.Kind> kinds, boolean recurse)
+ throws IOException;
+
+}
diff --git a/javax/tools/JavaFileObject.java b/javax/tools/JavaFileObject.java
new file mode 100644
index 000000000..09bd3417d
--- /dev/null
+++ b/javax/tools/JavaFileObject.java
@@ -0,0 +1,99 @@
+/* JavaFileObject.java -- Abstraction for working with class & source files.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.tools;
+
+/**
+ * Abstraction for tools working with source and class files.
+ * All methods may throw a {@link SecurityException}. All
+ * methods may throw a {@link NullPointerException} if supplied
+ * with a {@code null} argument, unless otherwise specified.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+public interface JavaFileObject
+ extends FileObject
+{
+
+ /**
+ * Kinds of Java files.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+ public enum Kind
+ {
+ /** Java class files, which end in {@code ".class"} */ CLASS (".class"),
+ /** Web pages, which end in {@code "*.html"} */ HTML (".html"),
+ /** Any other kind of file. */ OTHER (""),
+ /** Java source files, which end in {@code ".java"} */ SOURCE (".java");
+
+ /**
+ * The file extension usually used for files of this
+ * type. If there is no conventional extension for
+ * this type, this field is set to the empty string,
+ * {@code ""}.
+ */
+ public final String extension;
+
+ Kind(String extension)
+ {
+ this.extension = extension;
+ }
+
+ }
+
+ /**
+ * Returns the kind of this file object.
+ *
+ * @return the kind.
+ */
+ Kind getKind();
+
+ /**
+ * Checks if this file object represents the specified
+ * kind of file for the supplied type. The class name is
+ * a simple name i.e. not qualified.
+ *
+ * @param simpleName the simple name of the class.
+ * @param kind the kind of file.
+ * @return true if this object matches the type specified.
+ */
+ boolean isNameCompatible(String simpleName, Kind kind);
+
+}
diff --git a/javax/tools/OptionChecker.java b/javax/tools/OptionChecker.java
new file mode 100644
index 000000000..13475d01f
--- /dev/null
+++ b/javax/tools/OptionChecker.java
@@ -0,0 +1,59 @@
+/* OptionChecker.java -- Interface for recognising options.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.tools;
+
+/**
+ * Interface for recognising options.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+public interface OptionChecker
+{
+
+ /**
+ * Determines if the specified option is supported or not,
+ * and, if so, how many arguments it takes.
+ *
+ * @param option the name of the option.
+ * @return the number of arguments the option takes, or
+ * -1 if the option is not supported.
+ */
+ int isSupportedOption(String option);
+
+}
diff --git a/javax/tools/StandardLocation.java b/javax/tools/StandardLocation.java
new file mode 100644
index 000000000..f3d2cfb63
--- /dev/null
+++ b/javax/tools/StandardLocation.java
@@ -0,0 +1,118 @@
+/* StandardLocation.java -- Enumeration of standard file locations.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.tools;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static javax.tools.JavaFileManager.Location;
+
+/**
+ * Enumeration of standard locations for storing
+ * {@link FileObject}s.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+public enum StandardLocation
+ implements Location
+{
+ /** Location where annotation processors are found. */
+ ANNOTATION_PROCESSOR_PATH { public boolean isOutputLocation() { return false; } },
+ /** Location to write class files to. */
+ CLASS_OUTPUT { public boolean isOutputLocation() { return true; } },
+ /** Location where class files are found. */
+ CLASS_PATH { public boolean isOutputLocation() { return false; } },
+ /** Location where platform class files are found. */
+ PLATFORM_CLASS_PATH { public boolean isOutputLocation() { return false; } },
+ /** Location to write source files to. */
+ SOURCE_OUTPUT { public boolean isOutputLocation() { return true; } },
+ /** Location where source files are found. */
+ SOURCE_PATH { public boolean isOutputLocation() { return false; } };
+
+ private static final ConcurrentMap<String,Location> locCache =
+ new ConcurrentHashMap<String,Location>();
+
+ static
+ {
+ for (StandardLocation loc : values())
+ locCache.put(loc.name(), loc);
+ }
+
+ /**
+ * Returns the name of the location. This is simply
+ * the enum constant.
+ *
+ * @return the name of the location.
+ */
+ public String getName()
+ {
+ return name();
+ }
+
+ /**
+ * Returns an instance of {@link JavaFileManager.Location}
+ * for the given name. If the name is one of the standard
+ * names, the enumeration constant is returned. Otherwise,
+ * a new instance is generated. For location names {@code x}
+ * and {@code y}, {@code locationFor(x) == locationFor(y)}
+ * if, and only if, {@code x.equals(y)}. The returned location
+ * will only be an output location if the name ends with
+ * the suffix {@code "_OUTPUT"}.
+ *
+ * @param name the name of the location.
+ * @return the location.
+ */
+ public static Location locationFor(String name)
+ {
+ final String locName = name;
+ Location loc = locCache.get(name);
+ if (loc == null)
+ {
+ loc = new Location() {
+ public String getName() { return locName; }
+ public boolean isOutputLocation() { return locName.endsWith("_OUTPUT"); }
+ };
+ Location mapLoc = locCache.putIfAbsent(name, loc);
+ if (mapLoc != null) // Someone got there first
+ loc = mapLoc;
+ }
+ return loc;
+ }
+
+}