I think the reason for the thread save-ness is that it is used in the ServiceRegistry where we don't hold a lock. For the resolver it is only accessed inside a synchronized. Maybe we could make it configurable whether it needs to be thread save or not?
regards, Karl On Fri, Apr 20, 2018 at 2:47 PM, Guillaume Nodet <[email protected]> wrote: > While they should be similar to the framework one, I saw two differences in > the CapabilitySet: the framework implementation is thread safe, while the > one I added is not (I don't recall if I removed it for perfs or if it was > added later in the framework though). Also, the framework one is using > BundleCapability / BundleRequirement while the other one uses the > Capability / Requirement interfaces. > But there's definitely some overlap. > The header parsing could be reused too. > > 2018-04-20 10:56 GMT+02:00 Karl Pauls <[email protected]>: > >> On Fri, Apr 20, 2018 at 9:01 AM, Guillaume Nodet <[email protected]> >> wrote: >> > I'm going to work on those classes too then, in order to reuse them >> instead >> > of the one we have in Karaf. They are actually closer to the ones in the >> > framework. It also includes a CapabilitySet / SimpleFilter which speeds >> > things a lot when using the resolver. >> >> I was hoping we could maybe reuse them in the framework as well. >> >> regards, >> >> Karl >> >> > One point though, I'm not sure I like the setResource(xx) on the >> Capability >> > / Requirement, because there's a risk of running out of sync with >> > Resource#getCapabilities / getRequirements. So I wonder if a final >> > Resource field would be more appropriate. >> > >> > I think a Resource implementation would be interesting too. >> > >> > 2018-04-20 8:34 GMT+02:00 <[email protected]>: >> > >> >> Author: davidb >> >> Date: Fri Apr 20 06:34:25 2018 >> >> New Revision: 1829625 >> >> >> >> URL: http://svn.apache.org/viewvc?rev=1829625&view=rev >> >> Log: >> >> Improvements to the OSGi Capability and Requirement implementations >> >> >> >> These come from the Apache Sling Whitenboard Feature Model project. >> Merged >> >> with Felix Utils to increase sharing across projects. >> >> >> >> Added: >> >> felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> capabilities/ >> >> AbstractCapabilityRequirement.java >> >> Modified: >> >> felix/trunk/utils/pom.xml >> >> felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/CapabilityImpl.java >> >> felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/RequirementImpl.java >> >> felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> capabilities/ >> >> CapabilityImplTest.java >> >> felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> capabilities/ >> >> RequirementImplTest.java >> >> >> >> Modified: felix/trunk/utils/pom.xml >> >> URL: http://svn.apache.org/viewvc/felix/trunk/utils/pom.xml?rev= >> >> 1829625&r1=1829624&r2=1829625&view=diff >> >> ============================================================ >> >> ================== >> >> --- felix/trunk/utils/pom.xml (original) >> >> +++ felix/trunk/utils/pom.xml Fri Apr 20 06:34:25 2018 >> >> @@ -27,7 +27,7 @@ >> >> <modelVersion>4.0.0</modelVersion> >> >> <name>Apache Felix Utils</name> >> >> <description>Utility classes for OSGi.</description> >> >> - <version>1.10.5-SNAPSHOT</version> >> >> + <version>1.11.0-SNAPSHOT</version> >> >> <artifactId>org.apache.felix.utils</artifactId> >> >> >> >> <scm> >> >> >> >> Added: felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/AbstractCapabilityRequirement.java >> >> URL: http://svn.apache.org/viewvc/felix/trunk/utils/src/main/ >> >> java/org/apache/felix/utils/capabilities/AbstractCapabilityRequirement. >> >> java?rev=1829625&view=auto >> >> ============================================================ >> >> ================== >> >> --- felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> capabilities/ >> >> AbstractCapabilityRequirement.java (added) >> >> +++ felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> capabilities/ >> >> AbstractCapabilityRequirement.java Fri Apr 20 06:34:25 2018 >> >> @@ -0,0 +1,135 @@ >> >> +/* >> >> + * 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.felix.utils.capabilities; >> >> + >> >> +import org.osgi.resource.Resource; >> >> + >> >> +import java.util.Collections; >> >> +import java.util.HashMap; >> >> +import java.util.Map; >> >> + >> >> +abstract class AbstractCapabilityRequirement { >> >> + >> >> + /** The namespace. Required. */ >> >> + private final String namespace; >> >> + >> >> + /** Optional resource. */ >> >> + private volatile Resource resource; >> >> + >> >> + /** Optional attributes. Never null. */ >> >> + private final Map<String, Object> attributes; >> >> + >> >> + /** Optional attributes. Never null. */ >> >> + private final Map<String, String> directives; >> >> + >> >> + AbstractCapabilityRequirement(final String ns, final Map<String, >> >> Object> attrs, final Map<String, String> dirs, final Resource res) { >> >> + if ( ns == null ) { >> >> + throw new IllegalArgumentException("Namespace must not be >> >> null."); >> >> + } >> >> + namespace = ns; >> >> + attributes = attrs == null >> >> + ? Collections.<String, Object>emptyMap() >> >> + : Collections.unmodifiableMap(new HashMap<String, >> >> Object>(attrs)); >> >> + directives = dirs == null >> >> + ? Collections.<String,String>emptyMap() >> >> + : Collections.unmodifiableMap(new >> >> HashMap<String,String>(dirs)); >> >> + resource = res; >> >> + } >> >> + >> >> + /** >> >> + * Return the namespace. >> >> + * @return The namespace. This is never @{code null}. >> >> + */ >> >> + public String getNamespace() { >> >> + return namespace; >> >> + } >> >> + >> >> + /** >> >> + * Return the attributes. >> >> + * @return The attributes, might be empty. >> >> + */ >> >> + public Map<String, Object> getAttributes() { >> >> + return attributes; >> >> + } >> >> + >> >> + /** >> >> + * Return the directives. >> >> + * @return The directives, might be empty. >> >> + */ >> >> + public Map<String, String> getDirectives() { >> >> + return directives; >> >> + } >> >> + >> >> + /** >> >> + * Return the resource. >> >> + * @return The resource or @{code null}. >> >> + */ >> >> + public Resource getResource() { >> >> + return resource; >> >> + } >> >> + >> >> + /** >> >> + * Set the resource associated with this requirement. >> >> + * >> >> + * @param res The resource. >> >> + */ >> >> + public void setResource(Resource res) { >> >> + resource = res; >> >> + } >> >> + >> >> + @Override >> >> + public int hashCode() { >> >> + final int prime = 31; >> >> + int result = 1; >> >> + result = prime * result + attributes.hashCode(); >> >> + result = prime * result + directives.hashCode(); >> >> + result = prime * result + namespace.hashCode(); >> >> + >> >> + if (resource != null) >> >> + result = prime * result + resource.hashCode(); >> >> + >> >> + return result; >> >> + } >> >> + >> >> + @Override >> >> + public boolean equals(Object obj) { >> >> + if (this == obj) >> >> + return true; >> >> + if (obj == null) >> >> + return false; >> >> + if (getClass() != obj.getClass()) >> >> + return false; >> >> + AbstractCapabilityRequirement other = ( >> AbstractCapabilityRequirement) >> >> obj; >> >> + if (!namespace.equals(other.namespace)) >> >> + return false; >> >> + if (!attributes.equals(other.attributes)) >> >> + return false; >> >> + if (!directives.equals(other.directives)) >> >> + return false; >> >> + if (resource == null) { >> >> + return other.resource == null; >> >> + } else { >> >> + return resource.equals(other.resource); >> >> + } >> >> + } >> >> + >> >> + @Override >> >> + public String toString() { >> >> + return getClass().getSimpleName() + " [resource=" + resource + >> ", >> >> namespace=" + namespace + ", attributes=" + attributes >> >> + + ", directives=" + directives + "]"; >> >> + } >> >> +} >> >> >> >> Modified: felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/CapabilityImpl.java >> >> URL: http://svn.apache.org/viewvc/felix/trunk/utils/src/main/ >> >> java/org/apache/felix/utils/capabilities/CapabilityImpl. >> >> java?rev=1829625&r1=1829624&r2=1829625&view=diff >> >> ============================================================ >> >> ================== >> >> --- felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/CapabilityImpl.java (original) >> >> +++ felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/CapabilityImpl.java Fri Apr 20 06:34:25 2018 >> >> @@ -1,161 +1,59 @@ >> >> /* >> >> - * 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 >> >> + * 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 >> >> + * 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. >> >> + * 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.felix.utils.capabilities; >> >> >> >> import org.osgi.resource.Capability; >> >> import org.osgi.resource.Resource; >> >> >> >> -import java.util.Collections; >> >> import java.util.Map; >> >> >> >> /** >> >> * Implementation of the OSGi Capability interface. >> >> */ >> >> -public class CapabilityImpl implements Capability >> >> -{ >> >> - private final String namespace; >> >> - private final Map<String, Object> attributes; >> >> - private final Map<String, String> directives; >> >> - private volatile Resource resource; >> >> - >> >> +public class CapabilityImpl extends AbstractCapabilityRequirement >> >> implements Capability { >> >> /** >> >> - * Create a capability. >> >> - * >> >> + * Create a capability that is not associated with a resource. >> >> + * @param res The resource associated with the capability. May be >> >> null. >> >> * @param ns The namespace of the capability. >> >> * @param attrs The attributes of the capability. >> >> * @param dirs The directives of the capability. >> >> */ >> >> - public CapabilityImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs) >> >> - { >> >> + public CapabilityImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs) { >> >> this(ns, attrs, dirs, null); >> >> } >> >> >> >> /** >> >> * Create a capability. >> >> - * >> >> * @param ns The namespace of the capability. >> >> * @param attrs The attributes of the capability. >> >> * @param dirs The directives of the capability. >> >> - * @param res The resource associated with the capability. >> >> - */ >> >> - public CapabilityImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs, Resource res) >> >> - { >> >> - namespace = ns; >> >> - attributes = Collections.unmodifiableMap(attrs); >> >> - directives = Collections.unmodifiableMap(dirs); >> >> - resource = res; >> >> - } >> >> - >> >> - /** >> >> - * Returns the namespace of this capability. >> >> - * >> >> - * @return The namespace of this capability. >> >> - */ >> >> - public String getNamespace() >> >> - { >> >> - return namespace; >> >> - } >> >> - >> >> - /** >> >> - * Returns the attributes of this capability. >> >> - * >> >> - * @return An unmodifiable map of attribute names to attribute >> values >> >> for >> >> - * this capability, or an empty map if this capability has >> no >> >> - * attributes. >> >> - */ >> >> - public Map<String, Object> getAttributes() >> >> - { >> >> - return attributes; >> >> - } >> >> - >> >> - /** >> >> - * Returns the directives of this capability. >> >> - * >> >> - * @return An unmodifiable map of directive names to directive >> values >> >> for >> >> - * this capability, or an empty map if this capability has >> no >> >> - * directives. >> >> + * @param res The resource associated with the capability. May be >> >> null. >> >> */ >> >> - public Map<String, String> getDirectives() >> >> - { >> >> - return directives; >> >> + public CapabilityImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs, Resource res) { >> >> + super(ns, attrs, dirs, res); >> >> } >> >> >> >> /** >> >> - * Returns the resource declaring this capability. >> >> - * >> >> - * @return The resource declaring this capability. >> >> + * Create a capability based on an existing capability, providing >> the >> >> resource. >> >> + * The namespace, attributes and directives are copied from the >> >> provided capability. >> >> + * @param capability The capability to base the new requirement on. >> >> + * @param resource The resource to be associated with the >> capability >> >> */ >> >> - public Resource getResource() >> >> - { >> >> - return resource; >> >> - } >> >> - >> >> - /** >> >> - * Sets the resource associated with this capability. >> >> - * >> >> - * @param res The resource. >> >> - */ >> >> - public void setResource(Resource res) >> >> - { >> >> - resource = res; >> >> - } >> >> - >> >> - @Override >> >> - public int hashCode() { >> >> - final int prime = 31; >> >> - int result = 1; >> >> - result = prime * result + ((attributes == null) ? 0 : >> >> attributes.hashCode()); >> >> - result = prime * result + ((directives == null) ? 0 : >> >> directives.hashCode()); >> >> - result = prime * result + ((namespace == null) ? 0 : >> >> namespace.hashCode()); >> >> - result = prime * result + ((resource == null) ? 0 : >> >> resource.hashCode()); >> >> - return result; >> >> - } >> >> - >> >> - @Override >> >> - public boolean equals(Object obj) { >> >> - if (this == obj) >> >> - return true; >> >> - if (obj == null) >> >> - return false; >> >> - if (getClass() != obj.getClass()) >> >> - return false; >> >> - CapabilityImpl other = (CapabilityImpl) obj; >> >> - if (attributes == null) { >> >> - if (other.attributes != null) >> >> - return false; >> >> - } else if (!attributes.equals(other.attributes)) >> >> - return false; >> >> - if (directives == null) { >> >> - if (other.directives != null) >> >> - return false; >> >> - } else if (!directives.equals(other.directives)) >> >> - return false; >> >> - if (namespace == null) { >> >> - if (other.namespace != null) >> >> - return false; >> >> - } else if (!namespace.equals(other.namespace)) >> >> - return false; >> >> - if (resource == null) { >> >> - if (other.resource != null) >> >> - return false; >> >> - } else if (!resource.equals(other.resource)) >> >> - return false; >> >> - return true; >> >> + public CapabilityImpl(Resource resource, Capability capability) { >> >> + this(capability.getNamespace(), capability.getAttributes(), >> >> capability.getDirectives(), resource); >> >> } >> >> } >> >> >> >> Modified: felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/RequirementImpl.java >> >> URL: http://svn.apache.org/viewvc/felix/trunk/utils/src/main/ >> >> java/org/apache/felix/utils/capabilities/RequirementImpl. >> >> java?rev=1829625&r1=1829624&r2=1829625&view=diff >> >> ============================================================ >> >> ================== >> >> --- felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/RequirementImpl.java (original) >> >> +++ felix/trunk/utils/src/main/java/org/apache/felix/utils/ >> >> capabilities/RequirementImpl.java Fri Apr 20 06:34:25 2018 >> >> @@ -1,20 +1,18 @@ >> >> /* >> >> - * 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 >> >> + * 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 >> >> + * 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. >> >> + * 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.felix.utils.capabilities; >> >> >> >> @@ -28,154 +26,51 @@ import java.util.Map; >> >> /** >> >> * Implementation of the OSGi Requirement interface. >> >> */ >> >> -public class RequirementImpl implements Requirement >> >> -{ >> >> - private final String namespace; >> >> - private final Map<String, Object> attributes; >> >> - private final Map<String, String> directives; >> >> - private volatile Resource resource; >> >> - >> >> +public class RequirementImpl extends AbstractCapabilityRequirement >> >> implements Requirement { >> >> /** >> >> - * Create a requirement. >> >> - * >> >> + * Create a requirement that is not associated with a resource. >> >> + * @param res The resource associated with the requirement. >> >> * @param ns The namespace of the requirement. >> >> * @param attrs The attributes of the requirement. >> >> * @param dirs The directives of the requirement. >> >> */ >> >> - public RequirementImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs) >> >> - { >> >> + public RequirementImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs) { >> >> this(ns, attrs, dirs, null); >> >> } >> >> >> >> /** >> >> * Create a requirement. >> >> - * >> >> * @param ns The namespace of the requirement. >> >> * @param attrs The attributes of the requirement. >> >> * @param dirs The directives of the requirement. >> >> * @param res The resource associated with the requirement. >> >> */ >> >> - public RequirementImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs, Resource res) >> >> - { >> >> - namespace = ns; >> >> - attributes = attrs; >> >> - directives = dirs; >> >> - resource = res; >> >> - } >> >> - >> >> - /** >> >> - * Create a requirement with a namespace and a filter. >> >> - * >> >> - * This is a convenience method that creates a requirement with >> >> - * an empty attributes map and a single 'filter' directive. >> >> - * @param ns The namespace for the requirement. >> >> - * @param filter The filter. >> >> - */ >> >> - public RequirementImpl(String ns, String filter) >> >> - { >> >> - this(ns, Collections.<String, Object>emptyMap(), >> >> - filter == null ? Collections.<String, String> emptyMap() : >> >> - Collections.singletonMap(Namespace.REQUIREMENT_FILTER_ >> DIRECTIVE, >> >> filter)); >> >> + public RequirementImpl(String ns, Map<String, Object> attrs, >> >> Map<String, String> dirs, Resource res) { >> >> + super(ns, attrs, dirs, res); >> >> } >> >> >> >> /** >> >> - * Returns the namespace of this requirement. >> >> - * >> >> - * @return The namespace of this requirement. >> >> + * Create a requirement with a namespace and a filter. >> >> + * >> >> + * This is a convenience method that creates a requirement with >> >> + * an empty attributes map and a single 'filter' directive. >> >> + * @param ns The namespace for the requirement. >> >> + * @param filter The filter. >> >> + */ >> >> + public RequirementImpl(String ns, String filter) >> >> + { >> >> + this(ns, Collections.<String, Object>emptyMap(), >> >> + filter == null ? Collections.<String, String> emptyMap() : >> >> + Collections.singletonMap(Namespace.REQUIREMENT_FILTER_ >> DIRECTIVE, >> >> filter)); >> >> + } >> >> + >> >> + /** >> >> + * Create a requirement based on an existing requirement, providing >> >> the resource. >> >> + * The namespace, attributes and directives are copied from the >> >> provided requirement. >> >> + * @param requirement The requirement to base the new requirement >> on. >> >> + * @param resource The resource to be associated with the >> requirement >> >> */ >> >> - public String getNamespace() >> >> - { >> >> - return namespace; >> >> - } >> >> - >> >> - /** >> >> - * Returns the attributes of this requirement. >> >> - * >> >> - * <p> >> >> - * Requirement attributes have no specified semantics and are >> >> considered >> >> - * extra user defined information. >> >> - * >> >> - * @return An unmodifiable map of attribute names to attribute >> values >> >> for >> >> - * this requirement, or an empty map if this requirement >> has >> >> no >> >> - * attributes. >> >> - */ >> >> - public Map<String, Object> getAttributes() >> >> - { >> >> - return Collections.unmodifiableMap(attributes); >> >> - } >> >> - >> >> - /** >> >> - * Returns the directives of this requirement. >> >> - * >> >> - * @return An unmodifiable map of directive names to directive >> values >> >> for >> >> - * this requirement, or an empty map if this requirement >> has >> >> no >> >> - * directives. >> >> - */ >> >> - public Map<String, String> getDirectives() >> >> - { >> >> - return Collections.unmodifiableMap(directives); >> >> - } >> >> - >> >> - /** >> >> - * Returns the resource declaring this requirement. >> >> - * >> >> - * @return The resource declaring this requirement. This can be >> >> {@code null} >> >> - * if this requirement is synthesized. >> >> - */ >> >> - public Resource getResource() >> >> - { >> >> - return resource; >> >> - } >> >> - >> >> - /** >> >> - * Set the resource associated with this requirement. >> >> - * >> >> - * @param res The resource. >> >> - */ >> >> - public void setResource(Resource res) { >> >> - resource = res; >> >> - } >> >> - >> >> - @Override >> >> - public int hashCode() { >> >> - final int prime = 31; >> >> - int result = 1; >> >> - result = prime * result + ((attributes == null) ? 0 : >> >> attributes.hashCode()); >> >> - result = prime * result + ((directives == null) ? 0 : >> >> directives.hashCode()); >> >> - result = prime * result + ((namespace == null) ? 0 : >> >> namespace.hashCode()); >> >> - result = prime * result + ((resource == null) ? 0 : >> >> resource.hashCode()); >> >> - return result; >> >> - } >> >> - >> >> - @Override >> >> - public boolean equals(Object obj) { >> >> - if (this == obj) >> >> - return true; >> >> - if (obj == null) >> >> - return false; >> >> - if (getClass() != obj.getClass()) >> >> - return false; >> >> - RequirementImpl other = (RequirementImpl) obj; >> >> - if (attributes == null) { >> >> - if (other.attributes != null) >> >> - return false; >> >> - } else if (!attributes.equals(other.attributes)) >> >> - return false; >> >> - if (directives == null) { >> >> - if (other.directives != null) >> >> - return false; >> >> - } else if (!directives.equals(other.directives)) >> >> - return false; >> >> - if (namespace == null) { >> >> - if (other.namespace != null) >> >> - return false; >> >> - } else if (!namespace.equals(other.namespace)) >> >> - return false; >> >> - if (resource == null) { >> >> - if (other.resource != null) >> >> - return false; >> >> - } else if (!resource.equals(other.resource)) >> >> - return false; >> >> - return true; >> >> + public RequirementImpl(Resource resource, Requirement requirement) >> { >> >> + this(requirement.getNamespace(), requirement.getAttributes(), >> >> requirement.getDirectives(), resource); >> >> } >> >> } >> >> >> >> Modified: felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> >> capabilities/CapabilityImplTest.java >> >> URL: http://svn.apache.org/viewvc/felix/trunk/utils/src/test/ >> >> java/org/apache/felix/utils/capabilities/CapabilityImplTest.java?rev= >> >> 1829625&r1=1829624&r2=1829625&view=diff >> >> ============================================================ >> >> ================== >> >> --- felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> capabilities/CapabilityImplTest.java >> >> (original) >> >> +++ felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> capabilities/CapabilityImplTest.java >> >> Fri Apr 20 06:34:25 2018 >> >> @@ -57,4 +57,18 @@ public class CapabilityImplTest extends >> >> assertFalse(c1.equals(c3)); >> >> assertFalse(c1.hashCode() == c3.hashCode()); >> >> } >> >> + >> >> + public void testCopyCapability() { >> >> + CapabilityImpl c = new CapabilityImpl("x.y.z", >> >> + Collections.<String, Object>singletonMap("a", 123), >> >> + Collections.<String, String>singletonMap("x", "y"), >> >> + Mockito.mock(Resource.class)); >> >> + >> >> + Resource res2 = Mockito.mock(Resource.class); >> >> + CapabilityImpl c2 = new CapabilityImpl(res2, c); >> >> + assertFalse("Should not be equal, the resources are different", >> >> c.equals(c2)); >> >> + >> >> + c.setResource(res2); >> >> + assertEquals(c, c2); >> >> + } >> >> } >> >> >> >> Modified: felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> >> capabilities/RequirementImplTest.java >> >> URL: http://svn.apache.org/viewvc/felix/trunk/utils/src/test/ >> >> java/org/apache/felix/utils/capabilities/RequirementImplTest.java?rev= >> >> 1829625&r1=1829624&r2=1829625&view=diff >> >> ============================================================ >> >> ================== >> >> --- felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> capabilities/RequirementImplTest.java >> >> (original) >> >> +++ felix/trunk/utils/src/test/java/org/apache/felix/utils/ >> capabilities/RequirementImplTest.java >> >> Fri Apr 20 06:34:25 2018 >> >> @@ -69,4 +69,18 @@ public class RequirementImplTest extends >> >> assertEquals(0, r2.getAttributes().size()); >> >> assertEquals(0, r2.getDirectives().size()); >> >> } >> >> + >> >> + public void testCopyRequirement() { >> >> + RequirementImpl r = new RequirementImpl("x.y.z", >> >> + Collections.<String, Object>singletonMap("a", 123), >> >> + Collections.<String, String>singletonMap("x", "y"), >> >> + Mockito.mock(Resource.class)); >> >> + >> >> + Resource res2 = Mockito.mock(Resource.class); >> >> + RequirementImpl r2 = new RequirementImpl(res2, r); >> >> + assertFalse("Should not be equal, the resources are different", >> >> r.equals(r2)); >> >> + >> >> + r.setResource(res2); >> >> + assertEquals(r, r2); >> >> + } >> >> } >> >> >> >> >> >> >> > >> > >> > -- >> > ------------------------ >> > Guillaume Nodet >> >> >> >> -- >> Karl Pauls >> [email protected] >> > > > > -- > ------------------------ > Guillaume Nodet -- Karl Pauls [email protected]
