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

Reply via email to