20
20
import java .util .ArrayList ;
21
21
import java .util .Arrays ;
22
22
import java .util .Collection ;
23
+ import java .util .List ;
23
24
import java .util .Objects ;
24
25
import java .util .Optional ;
25
26
import java .util .stream .Stream ;
33
34
import org .eclipse .jdt .core .IClasspathEntry ;
34
35
import org .eclipse .jdt .core .IJavaProject ;
35
36
import org .eclipse .jdt .core .JavaCore ;
37
+ import org .eclipse .osgi .service .resolver .BundleDescription ;
36
38
import org .eclipse .pde .core .build .IBuild ;
37
39
import org .eclipse .pde .core .build .IBuildModel ;
38
40
import org .eclipse .pde .core .plugin .IFragment ;
50
52
import org .eclipse .pde .internal .core .plugin .Fragment ;
51
53
import org .eclipse .pde .internal .core .plugin .Plugin ;
52
54
import org .eclipse .pde .internal .core .plugin .PluginBase ;
55
+ import org .osgi .framework .Bundle ;
56
+ import org .osgi .framework .namespace .PackageNamespace ;
57
+ import org .osgi .framework .wiring .BundleWire ;
58
+ import org .osgi .framework .wiring .BundleWiring ;
53
59
import org .osgi .resource .Resource ;
54
60
55
61
public class ClasspathUtilCore {
@@ -87,34 +93,92 @@ private static Collection<ClasspathLibrary> collectLibraryEntries(IPluginModelBa
87
93
}
88
94
89
95
public static Stream <IClasspathEntry > classpathEntriesForBundle (String id ) {
96
+ return classpathEntriesForBundle (id , false , new IClasspathAttribute [0 ]);
97
+ }
98
+
99
+ public static Stream <IClasspathEntry > classpathEntriesForBundle (String id , boolean includeRequired ,
100
+ IClasspathAttribute [] extra ) {
90
101
// first look if we have something in the workspace...
91
102
IPluginModelBase model = PluginRegistry .findModel (id );
92
103
if (model != null && model .isEnabled ()) {
93
- IResource resource = model .getUnderlyingResource ();
94
- if (resource != null && PluginProject .isJavaProject (resource .getProject ())) {
95
- IJavaProject javaProject = JavaCore .create (resource .getProject ());
96
- return Stream .of (JavaCore .newProjectEntry (javaProject .getPath ()));
97
- }
98
- String location = model .getInstallLocation ();
99
- if (location == null ) {
100
- return Stream .empty ();
104
+ Stream <IClasspathEntry > modelBundleClasspath = classpathEntriesForModelBundle (model , extra );
105
+ if (includeRequired ) {
106
+ return Stream .concat (modelBundleClasspath ,
107
+ getRequiredByDescription (model .getBundleDescription (), extra ));
101
108
}
102
- boolean isJarShape = new File (location ).isFile ();
103
- IPluginLibrary [] libraries = model .getPluginBase ().getLibraries ();
104
- if (isJarShape || libraries .length == 0 ) {
105
- return Stream .of (getEntryForPath (IPath .fromOSString (location )));
106
- }
107
- return Arrays .stream (libraries ).filter (library -> !IPluginLibrary .RESOURCE .equals (library .getType ()))
108
- .map (library -> {
109
- String name = library .getName ();
110
- String expandedName = ClasspathUtilCore .expandLibraryName (name );
111
- return ClasspathUtilCore .getPath (model , expandedName , isJarShape );
112
- }).filter (Objects ::nonNull ).map (ClasspathUtilCore ::getEntryForPath );
109
+ return modelBundleClasspath ;
113
110
}
114
111
// if not found in the models, try to use one from the running eclipse
115
- return Optional .ofNullable (Platform .getBundle (id )).map (bundle -> bundle .adapt (File .class )).filter (File ::exists )
112
+ Bundle runtimeBundle = Platform .getBundle (id );
113
+ if (runtimeBundle == null ) {
114
+ return Stream .empty ();
115
+ }
116
+ Stream <IClasspathEntry > bundleClasspath = classpathEntriesForRuntimeBundle (runtimeBundle , extra ).stream ();
117
+ if (includeRequired ) {
118
+ return Stream .concat (bundleClasspath , getRequiredByWire (runtimeBundle , extra ));
119
+ }
120
+ return bundleClasspath ;
121
+ }
122
+
123
+ private static Stream <IClasspathEntry > getRequiredByDescription (BundleDescription description ,
124
+ IClasspathAttribute [] extra ) {
125
+ BundleWiring wiring = description .getWiring ();
126
+ if (wiring == null ) {
127
+ return Stream .empty ();
128
+ }
129
+
130
+ List <BundleWire > wires = wiring .getRequiredWires (PackageNamespace .PACKAGE_NAMESPACE );
131
+ return wires .stream ().map (wire -> {
132
+ return wire .getProvider ();
133
+ }).distinct ().flatMap (provider -> {
134
+ IPluginModelBase model = PluginRegistry .findModel (provider );
135
+ if (model != null && model .isEnabled ()) {
136
+ return classpathEntriesForModelBundle (model , extra );
137
+ }
138
+ return Stream .empty ();
139
+ });
140
+ }
141
+
142
+ protected static Stream <IClasspathEntry > classpathEntriesForModelBundle (IPluginModelBase model ,
143
+ IClasspathAttribute [] extra ) {
144
+ IResource resource = model .getUnderlyingResource ();
145
+ if (resource != null && PluginProject .isJavaProject (resource .getProject ())) {
146
+ IJavaProject javaProject = JavaCore .create (resource .getProject ());
147
+ return Stream .of (JavaCore .newProjectEntry (javaProject .getPath ()));
148
+ }
149
+ String location = model .getInstallLocation ();
150
+ if (location == null ) {
151
+ return Stream .empty ();
152
+ }
153
+ boolean isJarShape = new File (location ).isFile ();
154
+ IPluginLibrary [] libraries = model .getPluginBase ().getLibraries ();
155
+ if (isJarShape || libraries .length == 0 ) {
156
+ return Stream .of (getEntryForPath (IPath .fromOSString (location ), extra ));
157
+ }
158
+ return Arrays .stream (libraries ).filter (library -> !IPluginLibrary .RESOURCE .equals (library .getType ()))
159
+ .map (library -> {
160
+ String name = library .getName ();
161
+ String expandedName = ClasspathUtilCore .expandLibraryName (name );
162
+ return ClasspathUtilCore .getPath (model , expandedName , isJarShape );
163
+ }).filter (Objects ::nonNull ).map (entry -> getEntryForPath (entry , extra ));
164
+ }
165
+
166
+ public static Stream <IClasspathEntry > getRequiredByWire (Bundle bundle , IClasspathAttribute [] extra ) {
167
+ BundleWiring wiring = bundle .adapt (BundleWiring .class );
168
+ if (wiring == null ) {
169
+ return Stream .empty ();
170
+ }
171
+ List <BundleWire > wires = wiring .getRequiredWires (PackageNamespace .PACKAGE_NAMESPACE );
172
+ return wires .stream ().map (wire -> wire .getProviderWiring ().getBundle ()).distinct ()
173
+ .filter (b -> b .getBundleId () != 0 )
174
+ .flatMap (b -> classpathEntriesForRuntimeBundle (b , extra ).stream ());
175
+ }
176
+
177
+ private static Optional <IClasspathEntry > classpathEntriesForRuntimeBundle (Bundle bundle ,
178
+ IClasspathAttribute [] extra ) {
179
+ return Optional .ofNullable (bundle .adapt (File .class )).filter (File ::exists )
116
180
.map (File ::toPath ).map (Path ::normalize ).map (path -> IPath .fromOSString (path .toString ()))
117
- .map (ClasspathUtilCore :: getEntryForPath ). stream ( );
181
+ .map (entry -> getEntryForPath ( entry , extra ) );
118
182
}
119
183
120
184
public static boolean isEntryForModel (IClasspathEntry entry , IPluginModelBase projectModel ) {
@@ -127,8 +191,8 @@ public static boolean isEntryForModel(IClasspathEntry entry, IPluginModelBase pr
127
191
return false ;
128
192
}
129
193
130
- private static IClasspathEntry getEntryForPath (IPath path ) {
131
- return JavaCore .newLibraryEntry (path , path , IPath .ROOT , new IAccessRule [0 ], new IClasspathAttribute [ 0 ] , false );
194
+ private static IClasspathEntry getEntryForPath (IPath path , IClasspathAttribute [] extra ) {
195
+ return JavaCore .newLibraryEntry (path , path , IPath .ROOT , new IAccessRule [0 ], extra , false );
132
196
}
133
197
134
198
private static void addLibraryEntry (IPluginLibrary library , Collection <ClasspathLibrary > entries ) {
0 commit comments