/*
* 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.ContentHandler;
import org.apache.aries.subsystem.core.archive.DeployedContentHeader;
import org.apache.aries.subsystem.core.archive.DeploymentManifest;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.resource.Resource;
import org.osgi.service.coordinator.Coordination;
import org.osgi.service.subsystem.SubsystemConstants;
import org.osgi.service.subsystem.SubsystemException;
public abstract class ResourceInstaller {
public static ResourceInstaller newInstance(Coordination coordination, Resource resource, BasicSubsystem subsystem) {
String type = ResourceHelper.getTypeAttribute(resource);
if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
|| SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)
|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) {
return new SubsystemResourceInstaller(coordination, resource, subsystem);
} else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
return new BundleResourceInstaller(coordination, resource, subsystem);
} else if (Constants.ResourceTypeSynthesized.equals(type)) {
return new ResourceInstaller(coordination, resource, subsystem) {
@Override
public Resource install() throws Exception {
// do nothing;
return resource;
}
};
} else {
ServiceReference<ContentHandler> handlerRef = CustomResources.getCustomContentHandler(subsystem, type);
if (handlerRef != null)
return new CustomResourceInstaller(coordination, resource, type, subsystem, handlerRef);
}
throw new SubsystemException("No installer exists for resource type: " + type);
}
protected final Coordination coordination;
protected final BasicSubsystem provisionTo;
/* resource to install */
protected final Resource resource;
/* parent subsystem being installed into */
protected final BasicSubsystem subsystem;
public ResourceInstaller(Coordination coordination, Resource resource, BasicSubsystem subsystem) {
if (coordination == null || resource == null || subsystem == null) {
// We're assuming these are not null post construction, so enforce it here.
throw new NullPointerException();
}
this.coordination = coordination;
this.resource = resource;
this.subsystem = subsystem;
if (isDependency()) {
if (Utils.isInstallableResource(resource))
provisionTo = Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(subsystem);
else
provisionTo = null;
}
else
provisionTo = subsystem;
}
public abstract Resource install() throws Exception;
protected void addConstituent(final Resource resource) {
// Don't let a resource become a constituent of itself.
if (provisionTo == null || resource.equals(provisionTo))
return;
Activator.getInstance().getSubsystems().addConstituent(provisionTo, resource, isReferencedProvisionTo());
}
protected void addReference(final Resource resource) {
// Don't let a resource reference itself.
if (resource.equals(subsystem))
return;
// The following check protects against resources posing as content
// during a restart since the Deployed-Content header is currently used
// to track all constituents for persistence purposes, which includes
// resources that were provisioned to the subsystem as dependencies of
// other resources.
if (isReferencedSubsystem()) {
Activator.getInstance().getSubsystems().addReference(subsystem, resource);
}
}
protected String getLocation() {
return provisionTo.getLocation() + "!/" + ResourceHelper.getLocation(resource);
}
protected boolean isContent() {
return Utils.isContent(subsystem, resource);
}
protected boolean isDependency() {
return Utils.isDependency(subsystem, resource);
}
protected boolean isReferencedProvisionTo() {
DeploymentManifest manifest = subsystem.getDeploymentManifest();
if (manifest != null) {
DeployedContentHeader header = manifest.getDeployedContentHeader();
if (header != null && header.contains(resource))
return subsystem.isReferenced(resource);
}
if (subsystem.equals(provisionTo))
return isReferencedSubsystem();
return false;
}
protected boolean isReferencedSubsystem() {
DeploymentManifest manifest = subsystem.getDeploymentManifest();
if (manifest != null) {
DeployedContentHeader header = manifest.getDeployedContentHeader();
if (header != null && header.contains(resource))
return subsystem.isReferenced(resource);
}
return true;
}
}