Skip to content

Commit 7bd7a7f

Browse files
chrisruegerlaeubi
authored andcommitted
Initial bnd->PDE migration + License headers
- This commit does not compile - it only serves the purpose of having all migrated files in one place + the license headers - later commits will put those files in different folders, do cleanup etc.
1 parent 7c4e17e commit 7bd7a7f

28 files changed

+3074
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2010, 2023 bndtools project and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Neil Bartlett <[email protected]> - initial API and implementation
13+
* PK Søreide <[email protected]> - ongoing enhancements
14+
* Ferry Huberts <[email protected]> - ongoing enhancements
15+
* Peter Kriens <[email protected]> - ongoing enhancements
16+
* BJ Hargrave <[email protected]> - ongoing enhancements
17+
* Sean Bright <[email protected]> - ongoing enhancements
18+
*******************************************************************************/
19+
20+
package bndtools.tasks;
21+
22+
import static java.util.Collections.emptyList;
23+
24+
import java.util.ArrayList;
25+
import java.util.Collections;
26+
import java.util.HashMap;
27+
import java.util.List;
28+
import java.util.Map;
29+
import java.util.Map.Entry;
30+
import java.util.Set;
31+
import java.util.function.Predicate;
32+
33+
import org.bndtools.api.ILogger;
34+
import org.bndtools.api.Logger;
35+
import org.eclipse.core.runtime.IProgressMonitor;
36+
import org.eclipse.core.runtime.IStatus;
37+
import org.eclipse.core.runtime.Status;
38+
import org.eclipse.core.runtime.jobs.Job;
39+
import org.osgi.resource.Capability;
40+
import org.osgi.resource.Namespace;
41+
42+
import aQute.bnd.build.model.EE;
43+
import aQute.bnd.osgi.resource.ResourceUtils;
44+
import aQute.lib.io.IO;
45+
import bndtools.model.resolution.RequirementWrapper;
46+
47+
public class AnalyseBundleResolutionJob extends Job {
48+
49+
private static final ILogger logger = Logger.getLogger(AnalyseBundleResolutionJob.class);
50+
51+
private final Set<? extends CapReqLoader> loaders;
52+
53+
private Map<String, List<RequirementWrapper>> requirements;
54+
private Map<String, List<Capability>> capabilities;
55+
private EE ee;
56+
57+
public AnalyseBundleResolutionJob(String name, Set<? extends CapReqLoader> loaders) {
58+
this(name, loaders, null);
59+
}
60+
61+
public AnalyseBundleResolutionJob(String name, Set<? extends CapReqLoader> loaders, EE ee) {
62+
super(name);
63+
this.loaders = loaders;
64+
this.ee = ee;
65+
}
66+
67+
private static <K, V> void mergeMaps(Map<K, List<V>> from, Map<K, List<V>> into) {
68+
for (Entry<K, List<V>> entry : from.entrySet()) {
69+
K key = entry.getKey();
70+
71+
List<V> list = into.get(key);
72+
if (list == null) {
73+
list = new ArrayList<>();
74+
into.put(key, list);
75+
}
76+
77+
list.addAll(entry.getValue());
78+
}
79+
}
80+
81+
@Override
82+
protected IStatus run(IProgressMonitor monitor) {
83+
try {
84+
85+
86+
// Load all the capabilities and requirements
87+
Map<String, List<Capability>> allCaps = new HashMap<>();
88+
Map<String, List<RequirementWrapper>> allReqs = new HashMap<>();
89+
for (CapReqLoader loader : loaders) {
90+
try {
91+
Map<String, List<Capability>> caps = loader.loadCapabilities();
92+
mergeMaps(caps, allCaps);
93+
94+
Map<String, List<RequirementWrapper>> reqs = loader.loadRequirements();
95+
mergeMaps(reqs, allReqs);
96+
} catch (Exception e) {
97+
logger.logError("Error in Bnd resolution analysis.", e);
98+
} finally {
99+
IO.close(loader);
100+
}
101+
}
102+
103+
// Check for resolved requirements
104+
for (String namespace : allReqs.keySet()) {
105+
List<RequirementWrapper> rws = allReqs.getOrDefault(namespace, emptyList());
106+
List<Capability> candidates = allCaps.getOrDefault(namespace, emptyList());
107+
108+
List<Capability> javaCandidates = ee == null ? emptyList()
109+
: ee.getResource()
110+
.getCapabilities(namespace);
111+
112+
outer: for (RequirementWrapper rw : rws) {
113+
String filterDirective = rw.requirement.getDirectives()
114+
.get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
115+
if (filterDirective == null) {
116+
continue;
117+
}
118+
Predicate<Capability> predicate = ResourceUtils.filterMatcher(rw.requirement);
119+
for (Capability cand : candidates) {
120+
if (predicate.test(cand)) {
121+
rw.resolved = true;
122+
continue outer;
123+
}
124+
}
125+
for (Capability cand : javaCandidates) {
126+
if (predicate.test(cand)) {
127+
rw.java = true;
128+
continue outer;
129+
}
130+
}
131+
}
132+
}
133+
134+
// Generate the final results
135+
// Set<File> resultFiles = builderMap.keySet();
136+
// resultFileArray = resultFiles.toArray(new File[0]);
137+
138+
this.requirements = allReqs;
139+
this.capabilities = allCaps;
140+
141+
// showResults(resultFileArray, importResults, exportResults);
142+
return Status.OK_STATUS;
143+
} catch (Exception e) {
144+
throw new RuntimeException(e);
145+
}
146+
}
147+
148+
public Map<String, List<RequirementWrapper>> getRequirements() {
149+
return Collections.unmodifiableMap(requirements);
150+
}
151+
152+
public Map<String, List<Capability>> getCapabilities() {
153+
return Collections.unmodifiableMap(capabilities);
154+
}
155+
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2015, 2023 bndtools project and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Neil Bartlett <[email protected]> - initial API and implementation
13+
* BJ Hargrave <[email protected]> - ongoing enhancements
14+
* Peter Kriens <[email protected]> - ongoing enhancements
15+
* Christoph Rueger <[email protected]> - ongoing enhancements
16+
*******************************************************************************/
17+
package bndtools.tasks;
18+
19+
import static java.util.stream.Collectors.groupingBy;
20+
import static java.util.stream.Collectors.mapping;
21+
import static java.util.stream.Collectors.toList;
22+
23+
import java.io.File;
24+
import java.util.ArrayList;
25+
import java.util.Collection;
26+
import java.util.Collections;
27+
import java.util.LinkedList;
28+
import java.util.List;
29+
import java.util.Map;
30+
import java.util.Objects;
31+
32+
import org.osgi.framework.namespace.PackageNamespace;
33+
import org.osgi.resource.Capability;
34+
import org.osgi.resource.Requirement;
35+
import org.osgi.resource.Resource;
36+
37+
import aQute.bnd.exceptions.Exceptions;
38+
import aQute.bnd.osgi.Builder;
39+
import aQute.bnd.osgi.Clazz;
40+
import aQute.bnd.osgi.Jar;
41+
import aQute.bnd.osgi.resource.ResourceBuilder;
42+
import aQute.bnd.service.resource.SupportingResource;
43+
import bndtools.model.resolution.RequirementWrapper;
44+
45+
public abstract class BndBuilderCapReqLoader implements CapReqLoader {
46+
47+
protected final File file;
48+
private Map<String, List<Capability>> loadCapabilities;
49+
private Map<String, List<RequirementWrapper>> loadRequirements;
50+
51+
public BndBuilderCapReqLoader(File file) {
52+
this.file = file;
53+
}
54+
55+
@Override
56+
public String getShortLabel() {
57+
return file.getName();
58+
}
59+
60+
@Override
61+
public String getLongLabel() {
62+
return file.getName() + " - " + file.getParentFile()
63+
.getAbsolutePath();
64+
}
65+
66+
protected abstract Builder getBuilder() throws Exception;
67+
68+
private void load() throws Exception {
69+
if ((loadCapabilities != null) && (loadRequirements != null)) {
70+
return;
71+
}
72+
73+
Builder builder = getBuilder();
74+
if (builder == null) {
75+
loadCapabilities = Collections.emptyMap();
76+
loadRequirements = Collections.emptyMap();
77+
return;
78+
}
79+
80+
Jar jar = builder.getJar();
81+
if (jar == null) {
82+
loadCapabilities = Collections.emptyMap();
83+
loadRequirements = Collections.emptyMap();
84+
return;
85+
}
86+
87+
ResourceBuilder rb = new ResourceBuilder();
88+
rb.addJar(jar);
89+
SupportingResource sr = rb.build();
90+
List<Capability> capabilities = new ArrayList<>();
91+
List<Requirement> requirements = new ArrayList<>();
92+
93+
for (Resource resource : sr.all()) {
94+
capabilities.addAll(resource.getCapabilities(null));
95+
requirements.addAll(resource.getRequirements(null));
96+
}
97+
loadRequirements = requirements.stream()
98+
.collect(groupingBy(Requirement::getNamespace, mapping(this::toRequirementWrapper, toList())));
99+
loadCapabilities = capabilities.stream()
100+
.collect(groupingBy(Capability::getNamespace, toList()));
101+
}
102+
103+
@Override
104+
public Map<String, List<Capability>> loadCapabilities() throws Exception {
105+
load();
106+
return loadCapabilities;
107+
}
108+
109+
@Override
110+
public Map<String, List<RequirementWrapper>> loadRequirements() throws Exception {
111+
load();
112+
return loadRequirements;
113+
}
114+
115+
private RequirementWrapper toRequirementWrapper(Requirement req) {
116+
RequirementWrapper rw = new RequirementWrapper(req);
117+
if (req.getNamespace()
118+
.equals(PackageNamespace.PACKAGE_NAMESPACE)) {
119+
String pkgName = (String) req.getAttributes()
120+
.get(PackageNamespace.PACKAGE_NAMESPACE);
121+
try {
122+
rw.requirers = findImportingClasses(pkgName);
123+
} catch (Exception e) {
124+
throw Exceptions.duck(e);
125+
}
126+
}
127+
return rw;
128+
}
129+
130+
private List<Clazz> findImportingClasses(String pkgName) throws Exception {
131+
List<Clazz> classes = new LinkedList<>();
132+
Collection<Clazz> importers = getBuilder().getClasses("", "IMPORTING", pkgName);
133+
134+
// Remove *this* package
135+
for (Clazz clazz : importers) {
136+
String fqn = clazz.getFQN();
137+
int dot = fqn.lastIndexOf('.');
138+
if (dot >= 0) {
139+
String pkg = fqn.substring(0, dot);
140+
if (!pkgName.equals(pkg))
141+
classes.add(clazz);
142+
}
143+
}
144+
return classes;
145+
}
146+
147+
public File getFile() {
148+
return file;
149+
}
150+
151+
@Override
152+
public int hashCode() {
153+
final int prime = 31;
154+
int result = 1;
155+
result = prime * result + ((file == null) ? 0 : file.hashCode());
156+
return result;
157+
}
158+
159+
@Override
160+
public boolean equals(Object obj) {
161+
if (this == obj)
162+
return true;
163+
if (obj == null)
164+
return false;
165+
if (getClass() != obj.getClass())
166+
return false;
167+
BndBuilderCapReqLoader other = (BndBuilderCapReqLoader) obj;
168+
return Objects.equals(file, other.file);
169+
}
170+
171+
}

0 commit comments

Comments
 (0)