Filer.java revision 4056:adef848660f9
1/*
2 * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.annotation.processing;
27
28import javax.tools.JavaFileManager;
29import javax.tools.*;
30import javax.lang.model.element.Element;
31import javax.lang.model.util.Elements;
32import java.io.IOException;
33
34/**
35 * This interface supports the creation of new files by an annotation
36 * processor.  Files created in this way will be known to the
37 * annotation processing tool implementing this interface, better
38 * enabling the tool to manage them.  Source and class files so
39 * created will be {@linkplain RoundEnvironment#getRootElements
40 * considered for processing} by the tool in a subsequent {@linkplain
41 * RoundEnvironment round of processing} after the {@code close}
42 * method has been called on the {@code Writer} or {@code
43 * OutputStream} used to write the contents of the file.
44 *
45 * Three kinds of files are distinguished: source files, class files,
46 * and auxiliary resource files.
47 *
48 * <p> There are two distinguished supported locations (subtrees
49 * within the logical file system) where newly created files are
50 * placed: one for {@linkplain
51 * javax.tools.StandardLocation#SOURCE_OUTPUT new source files}, and
52 * one for {@linkplain javax.tools.StandardLocation#CLASS_OUTPUT new
53 * class files}.  (These might be specified on a tool's command line,
54 * for example, using flags such as {@code -s} and {@code -d}.)  The
55 * actual locations for new source files and new class files may or
56 * may not be distinct on a particular run of the tool.  Resource
57 * files may be created in either location.  The methods for reading
58 * and writing resources take a relative name argument.  A relative
59 * name is a non-null, non-empty sequence of path segments separated
60 * by {@code '/'}; {@code '.'} and {@code '..'} are invalid path
61 * segments.  A valid relative name must match the
62 * &quot;path-rootless&quot; rule of <a
63 * href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>, section
64 * 3.3.
65 *
66 * <p>The file creation methods take a variable number of arguments to
67 * allow the <em>originating elements</em> to be provided as hints to
68 * the tool infrastructure to better manage dependencies.  The
69 * originating elements are the types or packages (representing {@code
70 * package-info} files) or modules (representing {@code
71 * module-info} files) which caused an annotation processor to
72 * attempt to create a new file.  For example, if an annotation
73 * processor tries to create a source file, {@code
74 * GeneratedFromUserSource}, in response to processing
75 *
76 * <blockquote><pre>
77 *  &#64;Generate
78 *  public class UserSource {}
79 * </pre></blockquote>
80 *
81 * the type element for {@code UserSource} should be passed as part of
82 * the creation method call as in:
83 *
84 * <blockquote><pre>
85 *      filer.createSourceFile("GeneratedFromUserSource",
86 *                             eltUtils.getTypeElement("UserSource"));
87 * </pre></blockquote>
88 *
89 * If there are no originating elements, none need to be passed.  This
90 * information may be used in an incremental environment to determine
91 * the need to rerun processors or remove generated files.
92 * Non-incremental environments may ignore the originating element
93 * information.
94 *
95 * <p> During each run of an annotation processing tool, a file with a
96 * given pathname may be created only once.  If that file already
97 * exists before the first attempt to create it, the old contents will
98 * be deleted.  Any subsequent attempt to create the same file during
99 * a run will throw a {@link FilerException}, as will attempting to
100 * create both a class file and source file for the same type name or
101 * same package name.  The {@linkplain Processor initial inputs} to
102 * the tool are considered to be created by the zeroth round;
103 * therefore, attempting to create a source or class file
104 * corresponding to one of those inputs will result in a {@link
105 * FilerException}.
106 *
107 * <p> In general, processors must not knowingly attempt to overwrite
108 * existing files that were not generated by some processor.  A {@code
109 * Filer} may reject attempts to open a file corresponding to an
110 * existing type, like {@code java.lang.Object}.  Likewise, the
111 * invoker of the annotation processing tool must not knowingly
112 * configure the tool such that the discovered processors will attempt
113 * to overwrite existing files that were not generated.
114 *
115 * <p> Processors can indicate a source or class file is generated by
116 * including a {@code javax.annotation.Generated} annotation if the
117 * environment is configured so that that type is accessible.
118 *
119 * @apiNote Some of the effect of overwriting a file can be
120 * achieved by using a <i>decorator</i>-style pattern.  Instead of
121 * modifying a class directly, the class is designed so that either
122 * its superclass is generated by annotation processing or subclasses
123 * of the class are generated by annotation processing.  If the
124 * subclasses are generated, the parent class may be designed to use
125 * factories instead of public constructors so that only subclass
126 * instances would be presented to clients of the parent class.
127 *
128 * @author Joseph D. Darcy
129 * @author Scott Seligman
130 * @author Peter von der Ah&eacute;
131 * @since 1.6
132 */
133public interface Filer {
134    /**
135     * Creates a new source file and returns an object to allow
136     * writing to it. A source file for a type, or a package can
137     * be created.
138     *
139     * The file's name and path (relative to the {@linkplain
140     * StandardLocation#SOURCE_OUTPUT root output location for source
141     * files}) are based on the name of the item to be declared in
142     * that file as well as the specified module for the item (if
143     * any).
144     *
145     * If more than one type is being declared in a single file (that
146     * is, a single compilation unit), the name of the file should
147     * correspond to the name of the principal top-level type (the
148     * public one, for example).
149     *
150     * <p>A source file can also be created to hold information about
151     * a package, including package annotations.  To create a source
152     * file for a named package, have the {@code name} argument be the
153     * package's name followed by {@code ".package-info"}; to create a
154     * source file for an unnamed package, use {@code "package-info"}.
155     *
156     * <p>The optional module name is prefixed to the type name or
157     * package name and separated using a "{@code /}" character. For
158     * example, to create a source file for type {@code a.B} in module
159     * {@code foo}, use a {@code name} argument of {@code "foo/a.B"}.
160     *
161     * <p>If no explicit module prefix is given and modules are supported
162     * in the environment, a suitable module is inferred. If a suitable
163     * module cannot be inferred {@link FilerException} is thrown.
164     * An implementation may use information about the configuration of
165     * the annotation processing tool as part of the inference.
166     *
167     * <p>Creating a source file in or for an unnamed package in a named
168     * module is <em>not</em> supported.
169     *
170     * @apiNote To use a particular {@linkplain
171     * java.nio.charset.Charset charset} to encode the contents of the
172     * file, an {@code OutputStreamWriter} with the chosen charset can
173     * be created from the {@code OutputStream} from the returned
174     * object. If the {@code Writer} from the returned object is
175     * directly used for writing, its charset is determined by the
176     * implementation.  An annotation processing tool may have an
177     * {@code -encoding} flag or analogous option for specifying this;
178     * otherwise, it will typically be the platform's default
179     * encoding.
180     *
181     * <p>To avoid subsequent errors, the contents of the source file
182     * should be compatible with the {@linkplain
183     * ProcessingEnvironment#getSourceVersion source version} being used
184     * for this run.
185     *
186     * @implNote In the reference implementation, if the annotation
187     * processing tool is processing a single module <i>M</i>,
188     * then <i>M</i> is used as the module for files created without
189     * an explicit module prefix. If the tool is processing multiple
190     * modules, and {@link
191     * Elements#getPackageElement(java.lang.CharSequence)
192     * Elements.getPackageElement(package-of(name))}
193     * returns a package, the module that owns the returned package is used
194     * as the target module. A separate option may be used to provide the target
195     * module if it cannot be determined using the above rules.
196     *
197     * @param name  canonical (fully qualified) name of the principal type
198     *          being declared in this file or a package name followed by
199     *          {@code ".package-info"} for a package information file
200     * @param originatingElements type or package or module elements causally
201     * associated with the creation of this file, may be elided or
202     * {@code null}
203     * @return a {@code JavaFileObject} to write the new source file
204     * @throws FilerException if the same pathname has already been
205     * created, the same type has already been created, the name is
206     * otherwise not valid for the entity requested to being created,
207     * if the target module cannot be determined, if the target
208     * module is not writable, or a module is specified when the environment
209     * doesn't support modules.
210     * @throws IOException if the file cannot be created
211     * @jls 7.3 Compilation Units
212     */
213    JavaFileObject createSourceFile(CharSequence name,
214                                    Element... originatingElements) throws IOException;
215
216    /**
217     * Creates a new class file, and returns an object to allow
218     * writing to it. A class file for a type, or a package can
219     * be created.
220     *
221     * The file's name and path (relative to the {@linkplain
222     * StandardLocation#CLASS_OUTPUT root output location for class
223     * files}) are based on the name of the item to be declared as
224     * well as the specified module for the item (if any).
225     *
226     * <p>A class file can also be created to hold information about a
227     * package, including package annotations. To create a class file
228     * for a named package, have the {@code name} argument be the
229     * package's name followed by {@code ".package-info"}; creating a
230     * class file for an unnamed package is not supported.
231     *
232     * <p>The optional module name is prefixed to the type name or
233     * package name and separated using a "{@code /}" character. For
234     * example, to create a class file for type {@code a.B} in module
235     * {@code foo}, use a {@code name} argument of {@code "foo/a.B"}.
236     *
237     * <p>If no explicit module prefix is given and modules are supported
238     * in the environment, a suitable module is inferred. If a suitable
239     * module cannot be inferred {@link FilerException} is thrown.
240     * An implementation may use information about the configuration of
241     * the annotation processing tool as part of the inference.
242     *
243     * <p>Creating a class file in or for an unnamed package in a named
244     * module is <em>not</em> supported.
245     *
246     * @apiNote To avoid subsequent errors, the contents of the class
247     * file should be compatible with the {@linkplain
248     * ProcessingEnvironment#getSourceVersion source version} being
249     * used for this run.
250     *
251     * @implNote In the reference implementation, if the annotation
252     * processing tool is processing a single module <i>M</i>,
253     * then <i>M</i> is used as the module for files created without
254     * an explicit module prefix. If the tool is processing multiple
255     * modules, and {@link
256     * Elements#getPackageElement(java.lang.CharSequence)
257     * Elements.getPackageElement(package-of(name))}
258     * returns a package, the module that owns the returned package is used
259     * as the target module. A separate option may be used to provide the target
260     * module if it cannot be determined using the above rules.
261     *
262     * @param name binary name of the type being written or a package name followed by
263     *          {@code ".package-info"} for a package information file
264     * @param originatingElements type or package or module elements causally
265     * associated with the creation of this file, may be elided or
266     * {@code null}
267     * @return a {@code JavaFileObject} to write the new class file
268     * @throws FilerException if the same pathname has already been
269     * created, the same type has already been created, the name is
270     * not valid for a type, if the target module cannot be determined,
271     * if the target module is not writable, or a module is specified when
272     * the environment doesn't support modules.
273     * @throws IOException if the file cannot be created
274     */
275    JavaFileObject createClassFile(CharSequence name,
276                                   Element... originatingElements) throws IOException;
277
278    /**
279     * Creates a new auxiliary resource file for writing and returns a
280     * file object for it.  The file may be located along with the
281     * newly created source files, newly created binary files, or
282     * other supported location.  The locations {@link
283     * StandardLocation#CLASS_OUTPUT CLASS_OUTPUT} and {@link
284     * StandardLocation#SOURCE_OUTPUT SOURCE_OUTPUT} must be
285     * supported. The resource may be named relative to some module
286     * and/or package (as are source and class files), and from there
287     * by a relative pathname.  In a loose sense, the full pathname of
288     * the new file will be the concatenation of {@code location},
289     * {@code moduleAndPkg}, and {@code relativeName}.
290     *
291     * If {@code moduleAndPkg} contains a "{@code /}" character, the
292     * prefix before the "{@code /}" character is the module name and
293     * the suffix after the "{@code /}" character is the package
294     * name. The package suffix may be empty. If {@code moduleAndPkg}
295     * does not contain a "{@code /}" character, the entire argument
296     * is interpreted as a package name.
297     *
298     * <p>If the given location is neither a {@linkplain
299     * JavaFileManager.Location#isModuleOrientedLocation()
300     * module oriented location}, nor an {@linkplain
301     * JavaFileManager.Location#isOutputLocation()
302     * output location containing multiple modules}, and the explicit
303     * module prefix is given, {@link FilerException} is thrown.
304     *
305     * <p>If the given location is either a module oriented location,
306     * or an output location containing multiple modules, and no explicit
307     * modules prefix is given, a suitable module is
308     * inferred. If a suitable module cannot be inferred {@link
309     * FilerException} is thrown. An implementation may use information
310     * about the configuration of the annotation processing tool
311     * as part of the inference.
312     *
313     * <p>Files created via this method are <em>not</em> registered for
314     * annotation processing, even if the full pathname of the file
315     * would correspond to the full pathname of a new source file
316     * or new class file.
317     *
318     * @implNote In the reference implementation, if the annotation
319     * processing tool is processing a single module <i>M</i>,
320     * then <i>M</i> is used as the module for files created without
321     * an explicit module prefix. If the tool is processing multiple
322     * modules, and {@link
323     * Elements#getPackageElement(java.lang.CharSequence)
324     * Elements.getPackageElement(package-of(name))}
325     * returns a package, the module that owns the returned package is used
326     * as the target module. A separate option may be used to provide the target
327     * module if it cannot be determined using the above rules.
328     *
329     * @param location location of the new file
330     * @param moduleAndPkg module and/or package relative to which the file
331     *           should be named, or the empty string if none
332     * @param relativeName final pathname components of the file
333     * @param originatingElements type or package or module elements causally
334     * associated with the creation of this file, may be elided or
335     * {@code null}
336     * @return a {@code FileObject} to write the new resource
337     * @throws IOException if the file cannot be created
338     * @throws FilerException if the same pathname has already been
339     * created, if the target module cannot be determined,
340     * or if the target module is not writable, or if an explicit
341     * target module is specified and the location does not support it.
342     * @throws IllegalArgumentException for an unsupported location
343     * @throws IllegalArgumentException if {@code moduleAndPkg} is ill-formed
344     * @throws IllegalArgumentException if {@code relativeName} is not relative
345     */
346   FileObject createResource(JavaFileManager.Location location,
347                             CharSequence moduleAndPkg,
348                             CharSequence relativeName,
349                             Element... originatingElements) throws IOException;
350
351    /**
352     * Returns an object for reading an existing resource.  The
353     * locations {@link StandardLocation#CLASS_OUTPUT CLASS_OUTPUT}
354     * and {@link StandardLocation#SOURCE_OUTPUT SOURCE_OUTPUT} must
355     * be supported.
356     *
357     * <p>If {@code moduleAndPkg} contains a "{@code /}" character, the
358     * prefix before the "{@code /}" character is the module name and
359     * the suffix after the "{@code /}" character is the package
360     * name. The package suffix may be empty; however, if a module
361     * name is present, it must be nonempty. If {@code moduleAndPkg}
362     * does not contain a "{@code /}" character, the entire argument
363     * is interpreted as a package name.
364     *
365     * <p>If the given location is neither a {@linkplain
366     * JavaFileManager.Location#isModuleOrientedLocation()
367     * module oriented location}, nor an {@linkplain
368     * JavaFileManager.Location#isOutputLocation()
369     * output location containing multiple modules}, and the explicit
370     * module prefix is given, {@link FilerException} is thrown.
371     *
372     * <p>If the given location is either a module oriented location,
373     * or an output location containing multiple modules, and no explicit
374     * modules prefix is given, a suitable module is
375     * inferred. If a suitable module cannot be inferred {@link
376     * FilerException} is thrown. An implementation may use information
377     * about the configuration of the annotation processing tool
378     * as part of the inference.
379     *
380     * @implNote In the reference implementation, if the annotation
381     * processing tool is processing a single module <i>M</i>,
382     * then <i>M</i> is used as the module for files read without
383     * an explicit module prefix. If the tool is processing multiple
384     * modules, and {@link
385     * Elements#getPackageElement(java.lang.CharSequence)
386     * Elements.getPackageElement(package-of(name))}
387     * returns a package, the module that owns the returned package is used
388     * as the source module. A separate option may be used to provide the target
389     * module if it cannot be determined using the above rules.
390     *
391     * @param location location of the file
392     * @param moduleAndPkg module and/or package relative to which the file
393     *          should be searched for, or the empty string if none
394     * @param relativeName final pathname components of the file
395     * @return an object to read the file
396     * @throws FilerException if the same pathname has already been
397     * opened for writing, if the source module cannot be determined,
398     * or if the target module is not writable, or if an explicit target
399     * module is specified and the location does not support it.
400     * @throws IOException if the file cannot be opened
401     * @throws IllegalArgumentException for an unsupported location
402     * @throws IllegalArgumentException if {@code moduleAndPkg} is ill-formed
403     * @throws IllegalArgumentException if {@code relativeName} is not relative
404     */
405    FileObject getResource(JavaFileManager.Location location,
406                           CharSequence moduleAndPkg,
407                           CharSequence relativeName) throws IOException;
408}
409