org.eclipse.osgi.container.ModuleResolutionReport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/*******************************************************************************
* Copyright (c) 2013, 2016 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.container;
import java.util.*;
import org.eclipse.osgi.internal.framework.FilterImpl;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.report.resolution.ResolutionReport;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.namespace.*;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.resource.*;
import org.osgi.service.resolver.ResolutionException;
/**
* A resolution report implementation used by the container for resolution operations.
* @since 3.10
*/
class ModuleResolutionReport implements ResolutionReport {
static class Builder {
private final Map> resourceToEntries = new HashMap<>();
public void addEntry(Resource resource, Entry.Type type, Object data) {
List entries = resourceToEntries.get(resource);
if (entries == null) {
entries = new ArrayList<>();
resourceToEntries.put(resource, entries);
}
entries.add(new EntryImpl(type, data));
}
public ModuleResolutionReport build(Map> resolutionResult, ResolutionException cause) {
return new ModuleResolutionReport(resolutionResult, resourceToEntries, cause);
}
}
static class EntryImpl implements Entry {
private final Object data;
private final Type type;
EntryImpl(Type type, Object data) {
this.type = type;
this.data = data;
}
@Override
public Object getData() {
return data;
}
@Override
public Type getType() {
return type;
}
}
private final Map> entries;
private final ResolutionException resolutionException;
private final Map> resolutionResult;
ModuleResolutionReport(Map> resolutionResult, Map> entries, ResolutionException cause) {
this.entries = entries == null ? Collections.> emptyMap() : Collections.unmodifiableMap(new HashMap<>(entries));
this.resolutionResult = resolutionResult == null ? Collections.> emptyMap() : Collections.unmodifiableMap(resolutionResult);
this.resolutionException = cause;
}
@Override
public Map> getEntries() {
return entries;
}
@Override
public ResolutionException getResolutionException() {
return resolutionException;
}
Map> getResolutionResult() {
return resolutionResult;
}
private static String getResolutionReport0(String prepend, ModuleRevision revision, Map> reportEntries, Set visited) {
if (prepend == null) {
prepend = ""; //$NON-NLS-1$
}
if (visited == null) {
visited = new HashSet<>();
}
if (visited.contains(revision)) {
return ""; //$NON-NLS-1$
}
visited.add(revision);
StringBuilder result = new StringBuilder();
String id = revision.getRevisions().getModule().getId().toString();
result.append(prepend).append(revision.getSymbolicName()).append(" [").append(id).append("]").append('\n'); //$NON-NLS-1$ //$NON-NLS-2$
List revisionEntries = reportEntries.get(revision);
if (revisionEntries == null) {
result.append(prepend).append(" ").append(Msg.ModuleResolutionReport_NoReport); //$NON-NLS-1$
} else {
for (ResolutionReport.Entry entry : revisionEntries) {
printResolutionEntry(result, prepend + " ", entry, reportEntries, visited); //$NON-NLS-1$
}
}
return result.toString();
}
private static void printResolutionEntry(StringBuilder result, String prepend, ResolutionReport.Entry entry, Map> reportEntries, Set visited) {
switch (entry.getType()) {
case MISSING_CAPABILITY :
result.append(prepend).append(Msg.ModuleResolutionReport_UnresolvedReq).append(printRequirement(entry.getData())).append('\n');
break;
case SINGLETON_SELECTION :
result.append(prepend).append(Msg.ModuleResolutionReport_AnotherSingleton).append(entry.getData()).append('\n');
break;
case UNRESOLVED_PROVIDER :
@SuppressWarnings("unchecked")
Map> unresolvedProviders = (Map>) entry.getData();
for (Map.Entry> unresolvedRequirement : unresolvedProviders.entrySet()) {
// for now only printing the first possible unresolved candidates
Set unresolvedCapabilities = unresolvedRequirement.getValue();
if (!unresolvedCapabilities.isEmpty()) {
Capability unresolvedCapability = unresolvedCapabilities.iterator().next();
// make sure this is not a case of importing and exporting the same package
if (!unresolvedRequirement.getKey().getResource().equals(unresolvedCapability.getResource())) {
result.append(prepend).append(Msg.ModuleResolutionReport_UnresolvedReq).append(printRequirement(unresolvedRequirement.getKey())).append('\n');
result.append(prepend).append(" -> ").append(printCapability(unresolvedCapability)).append('\n'); //$NON-NLS-1$
result.append(getResolutionReport0(prepend + " ", (ModuleRevision) unresolvedCapability.getResource(), reportEntries, visited)); //$NON-NLS-1$
}
}
}
break;
case FILTERED_BY_RESOLVER_HOOK :
result.append(Msg.ModuleResolutionReport_FilteredByHook).append('\n');
break;
case USES_CONSTRAINT_VIOLATION :
result.append(prepend).append(Msg.ModuleResolutionReport_UsesConstraintError).append('\n');
result.append(" ").append(entry.getData()); //$NON-NLS-1$
break;
default :
result.append(Msg.ModuleResolutionReport_Unknown).append("type=").append(entry.getType()).append(" data=").append(entry.getData()).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$
break;
}
}
private static Object printCapability(Capability cap) {
if (PackageNamespace.PACKAGE_NAMESPACE.equals(cap.getNamespace())) {
return Constants.EXPORT_PACKAGE + ": " + createOSGiCapability(cap); //$NON-NLS-1$
} else if (BundleNamespace.BUNDLE_NAMESPACE.equals(cap.getNamespace())) {
return Constants.BUNDLE_SYMBOLICNAME + ": " + createOSGiCapability(cap); //$NON-NLS-1$
} else if (HostNamespace.HOST_NAMESPACE.equals(cap.getNamespace())) {
return Constants.BUNDLE_SYMBOLICNAME + ": " + createOSGiCapability(cap); //$NON-NLS-1$
}
return Constants.PROVIDE_CAPABILITY + ": " + cap.toString(); //$NON-NLS-1$
}
private static String createOSGiCapability(Capability cap) {
Map attributes = new HashMap<>(cap.getAttributes());
Map directives = cap.getDirectives();
String name = String.valueOf(attributes.remove(cap.getNamespace()));
return name + ModuleRevision.toString(attributes, false, true) + ModuleRevision.toString(directives, true, true);
}
private static String printRequirement(Object data) {
if (!(data instanceof Requirement)) {
return String.valueOf(data);
}
Requirement req = (Requirement) data;
if (PackageNamespace.PACKAGE_NAMESPACE.equals(req.getNamespace())) {
return Constants.IMPORT_PACKAGE + ": " + createOSGiRequirement(req, PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); //$NON-NLS-1$
} else if (BundleNamespace.BUNDLE_NAMESPACE.equals(req.getNamespace())) {
return Constants.REQUIRE_BUNDLE + ": " + createOSGiRequirement(req, BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); //$NON-NLS-1$
} else if (HostNamespace.HOST_NAMESPACE.equals(req.getNamespace())) {
return Constants.FRAGMENT_HOST + ": " + createOSGiRequirement(req, HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); //$NON-NLS-1$
}
return Constants.REQUIRE_CAPABILITY + ": " + req.toString(); //$NON-NLS-1$
}
private static String createOSGiRequirement(Requirement requirement, String... versions) {
Map directives = new HashMap<>(requirement.getDirectives());
String filter = directives.remove(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
if (filter == null)
throw new IllegalArgumentException("No filter directive found:" + requirement); //$NON-NLS-1$
FilterImpl filterImpl;
try {
filterImpl = FilterImpl.newInstance(filter);
} catch (InvalidSyntaxException e) {
throw new IllegalArgumentException("Invalid filter directive", e); //$NON-NLS-1$
}
Map matchingAttributes = filterImpl.getStandardOSGiAttributes(versions);
String name = matchingAttributes.remove(requirement.getNamespace());
if (name == null)
throw new IllegalArgumentException("Invalid requirement: " + requirement); //$NON-NLS-1$
return name + ModuleRevision.toString(matchingAttributes, false, true) + ModuleRevision.toString(directives, true, true);
}
@Override
public String getResolutionReportMessage(Resource resource) {
return getResolutionReport0(null, (ModuleRevision) resource, getEntries(), null);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy