package org.bndtools.utils.resources;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.namespace.contract.ContractNamespace;
import org.osgi.namespace.extender.ExtenderNamespace;
import org.osgi.namespace.service.ServiceNamespace;
import org.osgi.resource.Capability;
import org.osgi.resource.Resource;
import org.osgi.service.repository.ContentNamespace;
public final class ResourceUtils {
public static Capability getIdentityCapability(Resource resource) throws IllegalArgumentException {
List<Capability> caps = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
if (caps == null || caps.isEmpty())
throw new IllegalArgumentException("Resource has no identity");
if (caps.size() > 1) {
// Remove the alias identity "system.bundle"
List<Capability> filtered = new ArrayList<>(caps.size());
List<String> ids = new ArrayList<>(caps.size());
for (Capability cap : caps) {
String id = getIdentity(cap);
if (!Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(id)) {
filtered.add(cap);
ids.add(id);
}
}
caps = filtered;
if (caps.size() > 1)
throw new IllegalArgumentException("Resource has multiple identity capabilities: " + ids);
}
return caps.get(0);
}
public static String getIdentity(Capability identityCapability) throws IllegalArgumentException {
String id = (String) identityCapability.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE);
if (id == null)
throw new IllegalArgumentException("Resource identity capability has missing identity attribute");
return id;
}
public static final Version getVersion(Capability identityCapability) throws IllegalArgumentException {
Object versionObj = identityCapability.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
if (versionObj instanceof Version)
return (Version) versionObj;
if (versionObj == null || versionObj instanceof String)
return Version.parseVersion((String) versionObj);
throw new IllegalArgumentException("Resource identity capability has version attribute with incorrect type: " + versionObj.getClass());
}
public static final String getIdentity(Resource resource) throws IllegalArgumentException {
return getIdentity(getIdentityCapability(resource));
}
public static final Version getVersion(Resource resource) throws IllegalArgumentException {
return getVersion(getIdentityCapability(resource));
}
@SuppressWarnings("unused")
public static Capability getContentCapability(Resource resource) throws IllegalArgumentException {
List<Capability> caps = resource.getCapabilities(ContentNamespace.CONTENT_NAMESPACE);
if (caps == null)
throw new IllegalArgumentException("Resource has no content");
//A resource may have multiple capabilities and this is acceptable according to the specification
//to us, we should pick
//the first one with a URL that we understand, or the first URL if we understand none of them
Capability firstCap = null;
for (Capability c : caps) {
if (firstCap == null)
firstCap = c;
Object url = c.getAttributes().get("url");
if (url == null)
continue;
String urlString = String.valueOf(url);
try {
new URL(urlString);
return c;
} catch (MalformedURLException mue) {
// Oh well, just try the next one
}
}
if (firstCap == null)
throw new IllegalArgumentException("Resource has no content");
return firstCap;
}
public static URI getURI(Capability contentCapability) {
Object uriObj = contentCapability.getAttributes().get(ContentNamespace.CAPABILITY_URL_ATTRIBUTE);
if (uriObj == null)
throw new IllegalArgumentException("Resource content capability has missing URL attribute");
if (uriObj instanceof URI)
return (URI) uriObj;
try {
if (uriObj instanceof URL)
return ((URL) uriObj).toURI();
if (uriObj instanceof String) {
try {
URL url = new URL((String) uriObj);
return url.toURI();
} catch (MalformedURLException mfue) {
// Ignore
}
File f = new File((String) uriObj);
if (f.isFile()) {
return f.toURI();
}
return new URI((String) uriObj);
}
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Resource content capability has illegal URL attribute", e);
}
throw new IllegalArgumentException("Resource content capability has URL attribute with incorrect type: " + uriObj.getClass());
}
public static String getVersionAttributeForNamespace(String ns) {
String name;
if (IdentityNamespace.IDENTITY_NAMESPACE.equals(ns))
name = IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE;
else if (BundleNamespace.BUNDLE_NAMESPACE.equals(ns))
name = BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE;
else if (HostNamespace.HOST_NAMESPACE.equals(ns))
name = HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE;
else if (PackageNamespace.PACKAGE_NAMESPACE.equals(ns))
name = PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE;
else if (ServiceNamespace.SERVICE_NAMESPACE.equals(ns))
name = null;
else if (ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE.equals(ns))
name = ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE;
else if (ExtenderNamespace.EXTENDER_NAMESPACE.equals(ns))
name = ExtenderNamespace.CAPABILITY_VERSION_ATTRIBUTE;
else if (ContractNamespace.CONTRACT_NAMESPACE.equals(ns))
name = ContractNamespace.CAPABILITY_VERSION_ATTRIBUTE;
else
name = null;
return name;
}
}