1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.compiler;
20
21 import javax.tools.FileObject;
22 import javax.tools.ForwardingJavaFileManager;
23 import javax.tools.JavaFileManager;
24 import javax.tools.JavaFileObject;
25 import javax.tools.StandardJavaFileManager;
26 import javax.tools.StandardLocation;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.nio.file.Path;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.Map;
37 import java.util.Set;
38
39 import org.apache.maven.api.JavaPathType;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 final class WorkaroundForPatchModule extends ForwardingJavaFileManager<StandardJavaFileManager>
56 implements StandardJavaFileManager {
57
58
59
60 static final boolean ENABLED = true;
61
62
63
64
65
66
67 private final Set<JavaFileManager.Location> definedLocations;
68
69
70
71
72
73 private final Map<String, Collection<? extends Path>> patchesAsOption;
74
75
76
77
78
79 private boolean needsNewFileManager;
80
81
82
83
84 WorkaroundForPatchModule(final StandardJavaFileManager fileManager) {
85 super(fileManager);
86 definedLocations = new HashSet<>();
87 patchesAsOption = new HashMap<>();
88 }
89
90
91
92
93
94
95
96 StandardJavaFileManager getFileManagerIfUsable() {
97 return needsNewFileManager ? null : fileManager;
98 }
99
100
101
102
103
104
105
106 void copyTo(final StandardJavaFileManager target) throws IOException {
107 for (JavaFileManager.Location location : definedLocations) {
108 target.setLocation(location, fileManager.getLocation(location));
109 }
110 for (Map.Entry<String, Collection<? extends Path>> entry : patchesAsOption.entrySet()) {
111 Collection<? extends Path> paths = entry.getValue();
112 String moduleName = entry.getKey();
113 try {
114 target.setLocationForModule(StandardLocation.PATCH_MODULE_PATH, moduleName, paths);
115 } catch (UnsupportedOperationException e) {
116 specifyAsOption(target, JavaPathType.patchModule(moduleName), paths, e);
117 }
118 }
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132 private static void specifyAsOption(
133 StandardJavaFileManager fileManager,
134 JavaPathType.Modular type,
135 Collection<? extends Path> paths,
136 UnsupportedOperationException cause)
137 throws IOException {
138
139 String message;
140 Iterator<String> it = Arrays.asList(type.option(paths)).iterator();
141 if (!fileManager.handleOption(it.next(), it)) {
142 message = "Failed to set the %s option for module %s";
143 } else if (it.hasNext()) {
144 message = "Unexpected number of arguments after the %s option for module %s";
145 } else {
146 return;
147 }
148 JavaPathType rawType = type.rawType();
149 throw new IllegalArgumentException(
150 String.format(message, rawType.option().orElse(rawType.name()), type.moduleName()), cause);
151 }
152
153
154
155
156
157 @Override
158 public void setLocationForModule(
159 JavaFileManager.Location location, String moduleName, Collection<? extends Path> paths) throws IOException {
160
161 if (paths.isEmpty()) {
162 return;
163 }
164 final boolean isPatch = (location == StandardLocation.PATCH_MODULE_PATH);
165 if (isPatch && patchesAsOption.replace(moduleName, paths) != null) {
166
167
168
169
170 needsNewFileManager = true;
171 return;
172 }
173 try {
174 fileManager.setLocationForModule(location, moduleName, paths);
175 } catch (UnsupportedOperationException e) {
176 if (isPatch) {
177 specifyAsOption(fileManager, JavaPathType.patchModule(moduleName), paths, e);
178 patchesAsOption.put(moduleName, paths);
179 return;
180 }
181 throw e;
182 }
183 definedLocations.add(fileManager.getLocationForModule(location, moduleName));
184 }
185
186
187
188
189 @Override
190 public void setLocationFromPaths(JavaFileManager.Location location, Collection<? extends Path> paths)
191 throws IOException {
192 fileManager.setLocationFromPaths(location, paths);
193 definedLocations.add(location);
194 }
195
196 @Override
197 public void setLocation(Location location, Iterable<? extends File> files) throws IOException {
198 fileManager.setLocation(location, files);
199 definedLocations.add(location);
200 }
201
202 @Override
203 public Iterable<? extends File> getLocation(Location location) {
204 return fileManager.getLocation(location);
205 }
206
207 @Override
208 public Iterable<? extends Path> getLocationAsPaths(Location location) {
209 return fileManager.getLocationAsPaths(location);
210 }
211
212 @Override
213 public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
214 return fileManager.getJavaFileObjects(names);
215 }
216
217 @Override
218 public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
219 return fileManager.getJavaFileObjects(files);
220 }
221
222 @Override
223 public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
224 return fileManager.getJavaFileObjects(paths);
225 }
226
227 @Override
228 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
229 return fileManager.getJavaFileObjectsFromStrings(names);
230 }
231
232 @Override
233 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
234 return fileManager.getJavaFileObjectsFromFiles(files);
235 }
236
237 @Override
238 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Collection<? extends Path> paths) {
239 return fileManager.getJavaFileObjectsFromPaths(paths);
240 }
241
242 @Override
243 public Path asPath(FileObject file) {
244 return fileManager.asPath(file);
245 }
246 }