/* * #%L * JBossOSGi Resolver API * %% * Copyright (C) 2010 - 2012 JBoss by Red Hat * %% * 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. * #L% */ package org.jboss.osgi.resolver.spi; import static org.jboss.osgi.resolver.ResolverMessages.MESSAGES; import static org.osgi.framework.namespace.AbstractWiringNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE; import static org.osgi.framework.namespace.BundleNamespace.BUNDLE_NAMESPACE; import static org.osgi.framework.namespace.HostNamespace.HOST_NAMESPACE; import static org.osgi.framework.namespace.IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE; import static org.osgi.framework.namespace.IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE; import static org.osgi.framework.namespace.PackageNamespace.PACKAGE_NAMESPACE; import java.util.Collections; import java.util.Map; import org.jboss.osgi.resolver.XAttributeSupport; import org.jboss.osgi.resolver.XCapability; import org.jboss.osgi.resolver.XDirectiveSupport; import org.jboss.osgi.resolver.XHostCapability; import org.jboss.osgi.resolver.XIdentityCapability; import org.jboss.osgi.resolver.XPackageCapability; import org.jboss.osgi.resolver.XProvidedCapability; import org.jboss.osgi.resolver.XResource; import org.jboss.osgi.resolver.XResourceCapability; import org.osgi.framework.Version; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; /** * The abstract implementation of a {@link XCapability}. * * @author thomas.diesler@jboss.com * @since 02-Jul-2010 */ public class AbstractCapability extends AbstractElement implements XIdentityCapability, XHostCapability, XPackageCapability, XResourceCapability, XProvidedCapability { private final String namespace; private final XResource resource; private XAttributeSupport attributes; private XDirectiveSupport directives; private String namespaceValue; private String canonicalName; private Version version; private boolean valid; public AbstractCapability(XResource resource, String namespace, Map<String, Object> atts, Map<String, String> dirs) { if (resource == null) throw MESSAGES.illegalArgumentNull("resource"); if (namespace == null) throw MESSAGES.illegalArgumentNull("namespace"); if (atts == null) throw MESSAGES.illegalArgumentNull("attributes"); if (dirs == null) throw MESSAGES.illegalArgumentNull("directives"); this.resource = resource; this.namespace = namespace; this.attributes = new AttributeSupporter(atts); this.directives = new DirectiveSupporter(dirs); } @Override public XResource getResource() { return resource; } @Override public String getNamespace() { return namespace; } @Override public Map<String, String> getDirectives() { return isMutable() ? directives.getDirectives() : Collections.unmodifiableMap(directives.getDirectives()); } @Override public String getDirective(String key) { return directives.getDirective(key); } @Override public Map<String, Object> getAttributes() { return isMutable() ? attributes.getAttributes() : Collections.unmodifiableMap(attributes.getAttributes()); } @Override public Object getAttribute(String key) { return attributes.getAttribute(key); } private boolean isMutable() { return resource.isMutable(); } @Override public void validate() { if (!valid) { if (AbstractResource.identityNamespaces.contains(getNamespace())) { version = getVersion(this, CAPABILITY_VERSION_ATTRIBUTE); namespaceValue = (String) getAttribute(getNamespace()); if (namespaceValue == null) throw MESSAGES.illegalStateCannotObtainAttribute(getNamespace()); } else if (BUNDLE_NAMESPACE.equals(getNamespace())) { version = getVersion(this, CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); namespaceValue = (String) getAttribute(getNamespace()); if (namespaceValue == null) throw MESSAGES.illegalStateCannotObtainAttribute(getNamespace()); } else if (HOST_NAMESPACE.equals(getNamespace())) { version = getVersion(this, CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); namespaceValue = (String) getAttribute(getNamespace()); if (namespaceValue == null) throw MESSAGES.illegalStateCannotObtainAttribute(getNamespace()); } else if (PACKAGE_NAMESPACE.equals(getNamespace())) { version = getVersion(this, CAPABILITY_VERSION_ATTRIBUTE); attributes.getAttributes().put(CAPABILITY_VERSION_ATTRIBUTE, version); namespaceValue = (String) getAttribute(getNamespace()); if (namespaceValue == null) throw MESSAGES.illegalStateCannotObtainAttribute(getNamespace()); } canonicalName = toString(); valid = true; } } @Override @SuppressWarnings("unchecked") public <T extends XCapability> T adapt(Class<T> clazz) { T result = null; if (XIdentityCapability.class == clazz && AbstractResource.identityNamespaces.contains(getNamespace())) { result = (T) this; } else if (XResourceCapability.class == clazz && BUNDLE_NAMESPACE.equals(getNamespace())) { result = (T) this; } else if (XHostCapability.class == clazz && HOST_NAMESPACE.equals(getNamespace())) { result = (T) this; } else if (XPackageCapability.class == clazz && PACKAGE_NAMESPACE.equals(getNamespace())) { result = (T) this; } return result; } @Override public String getPackageName() { return namespaceValue; } @Override public String getName() { return namespaceValue; } @Override public Version getVersion() { return version; } static Version getVersion(Capability cap, String attname) { Object attval = cap.getAttributes().get(attname); if (attval != null && !(attval instanceof Version)) { attval = new Version(attval.toString()); cap.getAttributes().put(attname, attval); } return attval != null ? (Version)attval : Version.emptyVersion; } @Override public String getType() { String typeval = (String) getAttribute(CAPABILITY_TYPE_ATTRIBUTE); return typeval != null ? typeval : IdentityNamespace.TYPE_UNKNOWN; } @Override public boolean isSingleton() { return Boolean.parseBoolean(getDirective(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE)); } @Override public String toString() { String result = canonicalName; if (result == null) { String type; String nsval = null; if (AbstractResource.identityNamespaces.contains(getNamespace())) { type = XIdentityCapability.class.getSimpleName(); } else if (BUNDLE_NAMESPACE.equals(getNamespace())) { type = XResourceCapability.class.getSimpleName(); } else if (HOST_NAMESPACE.equals(getNamespace())) { type = XHostCapability.class.getSimpleName(); } else if (PACKAGE_NAMESPACE.equals(getNamespace())) { type = XPackageCapability.class.getSimpleName(); } else { type = XProvidedCapability.class.getSimpleName(); nsval = namespace; } StringBuffer buffer = new StringBuffer(type + "["); boolean addcomma = false; if (nsval != null) { buffer.append(nsval); addcomma = true; } if (!getAttributes().isEmpty()) { buffer.append(addcomma ? "," : ""); buffer.append("atts=" + attributes); addcomma = true; } if (!getDirectives().isEmpty()) { buffer.append(addcomma ? "," : ""); buffer.append("dirs=" + directives); addcomma = true; } XIdentityCapability icap = resource.getIdentityCapability(); if (icap != null) { buffer.append(addcomma ? "," : ""); buffer.append("[" + icap.getName() + ":" + icap.getVersion() + "]"); addcomma = true; } else { buffer.append(addcomma ? "," : ""); buffer.append("[anonymous]"); addcomma = true; } buffer.append("]"); result = buffer.toString(); } return result; } }