/* * #%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 java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import org.jboss.osgi.resolver.XAttributeSupport; import org.jboss.osgi.resolver.XCapability; import org.jboss.osgi.resolver.XIdentityCapability; import org.jboss.osgi.resolver.XRequirement; import org.jboss.osgi.resolver.XResource; import org.jboss.osgi.resolver.XWiring; import org.jboss.osgi.resolver.XWiringSupport; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Requirement; /** * The abstract implementation of an {@link XResource}. * * @author thomas.diesler@jboss.com * @since 02-Jul-2010 */ public class AbstractResource extends AbstractElement implements XResource { static List<String> identityNamespaces = Arrays.asList(IdentityNamespace.IDENTITY_NAMESPACE, XResource.MODULE_IDENTITY_NAMESPACE, XResource.MAVEN_IDENTITY_NAMESPACE); private final Map<String, List<Capability>> capabilities = new HashMap<String, List<Capability>>(); private final Map<String, List<Requirement>> requirements = new HashMap<String, List<Requirement>>(); private final XAttributeSupport attributes = new AttributeSupporter(null); private final AtomicBoolean mutable = new AtomicBoolean(true); private final XWiringSupport wiringSupport; private XIdentityCapability identityCapability; private State state = State.UNINSTALLED; static AbstractResource assertAbstractResource(XResource resource) { assert resource != null : "Null resource"; assert resource instanceof AbstractResource : "Not an AbstractResource: " + resource; return (AbstractResource) resource; } public AbstractResource() { wiringSupport = createWiringSupport(); } XWiringSupport createWiringSupport() { return new AbstractWiringSupport(); } protected void addCapability(Capability cap) { ensureMutable(); String namespace = cap.getNamespace(); getCaplist(namespace).add(cap); getCaplist(null).add(cap); if (identityNamespaces.contains(namespace)) { identityCapability = (XIdentityCapability) cap; } } protected void addRequirement(Requirement req) { ensureMutable(); String namespace = req.getNamespace(); getReqlist(namespace).add(req); getReqlist(null).add(req); } @Override public Map<String, Object> getAttributes() { Map<String, Object> atts = attributes.getAttributes(); return isMutable() ? atts : Collections.unmodifiableMap(atts); } @Override public Object getAttribute(String key) { return attributes.getAttribute(key); } @Override public void setMutable(boolean flag) { mutable.set(flag); } @Override public State getState() { return state; } void setState(State state) { this.state = state; } @Override public boolean isMutable() { return mutable.get(); } @Override public boolean isAbstract() { return identityCapability != null ? TYPE_ABSTRACT.equals(identityCapability.getType()) : true; } public void ensureImmutable() { if (isMutable()) throw MESSAGES.illegalStateInvalidAccessToMutableResource(); } public void ensureMutable() { if (!isMutable()) throw MESSAGES.illegalStateInvalidAccessToImmutableResource(); } @Override public XWiringSupport getWiringSupport() { return wiringSupport; } @Override public XWiring getWiring(boolean checkEffective) { return wiringSupport.getWiring(checkEffective); } @Override public void validate() { // identity List<Capability> icaps = new ArrayList<Capability>(); icaps.addAll(getCaplist(IdentityNamespace.IDENTITY_NAMESPACE)); icaps.addAll(getCaplist(XResource.MODULE_IDENTITY_NAMESPACE)); icaps.addAll(getCaplist(XResource.MAVEN_IDENTITY_NAMESPACE)); if (icaps.size() > 1) throw MESSAGES.illegalStateMultipleIdentityCapabilities(icaps); if (icaps.size() < 1) throw MESSAGES.illegalStateNoIdentityCapability(this); XCapability icap = (XCapability) icaps.get(0); identityCapability = icap.adapt(XIdentityCapability.class); // Validate the capabilities for (Capability cap : getCaplist(null)) { try { ((XCapability) cap).validate(); } catch (RuntimeException ex) { throw new ResourceValidationException(MESSAGES.validationInvalidCapability(cap), ex, cap); } } // Validate the requirements for (Requirement req : getReqlist(null)) { try { ((XRequirement) req).validate(); } catch (RuntimeException ex) { throw new ResourceValidationException(MESSAGES.validationInvalidRequirement(req), ex, req); } } } @Override public List<Capability> getCapabilities(String namespace) { ensureImmutable(); return Collections.unmodifiableList(getCaplist(namespace)); } @Override public List<Requirement> getRequirements(String namespace) { ensureImmutable(); return Collections.unmodifiableList(getReqlist(namespace)); } @Override public XIdentityCapability getIdentityCapability() { return identityCapability; } private List<Capability> getCaplist(String namespace) { List<Capability> caplist = capabilities.get(namespace); if (caplist == null) { caplist = new ArrayList<Capability>(); capabilities.put(namespace, caplist); } return caplist; } private List<Requirement> getReqlist(String namespace) { List<Requirement> reqlist = requirements.get(namespace); if (reqlist == null) { reqlist = new ArrayList<Requirement>(); requirements.put(namespace, reqlist); } return reqlist; } @Override public String toString() { XIdentityCapability id = identityCapability; String idstr = (id != null ? id.getName() + ":" + id.getVersion() : "anonymous"); return getClass().getSimpleName() + "[" + idstr + "]"; } }