/*
* 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.");
}
}
}