/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.aries.subsystem.core.internal; import org.apache.aries.subsystem.core.archive.AriesProvisionDependenciesDirective; import org.apache.aries.subsystem.core.archive.PreferredProviderHeader; import org.apache.aries.subsystem.core.archive.ProvisionPolicyDirective; import org.apache.aries.subsystem.core.archive.SubsystemContentHeader; import org.apache.aries.subsystem.core.archive.SubsystemManifest; import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader; import org.osgi.service.subsystem.Subsystem.State; import org.osgi.service.subsystem.SubsystemConstants; import org.osgi.service.subsystem.SubsystemException; public class SubsystemManifestValidator { public static void validate(BasicSubsystem subsystem, SubsystemManifest manifest) { if (subsystem.getResource().getId() == 0) { return; } validatePreferredProviderHeader(manifest.getPreferredProviderHeader()); validateAriesProvisionDependenciesDirective(subsystem); if (subsystem.isComposite()) { SubsystemContentHeader header = manifest.getSubsystemContentHeader(); if (header == null) { return; } for (SubsystemContentHeader.Clause clause : header.getClauses()) { if (!clause.getVersionRange().isExact()) { throw new SubsystemException("Composite subsystem using version range for content: " + clause); } } } else if (subsystem.isFeature()) { SubsystemTypeHeader subsystemTypeHeader = manifest.getSubsystemTypeHeader(); ProvisionPolicyDirective provisionPolicyDirective = subsystemTypeHeader.getProvisionPolicyDirective(); if (provisionPolicyDirective.isAcceptDependencies()) { throw new SubsystemException("Feature subsystems may not declare a provision-policy of acceptDependencies"); } if (manifest.getHeaders().get(SubsystemConstants.PREFERRED_PROVIDER) != null) { throw new SubsystemException("Feature subsystems may not declare a " + SubsystemConstants.PREFERRED_PROVIDER + " header"); } } } private static void validatePreferredProviderHeader(PreferredProviderHeader header) { if (header == null) { return; } for (PreferredProviderHeader.Clause clause : header.getClauses()) { String type = (String)clause.getAttribute(PreferredProviderHeader.Clause.ATTRIBUTE_TYPE).getValue(); if (!(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type) || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type) || Constants.ResourceTypeBundle.equals(type))) { throw new SubsystemException("Unsupported " + PreferredProviderHeader.NAME + " type: " + type); } } } private static void validateAriesProvisionDependenciesDirective(BasicSubsystem subsystem) { AriesProvisionDependenciesDirective directive = subsystem.getAriesProvisionDependenciesDirective(); BasicSubsystem parent = subsystem.getResource().getParents().iterator().next(); AriesProvisionDependenciesDirective parentDirective = parent.getAriesProvisionDependenciesDirective(); if (!directive.equals(parentDirective) && (subsystem.isFeature() || State.INSTALLING.equals(parent.getState()))) { throw new SubsystemException("The value of the " + AriesProvisionDependenciesDirective.NAME + " directive must be the same as the parent subsystem for features and implicitly installed subsystems."); } } }