I've merge in some optimizations we have in Karaf, mainly: - a CapabilitySet / SimpleFilter, both coming originally from the felix framework - a StringArrayMap to optimize the memory used by large amounts of resources - a ResourceBuilder that can be used to create full Resource from manifest headers
2018-04-20 9:43 GMT+02:00 Carsten Ziegeler <[email protected]>: > Capability and requirement must be immutable (according to the javadoc) > so a setResource sounds dangerous. > > Could we maybe have a jira issue tracking the changes/additions to utils? > > Regards > > Carsten > > > David Bosschaert wrote > > Hi Guillaume, > > > > The setResource() came from the implementation used by the Felix > > BundleRepository, which I used as a starting point. > > I'll have a look if we can remove it. > > > > BTW +1 on a shareable Resource Implementation. There is one in the Felix > > BundleRepository already which might be a starting point? > > > > Best regards, > > > > David > > > > On 20 April 2018 at 08:01, 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. > >> 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 > >> > > > -- > Carsten Ziegeler > Adobe Research Switzerland > [email protected] > -- ------------------------ Guillaume Nodet
