Skip to content

Commit

Permalink
Fix ModuleCapability/ModuleRequirement hashcode/equals according to API
Browse files Browse the repository at this point in the history
The API of Capability/Requirement currently defines the contract to be:
This Capability/Requirement is equal to another Capability/Requirement
if they have the same namespace, directives and attributes and are
declared by the same resource.

But Equinox currently implements hashCode/equals in terms of object
identity.
  • Loading branch information
laeubi committed May 3, 2024
1 parent 6ba55ab commit 72e3806
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.osgi.framework.namespace.NativeNamespace;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.resource.Capability;

/**
* An implementation of {@link BundleCapability}.
Expand All @@ -30,6 +32,7 @@ public final class ModuleCapability implements BundleCapability {
private final Map<String, Object> attributes;
private final Map<String, Object> transientAttrs;
private final ModuleRevision revision;
private transient int hashCode;

ModuleCapability(String namespace, Map<String, String> directives, Map<String, Object> attributes,
ModuleRevision revision) {
Expand Down Expand Up @@ -93,4 +96,26 @@ public ModuleRevision getResource() {
public String toString() {
return namespace + ModuleContainer.toString(attributes, false) + ModuleContainer.toString(directives, true);
}

@Override
public int hashCode() {
if (hashCode != 0) {
return hashCode;
}
return hashCode = Objects.hash(namespace, directives, attributes, revision);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Capability) {
Capability other = (Capability) obj;
return Objects.equals(revision, other.getResource()) && Objects.equals(namespace, other.getNamespace())
&& Objects.equals(directives, other.getDirectives())
&& Objects.equals(attributes, other.getAttributes());
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -1084,7 +1085,7 @@ public static void store(ModuleDatabase moduleDatabase, DataOutputStream out, bo
}

// Now persist all the Strings
Map<Object, Integer> objectTable = new HashMap<>();
Map<Object, Integer> objectTable = new IdentityHashMap<>();
allStrings.remove(null);
out.writeInt(allStrings.size());
for (String string : allStrings) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.eclipse.osgi.internal.container.Capabilities;
import org.eclipse.osgi.internal.framework.FilterImpl;
import org.osgi.framework.InvalidSyntaxException;
Expand All @@ -24,6 +25,7 @@
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.resource.Namespace;
import org.osgi.resource.Requirement;

/**
* An implementation of {@link BundleRequirement}. This requirement implements
Expand All @@ -38,6 +40,7 @@ public class ModuleRequirement implements BundleRequirement {
private final Map<String, String> directives;
private final Map<String, Object> attributes;
private final ModuleRevision revision;
private transient int hashCode;

ModuleRequirement(String namespace, Map<String, String> directives, Map<String, ?> attributes,
ModuleRevision revision) {
Expand Down Expand Up @@ -153,4 +156,26 @@ ModuleRequirement getOriginal() {
}
}

@Override
public int hashCode() {
if (hashCode != 0) {
return hashCode;
}
return hashCode = Objects.hash(namespace, directives, attributes, revision);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Requirement) {
Requirement other = (Requirement) obj;
return Objects.equals(revision, other.getResource()) && Objects.equals(namespace, other.getNamespace())
&& Objects.equals(directives, other.getDirectives())
&& Objects.equals(attributes, other.getAttributes());
}
return false;
}

}

0 comments on commit 72e3806

Please sign in to comment.