blob: 6918fb79f4d3f81aafccf1ba0c4e1600c6ec196e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.ace.deployment.verifier.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.manifestparser.ManifestParser;
import org.apache.felix.framework.util.manifestparser.R4Library;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
/**
*
*/
public class VerifierBundleRevision implements BundleRevision {
private final String m_symbolicName;
private final Version m_version;
private final List<BundleCapability> m_declaredCaps;
private final List<BundleRequirement> m_declaredReqs;
private final int m_type;
private final Bundle m_bundle;
private final List<R4Library> m_declaredLibs;
private final Map<String, String> m_headers;
/**
* @param log
* @param bundle
* @param config
* @param headers
* @throws BundleException
*/
public VerifierBundleRevision(Logger log, Bundle bundle, Map<String, String> config, Map<String, String> headers) throws BundleException {
m_bundle = bundle;
m_headers = Collections.unmodifiableMap(headers);
ManifestParser parser = new ManifestParser(log, config, this, headers);
m_symbolicName = parser.getSymbolicName();
m_version = parser.getBundleVersion();
m_declaredCaps = (m_bundle.getBundleId() != 0) ? parser.getCapabilities() : aliasSymbolicName(parser.getCapabilities());
m_declaredReqs = parser.getRequirements();
m_type = headers.containsKey(Constants.FRAGMENT_HOST) ? BundleRevision.TYPE_FRAGMENT : 0;
m_declaredLibs = parser.getLibraries();
}
/**
* Takes a given list of bundle capabilities and patches all symbolic names to be marked as system bundles.
*
* @param capabilities the capabilities to patch, may be <code>null</code>.
* @return the patched capabilities, or an emtpy list in case the given capabilities was <code>null</code>.
*/
private static List<BundleCapability> aliasSymbolicName(List<BundleCapability> capabilities)
{
if (capabilities == null)
{
return Collections.emptyList();
}
List<BundleCapability> aliasCaps = new ArrayList<BundleCapability>(capabilities);
for (int capIdx = 0; capIdx < aliasCaps.size(); capIdx++)
{
BundleCapability capability = aliasCaps.get(capIdx);
// Get the attributes and search for bundle symbolic name.
Map<String, Object> attributes = capability.getAttributes();
for (Entry<String, Object> entry : attributes.entrySet())
{
// If there is a bundle symbolic name attribute, add the
// standard alias as a value.
if (Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE.equalsIgnoreCase(entry.getKey()))
{
// Make a copy of the attribute array.
Map<String, Object> aliasAttrs = new HashMap<String, Object>(attributes);
// Add the aliased value.
aliasAttrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, new String[] { (String) entry.getValue(), Constants.SYSTEM_BUNDLE_SYMBOLICNAME });
// Create the aliased capability to replace the old capability.
aliasCaps.set(capIdx, new BundleCapabilityImpl(capability.getRevision(), capability.getNamespace(), capability.getDirectives(), aliasAttrs));
// Continue with the next capability.
break;
}
}
}
return aliasCaps;
}
/**
* {@inheritDoc}
*/
public Bundle getBundle() {
return m_bundle;
}
/**
* {@inheritDoc}
*/
public String getSymbolicName() {
return m_symbolicName;
}
/**
* {@inheritDoc}
*/
public Version getVersion() {
return m_version;
}
/**
* {@inheritDoc}
*/
public List<BundleCapability> getDeclaredCapabilities(String namespace) {
return m_declaredCaps;
}
/**
* {@inheritDoc}
*/
public List<Capability> getCapabilities(String namespace) {
return new ArrayList<Capability>(m_declaredCaps);
}
/**
* {@inheritDoc}
*/
public List<BundleRequirement> getDeclaredRequirements(String namespace) {
return m_declaredReqs;
}
/**
* {@inheritDoc}
*/
public List<Requirement> getRequirements(String namespace) {
return new ArrayList<Requirement>(m_declaredReqs);
}
/**
* {@inheritDoc}
*/
public List<R4Library> getDeclaredNativeLibraries() {
return m_declaredLibs;
}
/**
* {@inheritDoc}
*/
public int getTypes() {
return m_type;
}
/**
* {@inheritDoc}
*/
public BundleWiring getWiring() {
return null;
}
/**
* {@inheritDoc}
*/
public Map<String, String> getHeaders() {
return m_headers;
}
/**
* Returns the required execution environment, if defined.
*
* @return the required execution environment, can be <code>null</code> if not defined.
*/
@SuppressWarnings("deprecation")
public String getRequiredExecutionEnvironment() {
String result = getHeaders().get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
return result == null ? null : result.trim();
}
/**
* {@inheritDoc}
*/
public int hashCode() {
return (int) getBundle().getBundleId();
}
/**
* {@inheritDoc}
*/
public boolean equals(Object o) {
if (o instanceof VerifierBundleRevision) {
return o.hashCode() == hashCode();
}
return false;
}
/**
* {@inheritDoc}
*/
public String toString() {
return m_symbolicName + ";"+ Constants.VERSION_ATTRIBUTE + "=" + m_version + "(id=" + getBundle().getBundleId() + ")";
}
}