use of org.eclipse.osgi.service.resolver.GenericSpecification in project rt.equinox.framework by eclipse.
the class ResolverBundle method initialize.
void initialize(boolean useSelectedExports) {
if (getBundleDescription().getHost() != null) {
host = new BundleConstraint(this, getBundleDescription().getHost());
exports = new ResolverExport[0];
imports = new ResolverImport[0];
requires = new BundleConstraint[0];
GenericSpecification[] requirements = getBundleDescription().getGenericRequires();
List<GenericConstraint> constraints = new ArrayList<>();
for (GenericSpecification requirement : requirements) {
if (StateImpl.OSGI_EE_NAMESPACE.equals(requirement.getType())) {
constraints.add(new GenericConstraint(this, requirement, resolver.isDevelopmentMode()));
}
}
genericReqiures = constraints.toArray(new GenericConstraint[constraints.size()]);
GenericDescription[] capabilities = getBundleDescription().getGenericCapabilities();
GenericCapability identity = null;
for (GenericDescription capability : capabilities) {
if (IdentityNamespace.IDENTITY_NAMESPACE.equals(capability.getType())) {
identity = new GenericCapability(this, capability, resolver.isDevelopmentMode());
break;
}
}
genericCapabilities = identity == null ? new GenericCapability[0] : new GenericCapability[] { identity };
return;
}
ImportPackageSpecification[] actualImports = getBundleDescription().getImportPackages();
// Reorder imports so that optionals are at the end so that we wire statics before optionals
List<ResolverImport> importList = new ArrayList<>(actualImports.length);
for (int i = actualImports.length - 1; i >= 0; i--) if (ImportPackageSpecification.RESOLUTION_OPTIONAL.equals(actualImports[i].getDirective(Constants.RESOLUTION_DIRECTIVE)))
importList.add(new ResolverImport(this, actualImports[i]));
else
importList.add(0, new ResolverImport(this, actualImports[i]));
imports = importList.toArray(new ResolverImport[importList.size()]);
ExportPackageDescription[] actualExports = useSelectedExports ? getBundleDescription().getSelectedExports() : getBundleDescription().getExportPackages();
exports = new ResolverExport[actualExports.length];
for (int i = 0; i < actualExports.length; i++) exports[i] = new ResolverExport(this, actualExports[i]);
BundleSpecification[] actualRequires = getBundleDescription().getRequiredBundles();
requires = new BundleConstraint[actualRequires.length];
for (int i = 0; i < requires.length; i++) requires[i] = new BundleConstraint(this, actualRequires[i]);
GenericSpecification[] actualGenericRequires = getBundleDescription().getGenericRequires();
genericReqiures = new GenericConstraint[actualGenericRequires.length];
for (int i = 0; i < genericReqiures.length; i++) {
genericReqiures[i] = new GenericConstraint(this, actualGenericRequires[i], resolver.isDevelopmentMode());
}
GenericDescription[] actualCapabilities = useSelectedExports ? getBundleDescription().getSelectedGenericCapabilities() : getBundleDescription().getGenericCapabilities();
genericCapabilities = new GenericCapability[actualCapabilities.length];
for (int i = 0; i < genericCapabilities.length; i++) {
genericCapabilities[i] = new GenericCapability(this, actualCapabilities[i], resolver.isDevelopmentMode());
}
fragments = null;
fragmentExports = null;
fragmentImports = null;
fragmentRequires = null;
fragmentGenericCapabilities = null;
fragmentGenericRequires = null;
}
use of org.eclipse.osgi.service.resolver.GenericSpecification in project rt.equinox.framework by eclipse.
the class ResolverBundle method attachFragment.
void attachFragment(ResolverBundle fragment, boolean dynamicAttach) {
if (isFragment())
// cannot attach to fragments;
return;
if (!getBundleDescription().attachFragments() || (isResolved() && !getBundleDescription().dynamicFragments()))
// host is restricting attachment
return;
if (fragment.getHost().getNumPossibleSuppliers() > 0 && !((HostSpecification) fragment.getHost().getVersionConstraint()).isMultiHost())
// fragment is restricting attachment
return;
ImportPackageSpecification[] newImports = fragment.getBundleDescription().getImportPackages();
BundleSpecification[] newRequires = fragment.getBundleDescription().getRequiredBundles();
ExportPackageDescription[] newExports = fragment.getBundleDescription().getExportPackages();
GenericDescription[] newGenericCapabilities = fragment.getBundleDescription().getGenericCapabilities();
GenericSpecification[] newGenericRequires = fragment.getBundleDescription().getGenericRequires();
// if this is not during initialization then check if constraints conflict
if (dynamicAttach && constraintsConflict(fragment.getBundleDescription(), newImports, newRequires, newGenericRequires))
// do not allow fragments with conflicting constraints
return;
if (isResolved() && newExports.length > 0)
fragment.setNewFragmentExports(true);
initFragments();
// already attached to this host
for (Iterator<ResolverBundle> iFragments = fragments.iterator(); iFragments.hasNext(); ) {
ResolverBundle existingFragment = iFragments.next();
String bsn = existingFragment.getName();
if (bsn != null && bsn.equals(fragment.getName()))
return;
}
if (fragments.contains(fragment))
return;
fragments.add(fragment);
fragment.getHost().addPossibleSupplier(this);
if (newImports.length > 0) {
ArrayList<ResolverImport> hostImports = new ArrayList<>(newImports.length);
for (int i = 0; i < newImports.length; i++) if (!isImported(newImports[i].getName()))
hostImports.add(new ResolverImport(this, newImports[i]));
fragmentImports.put(fragment.bundleID, hostImports);
}
if (newRequires.length > 0) {
ArrayList<BundleConstraint> hostRequires = new ArrayList<>(newRequires.length);
for (int i = 0; i < newRequires.length; i++) if (!isRequired(newRequires[i].getName()))
hostRequires.add(new BundleConstraint(this, newRequires[i]));
fragmentRequires.put(fragment.bundleID, hostRequires);
}
if (newGenericRequires.length > 0) {
ArrayList<GenericConstraint> hostGenericRequires = new ArrayList<>(newGenericRequires.length);
for (int i = 0; i < newGenericRequires.length; i++) {
// only add namespaces that are not osgi.ee
if (!StateImpl.OSGI_EE_NAMESPACE.equals(newGenericRequires[i].getType())) {
hostGenericRequires.add(new GenericConstraint(this, newGenericRequires[i], resolver.isDevelopmentMode()));
}
}
if (!hostGenericRequires.isEmpty())
fragmentGenericRequires.put(fragment.bundleID, hostGenericRequires);
}
ArrayList<ResolverExport> hostExports = new ArrayList<>(newExports.length);
if (newExports.length > 0 && dynamicAttach) {
for (int i = 0; i < newExports.length; i++) {
ResolverExport[] currentExports = getExports(newExports[i].getName());
boolean foundEquivalent = false;
for (int j = 0; j < currentExports.length && !foundEquivalent; j++) {
if (equivalentExports(currentExports[j], newExports[i]))
foundEquivalent = true;
}
if (!foundEquivalent) {
ExportPackageDescription hostExport = new ExportPackageDescriptionImpl(getBundleDescription(), newExports[i]);
hostExports.add(new ResolverExport(this, hostExport));
}
}
fragmentExports.put(fragment.bundleID, hostExports);
}
List<GenericCapability> hostCapabilities = new ArrayList<>(newGenericCapabilities.length);
if (newGenericCapabilities.length > 0 && dynamicAttach) {
for (GenericDescription capability : newGenericCapabilities) {
if (!IdentityNamespace.IDENTITY_NAMESPACE.equals(capability.getType())) {
GenericDescription hostCapabililty = new GenericDescriptionImpl(getBundleDescription(), capability);
hostCapabilities.add(new GenericCapability(this, hostCapabililty, resolver.isDevelopmentMode()));
}
}
if (hostCapabilities.size() > 0) {
fragmentGenericCapabilities.put(fragment.bundleID, hostCapabilities);
if (isResolved())
fragment.setNewFragmentCapabilities(true);
}
}
if (dynamicAttach) {
resolver.getResolverExports().put(hostExports.toArray(new ResolverExport[hostExports.size()]));
resolver.addGenerics(hostCapabilities.toArray(new GenericCapability[hostCapabilities.size()]));
}
}
use of org.eclipse.osgi.service.resolver.GenericSpecification in project rt.equinox.framework by eclipse.
the class ResolverBundle method constraintsConflict.
boolean constraintsConflict(BundleDescription fragment, ImportPackageSpecification[] newImports, BundleSpecification[] newRequires, GenericSpecification[] newGenericRequires) {
// this method iterates over all additional constraints from a fragment
// if the host is resolved then the fragment is not allowed to add new constraints;
// if the host is resolved and it already has a constraint of the same name then ensure the supplier satisfies the fragment's constraint
boolean result = false;
for (int i = 0; i < newImports.length; i++) {
ResolverImport hostImport = getImport(newImports[i].getName());
ResolverExport resolvedExport = (ResolverExport) (hostImport == null ? null : hostImport.getSelectedSupplier());
if (importPackageConflict(resolvedExport, newImports[i])) {
result = true;
resolver.getState().addResolverError(fragment, ResolverError.FRAGMENT_CONFLICT, newImports[i].toString(), newImports[i]);
}
}
for (int i = 0; i < newRequires.length; i++) {
BundleConstraint hostRequire = getRequire(newRequires[i].getName());
ResolverBundle resolvedRequire = (ResolverBundle) (hostRequire == null ? null : hostRequire.getSelectedSupplier());
if ((resolvedRequire == null && isResolved()) || (resolvedRequire != null && !newRequires[i].isSatisfiedBy(resolvedRequire.getBundleDescription()))) {
result = true;
resolver.getState().addResolverError(fragment, ResolverError.FRAGMENT_CONFLICT, newRequires[i].toString(), newRequires[i]);
}
}
// only check that a fragment does not add generic constraints to an already resolved host
if (isResolved() && newGenericRequires != null) {
for (GenericSpecification genericSpecification : newGenericRequires) {
if (!StateImpl.OSGI_EE_NAMESPACE.equals(genericSpecification.getType())) {
result = true;
resolver.getState().addResolverError(fragment, ResolverError.FRAGMENT_CONFLICT, genericSpecification.toString(), genericSpecification);
}
}
}
return result;
}
use of org.eclipse.osgi.service.resolver.GenericSpecification in project rt.equinox.framework by eclipse.
the class ResolverImpl method rewireGeneric.
private void rewireGeneric(GenericConstraint constraint, List<ResolverBundle> visited) {
if (constraint.getSelectedSupplier() != null)
return;
GenericDescription[] suppliers = ((GenericSpecification) constraint.getVersionConstraint()).getSuppliers();
if (suppliers == null)
return;
VersionHashMap<GenericCapability> namespace = resolverGenerics.get(constraint.getNameSpace());
if (namespace == null) {
// $NON-NLS-1$
System.err.println("Could not find matching capability for " + constraint.getVersionConstraint());
// TODO log error!!
return;
}
String constraintName = constraint.getName();
List<GenericCapability> matches = constraintName == null ? namespace.get(constraintName) : namespace.getAllValues();
for (GenericCapability match : matches) {
for (GenericDescription supplier : suppliers) if (match.getBaseDescription() == supplier)
constraint.addPossibleSupplier(match);
}
VersionSupplier[] matchingCapabilities = constraint.getPossibleSuppliers();
if (matchingCapabilities != null)
for (int i = 0; i < matchingCapabilities.length; i++) rewireBundle(matchingCapabilities[i].getResolverBundle(), visited);
}
use of org.eclipse.osgi.service.resolver.GenericSpecification in project rt.equinox.framework by eclipse.
the class StateBuilder method createEquinoxRequires.
private static List<GenericSpecification> createEquinoxRequires(ManifestElement[] equinoxRequires) throws BundleException {
if (equinoxRequires == null)
return null;
ArrayList<GenericSpecification> results = new ArrayList<>(equinoxRequires.length);
for (int i = 0; i < equinoxRequires.length; i++) {
String[] genericNames = equinoxRequires[i].getValueComponents();
for (int j = 0; j < genericNames.length; j++) {
GenericSpecificationImpl spec = new GenericSpecificationImpl();
int colonIdx = genericNames[j].indexOf(':');
if (colonIdx > 0) {
spec.setName(genericNames[j].substring(0, colonIdx));
spec.setType(genericNames[j].substring(colonIdx + 1));
} else
spec.setName(genericNames[j]);
try {
spec.setMatchingFilter(equinoxRequires[i].getAttribute(Constants.SELECTION_FILTER_ATTRIBUTE), true);
} catch (InvalidSyntaxException e) {
String message = NLS.bind(Msg.MANIFEST_INVALID_HEADER_EXCEPTION, GENERIC_REQUIRE, equinoxRequires[i].toString());
// $NON-NLS-1$
throw new BundleException(message + " : " + Constants.SELECTION_FILTER_ATTRIBUTE, BundleException.MANIFEST_ERROR, e);
}
String optional = equinoxRequires[i].getAttribute(OPTIONAL_ATTR);
String multiple = equinoxRequires[i].getAttribute(MULTIPLE_ATTR);
int resolution = 0;
if (TRUE.equals(optional))
resolution |= GenericSpecification.RESOLUTION_OPTIONAL;
if (TRUE.equals(multiple))
resolution |= GenericSpecification.RESOLUTION_MULTIPLE;
spec.setResolution(resolution);
results.add(spec);
}
}
return results;
}
Aggregations