Lines 46-61
Link Here
|
46 |
|
46 |
|
47 |
import java.io.File; |
47 |
import java.io.File; |
48 |
import java.io.IOException; |
48 |
import java.io.IOException; |
|
|
49 |
import java.net.MalformedURLException; |
49 |
import java.net.URI; |
50 |
import java.net.URI; |
50 |
import java.net.URL; |
51 |
import java.net.URL; |
|
|
52 |
import java.util.Arrays; |
53 |
import java.util.Collection; |
54 |
import java.util.Collections; |
55 |
import java.util.logging.Level; |
56 |
import java.util.logging.Logger; |
57 |
import java.util.stream.Collectors; |
51 |
import org.netbeans.api.java.classpath.ClassPath; |
58 |
import org.netbeans.api.java.classpath.ClassPath; |
|
|
59 |
import org.netbeans.api.java.project.JavaProjectConstants; |
52 |
import org.netbeans.api.project.FileOwnerQuery; |
60 |
import org.netbeans.api.project.FileOwnerQuery; |
53 |
import org.netbeans.api.project.Project; |
61 |
import org.netbeans.api.project.Project; |
54 |
import org.netbeans.api.project.SourceGroup; |
62 |
import org.netbeans.api.project.SourceGroup; |
55 |
import org.netbeans.api.project.ant.AntArtifact; |
63 |
import org.netbeans.api.project.ant.AntArtifact; |
|
|
64 |
import org.netbeans.api.project.ant.AntArtifactQuery; |
56 |
import org.netbeans.api.project.libraries.Library; |
65 |
import org.netbeans.api.project.libraries.Library; |
57 |
import org.netbeans.modules.java.project.classpath.ProjectClassPathModifierAccessor; |
66 |
import org.netbeans.modules.java.project.classpath.ProjectClassPathModifierAccessor; |
58 |
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation; |
67 |
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation; |
|
|
68 |
import org.netbeans.spi.java.project.classpath.ProjectModulesModifier; |
59 |
import org.netbeans.spi.java.project.support.LookupMergerSupport; |
69 |
import org.netbeans.spi.java.project.support.LookupMergerSupport; |
60 |
import org.netbeans.spi.project.libraries.support.LibrariesSupport; |
70 |
import org.netbeans.spi.project.libraries.support.LibrariesSupport; |
61 |
import org.netbeans.spi.project.support.ant.PropertyUtils; |
71 |
import org.netbeans.spi.project.support.ant.PropertyUtils; |
Lines 63-68
Link Here
|
63 |
import org.openide.filesystems.FileUtil; |
73 |
import org.openide.filesystems.FileUtil; |
64 |
import org.openide.filesystems.URLMapper; |
74 |
import org.openide.filesystems.URLMapper; |
65 |
import org.openide.util.BaseUtilities; |
75 |
import org.openide.util.BaseUtilities; |
|
|
76 |
import org.openide.util.Lookup; |
66 |
import org.openide.util.Parameters; |
77 |
import org.openide.util.Parameters; |
67 |
|
78 |
|
68 |
/** |
79 |
/** |
Lines 73-78
Link Here
|
73 |
* @since org.netbeans.modules.java.project/1 1.10 |
84 |
* @since org.netbeans.modules.java.project/1 1.10 |
74 |
*/ |
85 |
*/ |
75 |
public class ProjectClassPathModifier { |
86 |
public class ProjectClassPathModifier { |
|
|
87 |
private static final Logger LOG = Logger.getLogger(ProjectClassPathModifier.class.getName()); |
76 |
|
88 |
|
77 |
private ProjectClassPathModifier() {} |
89 |
private ProjectClassPathModifier() {} |
78 |
|
90 |
|
Lines 94-100
Link Here
|
94 |
if (extensible.pcmi != null) { |
106 |
if (extensible.pcmi != null) { |
95 |
assert extensible.sg != null; |
107 |
assert extensible.sg != null; |
96 |
assert extensible.classPathType != null; |
108 |
assert extensible.classPathType != null; |
97 |
return ProjectClassPathModifierAccessor.INSTANCE.addLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType); |
109 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.addLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
110 |
boolean r2 = !extensible.classPathType.equals(classPathType) && |
111 |
addRootsToModinfo(classPathType, projectArtifact, toURLs(libraries)); |
112 |
return r1 || r2; |
98 |
} else { |
113 |
} else { |
99 |
boolean result = false; |
114 |
boolean result = false; |
100 |
for (Library library : libraries) { |
115 |
for (Library library : libraries) { |
Lines 121-127
Link Here
|
121 |
if (extensible.pcmi != null) { |
136 |
if (extensible.pcmi != null) { |
122 |
assert extensible.sg != null; |
137 |
assert extensible.sg != null; |
123 |
assert extensible.classPathType != null; |
138 |
assert extensible.classPathType != null; |
124 |
return ProjectClassPathModifierAccessor.INSTANCE.removeLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType); |
139 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.removeLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
140 |
boolean r2 = !extensible.classPathType.equals(classPathType) && |
141 |
removeRootsFromModinfo(classPathType, projectArtifact, toURLs(libraries)); |
142 |
return r1 || r2; |
125 |
} else { |
143 |
} else { |
126 |
throw new UnsupportedOperationException("Cannot remove libraries using " + extensible); // NOI18N |
144 |
throw new UnsupportedOperationException("Cannot remove libraries using " + extensible); // NOI18N |
127 |
} |
145 |
} |
Lines 146-152
Link Here
|
146 |
if (extensible.pcmi != null) { |
164 |
if (extensible.pcmi != null) { |
147 |
assert extensible.sg != null; |
165 |
assert extensible.sg != null; |
148 |
assert extensible.classPathType != null; |
166 |
assert extensible.classPathType != null; |
149 |
return ProjectClassPathModifierAccessor.INSTANCE.addRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType); |
167 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.addRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
168 |
boolean r2 = !extensible.classPathType.equals(classPathType) && addRootsToModinfo(classPathType, projectArtifact, Arrays.asList(classPathRoots)); |
169 |
return r1 || r2; |
150 |
} else { |
170 |
} else { |
151 |
boolean result = false; |
171 |
boolean result = false; |
152 |
for (URL urlToAdd : classPathRoots) { |
172 |
for (URL urlToAdd : classPathRoots) { |
Lines 183-189
Link Here
|
183 |
if (extensible.pcmi != null) { |
203 |
if (extensible.pcmi != null) { |
184 |
assert extensible.sg != null; |
204 |
assert extensible.sg != null; |
185 |
assert extensible.classPathType != null; |
205 |
assert extensible.classPathType != null; |
186 |
return ProjectClassPathModifierAccessor.INSTANCE.addRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType); |
206 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.addRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
207 |
boolean r2 = !extensible.classPathType.equals(classPathType) && |
208 |
addRootsToModinfo(classPathType, projectArtifact, toURLs(Arrays.asList(classPathRoots))); |
209 |
return r1 || r2; |
187 |
} else { |
210 |
} else { |
188 |
boolean result = false; |
211 |
boolean result = false; |
189 |
final Project project = FileOwnerQuery.getOwner(projectArtifact); |
212 |
final Project project = FileOwnerQuery.getOwner(projectArtifact); |
Lines 226-232
Link Here
|
226 |
if (extensible.pcmi != null) { |
249 |
if (extensible.pcmi != null) { |
227 |
assert extensible.sg != null; |
250 |
assert extensible.sg != null; |
228 |
assert extensible.classPathType != null; |
251 |
assert extensible.classPathType != null; |
229 |
return ProjectClassPathModifierAccessor.INSTANCE.removeRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType); |
252 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.removeRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
253 |
boolean r2 = !extensible.classPathType.equals(classPathType) && |
254 |
removeRootsFromModinfo(classPathType, projectArtifact, Arrays.asList(classPathRoots)); |
255 |
return r1 || r2; |
230 |
} else { |
256 |
} else { |
231 |
throw new UnsupportedOperationException("Cannot remove roots from " + extensible); // NOI18N |
257 |
throw new UnsupportedOperationException("Cannot remove roots from " + extensible); // NOI18N |
232 |
} |
258 |
} |
Lines 279-285
Link Here
|
279 |
if (extensible.pcmi != null) { |
305 |
if (extensible.pcmi != null) { |
280 |
assert extensible.sg != null; |
306 |
assert extensible.sg != null; |
281 |
assert extensible.classPathType != null; |
307 |
assert extensible.classPathType != null; |
282 |
return ProjectClassPathModifierAccessor.INSTANCE.addAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType); |
308 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.addAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
309 |
boolean r2 = !extensible.classPathType.equals(classPathType) && |
310 |
addRootsToModinfo(classPathType, projectArtifact, toURLs(Arrays.asList(artifactElements))); |
311 |
return r1 || r2; |
283 |
} else { |
312 |
} else { |
284 |
boolean result = false; |
313 |
boolean result = false; |
285 |
for (int i=0; i< artifacts.length; i++) { |
314 |
for (int i=0; i< artifacts.length; i++) { |
Lines 312-318
Link Here
|
312 |
if (extensible.pcmi != null) { |
341 |
if (extensible.pcmi != null) { |
313 |
assert extensible.sg != null; |
342 |
assert extensible.sg != null; |
314 |
assert extensible.classPathType != null; |
343 |
assert extensible.classPathType != null; |
315 |
return ProjectClassPathModifierAccessor.INSTANCE.addProjects (projects, extensible.pcmi, extensible.sg, extensible.classPathType); |
344 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.addProjects (projects, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
345 |
boolean r2 = !extensible.classPathType.equals(classPathType) && |
346 |
addRootsToModinfo(classPathType, projectArtifact, toURLs(projects)); |
347 |
return r1 || r2; |
316 |
} else { |
348 |
} else { |
317 |
throw new UnsupportedOperationException("Cannot add project as dependency. Missing ProjectClassPathModifierImplementation service in project type."); |
349 |
throw new UnsupportedOperationException("Cannot add project as dependency. Missing ProjectClassPathModifierImplementation service in project type."); |
318 |
} |
350 |
} |
Lines 339-345
Link Here
|
339 |
if (extensible.pcmi != null) { |
371 |
if (extensible.pcmi != null) { |
340 |
assert extensible.sg != null; |
372 |
assert extensible.sg != null; |
341 |
assert extensible.classPathType != null; |
373 |
assert extensible.classPathType != null; |
342 |
return ProjectClassPathModifierAccessor.INSTANCE.removeAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType); |
374 |
boolean r1 = ProjectClassPathModifierAccessor.INSTANCE.removeAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType); |
|
|
375 |
boolean r2 = !extensible.classPathType.equals(classPathType) && |
376 |
removeRootsFromModinfo(classPathType, projectArtifact, toURLs(Arrays.asList(artifactElements))); |
377 |
return r1 || r2; |
343 |
} else { |
378 |
} else { |
344 |
throw new UnsupportedOperationException("Cannot remove artifacts from " + extensible); // NOI18N |
379 |
throw new UnsupportedOperationException("Cannot remove artifacts from " + extensible); // NOI18N |
345 |
} |
380 |
} |
Lines 368-373
Link Here
|
368 |
throw new UnsupportedOperationException("No project found to correspond to " + FileUtil.getFileDisplayName(projectArtifact)); // NOI18N |
403 |
throw new UnsupportedOperationException("No project found to correspond to " + FileUtil.getFileDisplayName(projectArtifact)); // NOI18N |
369 |
} |
404 |
} |
370 |
final ProjectClassPathModifierImplementation pm = project.getLookup().lookup(ProjectClassPathModifierImplementation.class); |
405 |
final ProjectClassPathModifierImplementation pm = project.getLookup().lookup(ProjectClassPathModifierImplementation.class); |
|
|
406 |
final ProjectModulesModifier pmm = Lookup.getDefault().lookup(ProjectModulesModifier.class); |
407 |
|
408 |
String substModulePath = pmm == null ? null : pmm.provideModularClasspath(projectArtifact, classPathType); |
409 |
final String _classPathType = substModulePath == null ? classPathType : substModulePath; |
371 |
if (pm != null) { |
410 |
if (pm != null) { |
372 |
final SourceGroup[] sgs = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleSourceGroups(pm); |
411 |
final SourceGroup[] sgs = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleSourceGroups(pm); |
373 |
assert sgs != null : "Class: " + pm.getClass() + " returned null as source groups."; //NOI18N |
412 |
assert sgs != null : "Class: " + pm.getClass() + " returned null as source groups."; //NOI18N |
Lines 375-400
Link Here
|
375 |
if ((projectArtifact == sg.getRootFolder() || FileUtil.isParentOf(sg.getRootFolder(),projectArtifact)) && sg.contains(projectArtifact)) { |
414 |
if ((projectArtifact == sg.getRootFolder() || FileUtil.isParentOf(sg.getRootFolder(),projectArtifact)) && sg.contains(projectArtifact)) { |
376 |
final String[] types = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleClassPathTypes(pm,sg); |
415 |
final String[] types = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleClassPathTypes(pm,sg); |
377 |
assert types != null : "Class: " + pm.getClass() + " returned null as classpath types."; //NOI18N |
416 |
assert types != null : "Class: " + pm.getClass() + " returned null as classpath types."; //NOI18N |
|
|
417 |
boolean originalFound = false; |
378 |
for (String type : types) { |
418 |
for (String type : types) { |
379 |
if (classPathType.equals(type)) { |
419 |
if (_classPathType.equals(type)) { |
380 |
String label = "ProjectClassPathModifierImplementation for " + classPathType + " on " + FileUtil.getFileDisplayName(sg.getRootFolder()); // NOI18N |
420 |
String label = "ProjectClassPathModifierImplementation for " + _classPathType + " on " + FileUtil.getFileDisplayName(sg.getRootFolder()); // NOI18N |
381 |
return new Extensible(pm, sg, type,label); |
421 |
return new Extensible(pm, sg, type,label); |
|
|
422 |
} else if (classPathType.equals(type)) { |
423 |
originalFound = true; |
382 |
} |
424 |
} |
383 |
} |
425 |
} |
|
|
426 |
if (originalFound) { |
427 |
String label = "ProjectClassPathModifierImplementation for " + classPathType + " on " + FileUtil.getFileDisplayName(sg.getRootFolder()); // NOI18N |
428 |
return new Extensible(pm, sg, classPathType,label); |
429 |
} |
384 |
} |
430 |
} |
385 |
} |
431 |
} |
386 |
throw new UnsupportedOperationException("Project in " + FileUtil.getFileDisplayName(project.getProjectDirectory()) + " of " + project.getClass() + |
432 |
throw new UnsupportedOperationException("Project in " + FileUtil.getFileDisplayName(project.getProjectDirectory()) + " of " + project.getClass() + |
387 |
" has a ProjectClassPathModifierImplementation but it will not handle " + classPathType + " for " + FileUtil.getFileDisplayName(projectArtifact) + |
433 |
" has a ProjectClassPathModifierImplementation but it will not handle " + _classPathType + " for " + FileUtil.getFileDisplayName(projectArtifact) + |
388 |
" extensible source groups: " + sourceGroupsToString(sgs)); // NOI18N |
434 |
" extensible source groups: " + sourceGroupsToString(sgs)); // NOI18N |
389 |
} else { |
435 |
} else { |
390 |
final org.netbeans.spi.java.project.classpath.ProjectClassPathExtender pe = |
436 |
final org.netbeans.spi.java.project.classpath.ProjectClassPathExtender pe = |
391 |
project.getLookup().lookup(org.netbeans.spi.java.project.classpath.ProjectClassPathExtender.class); |
437 |
project.getLookup().lookup(org.netbeans.spi.java.project.classpath.ProjectClassPathExtender.class); |
392 |
if (pe != null) { |
438 |
if (pe != null) { |
393 |
if (classPathType.equals(ClassPath.COMPILE)) { |
439 |
if (_classPathType.equals(ClassPath.COMPILE)) { |
394 |
return new Extensible(pe, "ProjectClassPathExtender for " + FileUtil.getFileDisplayName(project.getProjectDirectory())); // NOI18N |
440 |
return new Extensible(pe, "ProjectClassPathExtender for " + FileUtil.getFileDisplayName(project.getProjectDirectory())); // NOI18N |
395 |
} else { |
441 |
} else { |
396 |
throw new UnsupportedOperationException("Project in " + FileUtil.getFileDisplayName(project.getProjectDirectory()) + " of " + project.getClass() + |
442 |
throw new UnsupportedOperationException("Project in " + FileUtil.getFileDisplayName(project.getProjectDirectory()) + " of " + project.getClass() + |
397 |
" has a ProjectClassPathExtender in its lookup but no ProjectClassPathModifierImplementation to handle " + classPathType); // NOI18N |
443 |
" has a ProjectClassPathExtender in its lookup but no ProjectClassPathModifierImplementation to handle " + _classPathType); // NOI18N |
398 |
} |
444 |
} |
399 |
} else { |
445 |
} else { |
400 |
throw new UnsupportedOperationException("Project in " + FileUtil.getFileDisplayName(project.getProjectDirectory()) + " of " + project.getClass() + |
446 |
throw new UnsupportedOperationException("Project in " + FileUtil.getFileDisplayName(project.getProjectDirectory()) + " of " + project.getClass() + |
Lines 550-554
Link Here
|
550 |
} |
596 |
} |
551 |
}; |
597 |
}; |
552 |
} |
598 |
} |
553 |
|
599 |
|
|
|
600 |
private static Collection<URL> toURLs(Collection<URI> libs) { |
601 |
URL[] urls = new URL[libs.size()]; |
602 |
int index = 0; |
603 |
for (URI u : libs) { |
604 |
try { |
605 |
urls[index++] = u.toURL(); |
606 |
} catch (MalformedURLException ex) { |
607 |
return Collections.emptyList(); |
608 |
} |
609 |
} |
610 |
return Arrays.asList(urls); |
611 |
} |
612 |
|
613 |
private static Collection<URL> toURLs(Project[] prjs) { |
614 |
return |
615 |
toURLs( |
616 |
Arrays.asList(prjs).stream().flatMap( |
617 |
(prj) -> Arrays.asList( |
618 |
AntArtifactQuery.findArtifactsByType(prj, JavaProjectConstants.ARTIFACT_TYPE_JAR) |
619 |
).stream()). |
620 |
flatMap((a) -> Arrays.asList(a.getArtifactLocations()).stream()). |
621 |
collect(Collectors.toList()) |
622 |
); |
623 |
} |
624 |
|
625 |
private static Collection<URL> toURLs(Library[] libraries) { |
626 |
return Arrays.stream(libraries).flatMap((l) -> l.getContent("classpath").stream()). |
627 |
collect(Collectors.toList()); |
628 |
} |
629 |
|
630 |
private static boolean removeRootsFromModinfo(String originalPathType, FileObject artifact, Collection<URL> libs) { |
631 |
ProjectModulesModifier pmm = Lookup.getDefault().lookup(ProjectModulesModifier.class); |
632 |
if (pmm == null) { |
633 |
return false; |
634 |
} else { |
635 |
try { |
636 |
return pmm.removeRequiredModules(originalPathType, artifact, libs); |
637 |
} catch (IOException ex) { |
638 |
LOG.log(Level.WARNING, "Could not remove module requires", ex); |
639 |
return false; |
640 |
} |
641 |
} |
642 |
} |
643 |
|
644 |
private static boolean addRootsToModinfo(String originalPathType, FileObject artifact, Collection<URL> libs) { |
645 |
ProjectModulesModifier pmm = Lookup.getDefault().lookup(ProjectModulesModifier.class); |
646 |
if (pmm == null) { |
647 |
return false; |
648 |
} else { |
649 |
try { |
650 |
return pmm.addRequiredModules(originalPathType, artifact, libs); |
651 |
} catch (IOException ex) { |
652 |
LOG.log(Level.WARNING, "Could not declare module requires", ex); |
653 |
return false; |
654 |
} |
655 |
} |
656 |
} |
554 |
} |
657 |
} |