1 /*
2  * Copyright (c) 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 
26 package com.sun.tools.javac.main;
27 
28 import java.io.File;
29 import java.io.IOException;
30 import java.nio.file.Path;
31 import java.util.Collection;
32 import java.util.Iterator;
33 import java.util.ServiceLoader;
34 import java.util.Set;
35 
36 import javax.tools.FileObject;
37 import javax.tools.JavaFileManager;
38 import javax.tools.JavaFileManager.Location;
39 import javax.tools.JavaFileObject;
40 import javax.tools.JavaFileObject.Kind;
41 import javax.tools.StandardJavaFileManager;
42 
43 import com.sun.tools.javac.util.Context;
44 
45 /**
46  * A JavaFileManager that delegates to one of two delegate ClassLoaders.
47  */
48 public class DelegatingJavaFileManager implements JavaFileManager {
49 
installReleaseFileManager(Context context, JavaFileManager releaseFM, JavaFileManager originalFM)50     public static void installReleaseFileManager(Context context,
51                                                  JavaFileManager releaseFM,
52                                                  JavaFileManager originalFM) {
53         context.put(JavaFileManager.class, (JavaFileManager) null);
54         JavaFileManager nue = originalFM instanceof StandardJavaFileManager
55                 ? new DelegatingSJFM(releaseFM,
56                                                         (StandardJavaFileManager) originalFM)
57                 : new DelegatingJavaFileManager(releaseFM, originalFM);
58         context.put(JavaFileManager.class, nue);
59     }
60 
61     private final JavaFileManager releaseFM;
62     private final JavaFileManager baseFM;
63 
DelegatingJavaFileManager(JavaFileManager releaseFM, JavaFileManager baseFM)64     private DelegatingJavaFileManager(JavaFileManager releaseFM, JavaFileManager baseFM) {
65         this.releaseFM = releaseFM;
66         this.baseFM = baseFM;
67     }
68 
delegate(Location location)69     private JavaFileManager delegate(Location location) {
70         if (releaseFM.hasLocation(location)) {
71             return releaseFM;
72         }
73         return baseFM;
74     }
75 
76     @Override
getClassLoader(Location location)77     public ClassLoader getClassLoader(Location location) {
78         return delegate(location).getClassLoader(location);
79     }
80 
81     @Override
list(Location location, String packageName, Set<Kind> kinds, boolean recurse)82     public Iterable<JavaFileObject> list(Location location, String packageName,
83                                          Set<Kind> kinds, boolean recurse) throws IOException {
84         return delegate(location).list(location, packageName, kinds, recurse);
85     }
86 
87     @Override
inferBinaryName(Location location, JavaFileObject file)88     public String inferBinaryName(Location location, JavaFileObject file) {
89         return delegate(location).inferBinaryName(location, file);
90     }
91 
92     @Override
isSameFile(FileObject a, FileObject b)93     public boolean isSameFile(FileObject a, FileObject b) {
94         return baseFM.isSameFile(a, b);
95     }
96 
97     @Override
handleOption(String current, Iterator<String> remaining)98     public boolean handleOption(String current, Iterator<String> remaining) {
99         return baseFM.handleOption(current, remaining);
100     }
101 
102     @Override
hasLocation(Location location)103     public boolean hasLocation(Location location) {
104         return releaseFM.hasLocation(location) || baseFM.hasLocation(location);
105     }
106 
107     @Override
getJavaFileForInput(Location location, String className, Kind kind)108     public JavaFileObject getJavaFileForInput(Location location, String className,
109                                               Kind kind) throws IOException {
110         return delegate(location).getJavaFileForInput(location, className, kind);
111     }
112 
113     @Override
getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling)114     public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
115                                                FileObject sibling) throws IOException {
116         return delegate(location).getJavaFileForOutput(location, className, kind, sibling);
117     }
118 
119     @Override
getFileForInput(Location location, String packageName, String relativeName)120     public FileObject getFileForInput(Location location, String packageName,
121                                       String relativeName) throws IOException {
122         return delegate(location).getFileForInput(location, packageName, relativeName);
123     }
124 
125     @Override
getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling)126     public FileObject getFileForOutput(Location location, String packageName, String relativeName,
127                                        FileObject sibling) throws IOException {
128         return delegate(location).getFileForOutput(location, packageName, relativeName, sibling);
129     }
130 
131     @Override
flush()132     public void flush() throws IOException {
133         releaseFM.flush();
134         baseFM.flush();
135     }
136 
137     @Override
close()138     public void close() throws IOException {
139         releaseFM.close();
140         baseFM.close();
141     }
142 
143     @Override
getLocationForModule(Location location, String moduleName)144     public Location getLocationForModule(Location location,
145                                          String moduleName) throws IOException {
146         return delegate(location).getLocationForModule(location, moduleName);
147     }
148 
149     @Override
getLocationForModule(Location location, JavaFileObject fo)150     public Location getLocationForModule(Location location,
151                                          JavaFileObject fo) throws IOException {
152         return delegate(location).getLocationForModule(location, fo);
153     }
154 
155     @Override
getServiceLoader(Location location, Class<S> service)156     public <S> ServiceLoader<S> getServiceLoader(Location location,
157                                                  Class<S> service) throws IOException {
158         return delegate(location).getServiceLoader(location, service);
159     }
160 
161     @Override
inferModuleName(Location location)162     public String inferModuleName(Location location) throws IOException {
163         return delegate(location).inferModuleName(location);
164     }
165 
166     @Override
listLocationsForModules(Location location)167     public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
168         return delegate(location).listLocationsForModules(location);
169     }
170 
171     @Override
contains(Location location, FileObject fo)172     public boolean contains(Location location, FileObject fo) throws IOException {
173         return delegate(location).contains(location, fo);
174     }
175 
176     @Override
isSupportedOption(String option)177     public int isSupportedOption(String option) {
178         return baseFM.isSupportedOption(option);
179     }
180 
getBaseFileManager()181     public JavaFileManager getBaseFileManager() {
182         return baseFM;
183     }
184 
185     private static final class DelegatingSJFM extends DelegatingJavaFileManager
186                                               implements StandardJavaFileManager {
187 
188         private final StandardJavaFileManager baseSJFM;
189 
DelegatingSJFM(JavaFileManager releaseFM, StandardJavaFileManager baseSJFM)190         private DelegatingSJFM(JavaFileManager releaseFM,
191                                                   StandardJavaFileManager baseSJFM) {
192             super(releaseFM, baseSJFM);
193             this.baseSJFM = baseSJFM;
194         }
195 
196         @Override
isSameFile(FileObject a, FileObject b)197         public boolean isSameFile(FileObject a, FileObject b) {
198             return baseSJFM.isSameFile(a, b);
199         }
200 
201         @Override
getJavaFileObjectsFromFiles(Iterable<? extends File> files)202         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles
203                                                   (Iterable<? extends File> files) {
204             return baseSJFM.getJavaFileObjectsFromFiles(files);
205         }
206 
207         @Override
getJavaFileObjectsFromPaths(Collection<? extends Path> paths)208         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths
209                                                   (Collection<? extends Path> paths) {
210             return baseSJFM.getJavaFileObjectsFromPaths(paths);
211         }
212 
213         @Deprecated(since = "13")
214         @Override
getJavaFileObjectsFromPaths(Iterable<? extends Path> paths)215         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths
216                                                   (Iterable<? extends Path> paths) {
217             return baseSJFM.getJavaFileObjectsFromPaths(paths);
218         }
219 
220         @Override
getJavaFileObjects(File... files)221         public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
222             return baseSJFM.getJavaFileObjects(files);
223         }
224 
225         @Override
getJavaFileObjects(Path... paths)226         public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
227             return baseSJFM.getJavaFileObjects(paths);
228         }
229 
230         @Override
getJavaFileObjectsFromStrings(Iterable<String> names)231         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings
232                                                   (Iterable<String> names) {
233             return baseSJFM.getJavaFileObjectsFromStrings(names);
234         }
235 
236         @Override
getJavaFileObjects(String... names)237         public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
238             return baseSJFM.getJavaFileObjects(names);
239         }
240 
241         @Override
setLocation(Location location, Iterable<? extends File> files)242         public void setLocation(Location location,
243                                 Iterable<? extends File> files) throws IOException {
244             baseSJFM.setLocation(location, files);
245         }
246 
247         @Override
setLocationFromPaths(Location location, Collection<? extends Path> paths)248         public void setLocationFromPaths(Location location,
249                                          Collection<? extends Path> paths) throws IOException {
250             baseSJFM.setLocationFromPaths(location, paths);
251         }
252 
253         @Override
setLocationForModule(Location location, String moduleName, Collection<? extends Path> paths)254         public void setLocationForModule(Location location, String moduleName,
255                                          Collection<? extends Path> paths) throws IOException {
256             baseSJFM.setLocationForModule(location, moduleName, paths);
257         }
258 
259         @Override
getLocation(Location location)260         public Iterable<? extends File> getLocation(Location location) {
261             return baseSJFM.getLocation(location);
262         }
263 
264         @Override
getLocationAsPaths(Location location)265         public Iterable<? extends Path> getLocationAsPaths(Location location) {
266             return baseSJFM.getLocationAsPaths(location);
267         }
268 
269         @Override
asPath(FileObject file)270         public Path asPath(FileObject file) {
271             return baseSJFM.asPath(file);
272         }
273 
274         @Override
setPathFactory(PathFactory f)275         public void setPathFactory(PathFactory f) {
276             baseSJFM.setPathFactory(f);
277         }
278 
279     }
280 }
281