Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java
66645 views
1
/*
2
* Copyright (c) 2006, 2020, 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
26
package javax.tools;
27
28
import java.io.File;
29
import java.io.IOException;
30
import java.nio.file.Path;
31
import java.util.ArrayList;
32
import java.util.Arrays;
33
import java.util.Collection;
34
import java.util.Iterator;
35
import java.util.List;
36
37
/**
38
* File manager based on {@link File java.io.File} and {@link Path java.nio.file.Path}.
39
*
40
* A common way to obtain an instance of this class is using
41
* {@linkplain JavaCompiler#getStandardFileManager getStandardFileManager}, for example:
42
*
43
* <pre>
44
* JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
45
* {@code DiagnosticCollector<JavaFileObject>} diagnostics =
46
* new {@code DiagnosticCollector<JavaFileObject>()};
47
* StandardJavaFileManager fm = compiler.getStandardFileManager(diagnostics, null, null);
48
* </pre>
49
*
50
* This file manager creates file objects representing regular
51
* {@linkplain File files},
52
* {@linkplain java.util.zip.ZipEntry zip file entries}, or entries in
53
* similar file system based containers. Any file object returned
54
* from a file manager implementing this interface must observe the
55
* following behavior:
56
*
57
* <ul>
58
* <li>
59
* File names need not be canonical.
60
* </li>
61
* <li>
62
* For file objects representing regular files
63
* <ul>
64
* <li>
65
* the method <code>{@linkplain FileObject#delete()}</code>
66
* is equivalent to <code>{@linkplain File#delete()}</code>,
67
* </li>
68
* <li>
69
* the method <code>{@linkplain FileObject#getLastModified()}</code>
70
* is equivalent to <code>{@linkplain File#lastModified()}</code>,
71
* </li>
72
* <li>
73
* the methods <code>{@linkplain FileObject#getCharContent(boolean)}</code>,
74
* <code>{@linkplain FileObject#openInputStream()}</code>, and
75
* <code>{@linkplain FileObject#openReader(boolean)}</code>
76
* must succeed if the following would succeed (ignoring
77
* encoding issues):
78
* <blockquote>
79
* <pre>new {@linkplain java.io.FileInputStream#FileInputStream(File) FileInputStream}(new {@linkplain File#File(java.net.URI) File}({@linkplain FileObject fileObject}.{@linkplain FileObject#toUri() toUri}()))</pre>
80
* </blockquote>
81
* </li>
82
* <li>
83
* and the methods
84
* <code>{@linkplain FileObject#openOutputStream()}</code>, and
85
* <code>{@linkplain FileObject#openWriter()}</code> must
86
* succeed if the following would succeed (ignoring encoding
87
* issues):
88
* <blockquote>
89
* <pre>new {@linkplain java.io.FileOutputStream#FileOutputStream(File) FileOutputStream}(new {@linkplain File#File(java.net.URI) File}({@linkplain FileObject fileObject}.{@linkplain FileObject#toUri() toUri}()))</pre>
90
* </blockquote>
91
* </li>
92
* </ul>
93
* </li>
94
* <li>
95
* The {@linkplain java.net.URI URI} returned from
96
* <code>{@linkplain FileObject#toUri()}</code>
97
* <ul>
98
* <li>
99
* must be {@linkplain java.net.URI#isAbsolute() absolute} (have a schema), and
100
* </li>
101
* <li>
102
* must have a {@linkplain java.net.URI#normalize() normalized}
103
* {@linkplain java.net.URI#getPath() path component} which
104
* can be resolved without any process-specific context such
105
* as the current directory (file names must be absolute).
106
* </li>
107
* </ul>
108
* </li>
109
* </ul>
110
*
111
* According to these rules, the following URIs, for example, are
112
* allowed:
113
* <ul>
114
* <li>
115
* <code>file:///C:/Documents%20and%20Settings/UncleBob/BobsApp/Test.java</code>
116
* </li>
117
* <li>
118
* <code>jar:///C:/Documents%20and%20Settings/UncleBob/lib/vendorA.jar!/com/vendora/LibraryClass.class</code>
119
* </li>
120
* </ul>
121
* Whereas these are not (reason in parentheses):
122
* <ul>
123
* <li>
124
* <code>file:BobsApp/Test.java</code> (the file name is relative
125
* and depend on the current directory)
126
* </li>
127
* <li>
128
* <code>jar:lib/vendorA.jar!/com/vendora/LibraryClass.class</code>
129
* (the first half of the path depends on the current directory,
130
* whereas the component after ! is legal)
131
* </li>
132
* <li>
133
* <code>Test.java</code> (this URI depends on the current
134
* directory and does not have a schema)
135
* </li>
136
* <li>
137
* <code>jar:///C:/Documents%20and%20Settings/UncleBob/BobsApp/../lib/vendorA.jar!com/vendora/LibraryClass.class</code>
138
* (the path is not normalized)
139
* </li>
140
* </ul>
141
*
142
* <p>All implementations of this interface must support Path objects representing
143
* files in the {@linkplain java.nio.file.FileSystems#getDefault() default file system.}
144
* It is recommended that implementations should support Path objects from any filesystem.</p>
145
*
146
*
147
* @apiNote
148
* Some methods on this interface take a {@code Collection<? extends Path>}
149
* instead of {@code Iterable<? extends Path>}.
150
* This is to prevent the possibility of accidentally calling the method
151
* with a single {@code Path} as such an argument, because although
152
* {@code Path} implements {@code Iterable<Path>}, it would almost never be
153
* correct to call these methods with a single {@code Path} and have it be treated as
154
* an {@code Iterable} of its components.
155
*
156
*
157
* @author Peter von der Ah&eacute;
158
* @since 1.6
159
*/
160
public interface StandardJavaFileManager extends JavaFileManager {
161
162
/**
163
* Compares two file objects and return true if they represent the
164
* same canonical file, zip file entry, or entry in any file
165
* system based container.
166
*
167
* @param a a file object
168
* @param b a file object
169
* @return true if the given file objects represent the same
170
* canonical file, zip file entry or path; false otherwise
171
*
172
* @throws IllegalArgumentException if either of the arguments
173
* were created with another file manager implementation
174
*/
175
@Override
176
boolean isSameFile(FileObject a, FileObject b);
177
178
/**
179
* Returns file objects representing the given files.
180
*
181
* @param files a list of files
182
* @return a list of file objects
183
* @throws IllegalArgumentException if the list of files includes
184
* a directory
185
*/
186
Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
187
Iterable<? extends File> files);
188
189
/**
190
* Returns file objects representing the given paths.
191
*
192
* @implSpec
193
* The default implementation lazily converts each path to a file and calls
194
* {@link #getJavaFileObjectsFromFiles(Iterable) getJavaFileObjectsFromFiles}.
195
* {@code IllegalArgumentException} will be thrown
196
* if any of the paths cannot be converted to a file at the point the conversion happens.
197
*
198
* @param paths a list of paths
199
* @return a list of file objects
200
* @throws IllegalArgumentException if the list of paths includes
201
* a directory or if this file manager does not support any of the
202
* given paths
203
*
204
* @since 13
205
*/
206
default Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(
207
Collection<? extends Path> paths) {
208
return getJavaFileObjectsFromFiles(asFiles(paths));
209
}
210
211
/**
212
* Returns file objects representing the given paths.
213
*
214
* @implSpec
215
* The default implementation lazily converts each path to a file and calls
216
* {@link #getJavaFileObjectsFromPaths(Collection) getJavaFileObjectsFromPaths}.
217
* {@code IllegalArgumentException} will be thrown
218
* if any of the paths cannot be converted to a file at the point the conversion happens.
219
*
220
* @param paths a list of paths
221
* @return a list of file objects
222
* @throws IllegalArgumentException if the list of paths includes
223
* a directory or if this file manager does not support any of the
224
* given paths.
225
*
226
* @since 9
227
* @deprecated use {@link #getJavaFileObjectsFromPaths(Collection)} instead,
228
* to prevent the possibility of accidentally calling the method with a
229
* single {@code Path} as such an argument. Although {@code Path} implements
230
* {@code Iterable<Path>}, it would almost never be correct to pass a single
231
* {@code Path} and have it be treated as an {@code Iterable} of its
232
* components.
233
*/
234
@Deprecated(since = "13")
235
default Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(
236
Iterable<? extends Path> paths) {
237
return getJavaFileObjectsFromPaths(asCollection(paths));
238
}
239
240
/**
241
* Returns file objects representing the given files.
242
* Convenience method equivalent to:
243
*
244
* <pre>
245
* getJavaFileObjectsFromFiles({@linkplain java.util.Arrays#asList Arrays.asList}(files))
246
* </pre>
247
*
248
* @param files an array of files
249
* @return a list of file objects
250
* @throws IllegalArgumentException if the array of files includes
251
* a directory or if this file manager does not support any of the
252
* given paths
253
* @throws NullPointerException if the given array contains null
254
* elements
255
*/
256
Iterable<? extends JavaFileObject> getJavaFileObjects(File... files);
257
258
/**
259
* Returns file objects representing the given paths.
260
* Convenience method equivalent to:
261
*
262
* <pre>
263
* getJavaFileObjectsFromPaths({@linkplain java.util.Arrays#asList Arrays.asList}(paths))
264
* </pre>
265
*
266
* @implSpec
267
* The default implementation will only throw {@code NullPointerException}
268
* if {@linkplain #getJavaFileObjectsFromPaths(Collection)} throws it.
269
*
270
* @param paths an array of paths
271
* @return a list of file objects
272
* @throws IllegalArgumentException if the array of files includes
273
* a directory or if this file manager does not support any of the
274
* given paths
275
* @throws NullPointerException if the given array contains null
276
* elements
277
*
278
* @since 9
279
*/
280
default Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
281
return getJavaFileObjectsFromPaths(Arrays.asList(paths));
282
}
283
284
/**
285
* Returns file objects representing the given file names.
286
*
287
* @param names a list of file names
288
* @return a list of file objects
289
* @throws IllegalArgumentException if the list of file names
290
* includes a directory
291
*/
292
Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(
293
Iterable<String> names);
294
295
/**
296
* Returns file objects representing the given file names.
297
* Convenience method equivalent to:
298
*
299
* <pre>
300
* getJavaFileObjectsFromStrings({@linkplain java.util.Arrays#asList Arrays.asList}(names))
301
* </pre>
302
*
303
* @param names a list of file names
304
* @return a list of file objects
305
* @throws IllegalArgumentException if the array of file names
306
* includes a directory
307
* @throws NullPointerException if the given array contains null
308
* elements
309
*/
310
Iterable<? extends JavaFileObject> getJavaFileObjects(String... names);
311
312
/**
313
* Associates the given search path with the given location. Any
314
* previous value will be discarded.
315
*
316
* If the location is a module-oriented or output location, any module-specific
317
* associations set up by {@linkplain #setLocationForModule setLocationForModule}
318
* will be cancelled.
319
*
320
* @param location a location
321
* @param files a list of files, if {@code null} use the default
322
* search path for this location
323
* @see #getLocation
324
* @throws IllegalArgumentException if {@code location} is an output
325
* location and {@code files} does not contain exactly one element
326
* @throws IOException if {@code location} is an output location and
327
* does not represent an existing directory
328
*/
329
void setLocation(Location location, Iterable<? extends File> files)
330
throws IOException;
331
332
/**
333
* Associates the given search path with the given location.
334
* Any previous value will be discarded.
335
*
336
* If the location is a module-oriented or output location, any module-specific
337
* associations set up by {@linkplain #setLocationForModule setLocationForModule}
338
* will be cancelled.
339
*
340
* @implSpec
341
* The default implementation lazily converts each path to a file and calls
342
* {@link #setLocation setLocation}.
343
* {@code IllegalArgumentException} will be thrown if any of the paths cannot
344
* be converted to a file at the point the conversion happens.
345
*
346
* @param location a location
347
* @param paths a list of paths, if {@code null} use the default
348
* search path for this location
349
* @see #getLocation
350
* @throws IllegalArgumentException if {@code location} is an output
351
* location and {@code paths} does not contain exactly one element
352
* or if this file manager does not support any of the given paths
353
* @throws IOException if {@code location} is an output location and
354
* {@code paths} does not represent an existing directory
355
*
356
* @since 9
357
*/
358
default void setLocationFromPaths(Location location, Collection<? extends Path> paths)
359
throws IOException {
360
setLocation(location, asFiles(paths));
361
}
362
363
/**
364
* Associates the given search path with the given module and location,
365
* which must be a module-oriented or output location.
366
* Any previous value will be discarded.
367
* This overrides any default association derived from the search path
368
* associated with the location itself.
369
*
370
* All such module-specific associations will be cancelled if a
371
* new search path is associated with the location by calling
372
* {@linkplain #setLocation setLocation} or
373
* {@linkplain #setLocationFromPaths setLocationFromPaths}.
374
*
375
* @throws IllegalStateException if the location is not a module-oriented
376
* or output location.
377
* @throws UnsupportedOperationException if this operation is not supported by
378
* this file manager.
379
* @throws IOException if {@code location} is an output location and
380
* {@code paths} does not represent an existing directory
381
*
382
* @param location the location
383
* @param moduleName the name of the module
384
* @param paths the search path to associate with the location and module.
385
*
386
* @see #setLocation
387
* @see #setLocationFromPaths
388
*
389
* @since 9
390
*/
391
default void setLocationForModule(Location location, String moduleName,
392
Collection<? extends Path> paths) throws IOException {
393
throw new UnsupportedOperationException();
394
}
395
396
/**
397
* Returns the search path associated with the given location.
398
*
399
* @param location a location
400
* @return a list of files or {@code null} if this location has no
401
* associated search path
402
* @throws IllegalStateException if any element of the search path
403
* cannot be converted to a {@linkplain File}, or if the search path
404
* cannot be represented as a simple series of files.
405
*
406
* @see #setLocation
407
* @see Path#toFile
408
*/
409
Iterable<? extends File> getLocation(Location location);
410
411
/**
412
* Returns the search path associated with the given location.
413
*
414
* @implSpec
415
* The default implementation calls {@link #getLocation getLocation}
416
* and then returns an {@code Iterable} formed by calling {@code toPath()}
417
* on each {@code File} returned from {@code getLocation}.
418
*
419
* @param location a location
420
* @return a list of paths or {@code null} if this location has no
421
* associated search path
422
* @throws IllegalStateException if the search path cannot be represented
423
* as a simple series of paths.
424
*
425
* @see #setLocationFromPaths
426
* @since 9
427
*/
428
default Iterable<? extends Path> getLocationAsPaths(Location location) {
429
return asPaths(getLocation(location));
430
}
431
432
/**
433
* Returns the path, if any, underlying this file object (optional operation).
434
* File objects derived from a {@link java.nio.file.FileSystem FileSystem},
435
* including the default file system, typically have a corresponding underlying
436
* {@link java.nio.file.Path Path} object. In such cases, this method may be
437
* used to access that object.
438
*
439
* @implSpec
440
* The default implementation throws {@link UnsupportedOperationException}
441
* for all files.
442
*
443
* @param file a file object
444
* @return a path representing the same underlying file system artifact
445
* @throws IllegalArgumentException if the file object does not have an underlying path
446
* @throws UnsupportedOperationException if the operation is not supported by this file manager
447
*
448
* @since 9
449
*/
450
default Path asPath(FileObject file) {
451
throw new UnsupportedOperationException();
452
}
453
454
/**
455
* Factory to create {@code Path} objects from strings.
456
*
457
* @since 9
458
*/
459
interface PathFactory {
460
/**
461
* Converts a path string, or a sequence of strings that when joined form a path string, to a Path.
462
*
463
* @param first the path string or initial part of the path string
464
* @param more additional strings to be joined to form the path string
465
* @return the resulting {@code Path}
466
*/
467
Path getPath(String first, String... more);
468
}
469
470
/**
471
* Specify a factory that can be used to generate a path from a string, or series of strings.
472
*
473
* If this method is not called, a factory whose {@code getPath} method is
474
* equivalent to calling
475
* {@link java.nio.file.Paths#get(String, String...) java.nio.file.Paths.get(first, more)}
476
* will be used.
477
*
478
* @implSpec
479
* The default implementation of this method ignores the factory that is provided.
480
*
481
* @param f the factory
482
*
483
* @since 9
484
*/
485
default void setPathFactory(PathFactory f) { }
486
487
488
private static Iterable<Path> asPaths(final Iterable<? extends File> files) {
489
return () -> new Iterator<>() {
490
final Iterator<? extends File> iter = files.iterator();
491
492
@Override
493
public boolean hasNext() {
494
return iter.hasNext();
495
}
496
497
@Override
498
public Path next() {
499
return iter.next().toPath();
500
}
501
};
502
}
503
504
private static Iterable<File> asFiles(final Iterable<? extends Path> paths) {
505
return () -> new Iterator<>() {
506
final Iterator<? extends Path> iter = paths.iterator();
507
508
@Override
509
public boolean hasNext() {
510
return iter.hasNext();
511
}
512
513
@Override
514
public File next() {
515
Path p = iter.next();
516
try {
517
return p.toFile();
518
} catch (UnsupportedOperationException e) {
519
throw new IllegalArgumentException(p.toString(), e);
520
}
521
}
522
};
523
}
524
525
private static <T> Collection<T> asCollection(Iterable<T> iterable) {
526
if (iterable instanceof Collection) {
527
return (Collection<T>) iterable;
528
}
529
List<T> result = new ArrayList<>();
530
for (T item : iterable) result.add(item);
531
return result;
532
}
533
}
534
535