Skip to content

Commit 813df82

Browse files
committed
Fix ModuleCapability/ModuleRequirement hashcode/equals according to API
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.
1 parent c95032b commit 813df82

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleCapability.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
import java.util.Collections;
1717
import java.util.HashMap;
1818
import java.util.Map;
19+
import java.util.Objects;
1920
import org.osgi.framework.namespace.NativeNamespace;
2021
import org.osgi.framework.wiring.BundleCapability;
22+
import org.osgi.resource.Capability;
2123

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

3437
ModuleCapability(String namespace, Map<String, String> directives, Map<String, Object> attributes,
3538
ModuleRevision revision) {
@@ -93,4 +96,26 @@ public ModuleRevision getResource() {
9396
public String toString() {
9497
return namespace + ModuleContainer.toString(attributes, false) + ModuleContainer.toString(directives, true);
9598
}
99+
100+
@Override
101+
public int hashCode() {
102+
if (hashCode != 0) {
103+
return hashCode;
104+
}
105+
return hashCode = Objects.hash(namespace, directives, attributes, revision);
106+
}
107+
108+
@Override
109+
public boolean equals(Object obj) {
110+
if (this == obj) {
111+
return true;
112+
}
113+
if (obj instanceof Capability) {
114+
Capability other = (Capability) obj;
115+
return Objects.equals(revision, other.getResource()) && Objects.equals(namespace, other.getNamespace())
116+
&& Objects.equals(directives, other.getDirectives())
117+
&& Objects.equals(attributes, other.getAttributes());
118+
}
119+
return false;
120+
}
96121
}

bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.EnumSet;
2626
import java.util.HashMap;
2727
import java.util.HashSet;
28+
import java.util.IdentityHashMap;
2829
import java.util.List;
2930
import java.util.Map;
3031
import java.util.Set;
@@ -1084,7 +1085,7 @@ public static void store(ModuleDatabase moduleDatabase, DataOutputStream out, bo
10841085
}
10851086

10861087
// Now persist all the Strings
1087-
Map<Object, Integer> objectTable = new HashMap<>();
1088+
Map<Object, Integer> objectTable = new IdentityHashMap<>();
10881089
allStrings.remove(null);
10891090
out.writeInt(allStrings.size());
10901091
for (String string : allStrings) {

bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRequirement.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import java.util.HashMap;
1717
import java.util.Map;
18+
import java.util.Objects;
1819
import org.eclipse.osgi.internal.container.Capabilities;
1920
import org.eclipse.osgi.internal.framework.FilterImpl;
2021
import org.osgi.framework.InvalidSyntaxException;
@@ -24,6 +25,7 @@
2425
import org.osgi.framework.wiring.BundleCapability;
2526
import org.osgi.framework.wiring.BundleRequirement;
2627
import org.osgi.resource.Namespace;
28+
import org.osgi.resource.Requirement;
2729

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

4245
ModuleRequirement(String namespace, Map<String, String> directives, Map<String, ?> attributes,
4346
ModuleRevision revision) {
@@ -153,4 +156,26 @@ ModuleRequirement getOriginal() {
153156
}
154157
}
155158

159+
@Override
160+
public int hashCode() {
161+
if (hashCode != 0) {
162+
return hashCode;
163+
}
164+
return hashCode = Objects.hash(namespace, directives, attributes, revision);
165+
}
166+
167+
@Override
168+
public boolean equals(Object obj) {
169+
if (this == obj) {
170+
return true;
171+
}
172+
if (obj instanceof Requirement) {
173+
Requirement other = (Requirement) obj;
174+
return Objects.equals(revision, other.getResource()) && Objects.equals(namespace, other.getNamespace())
175+
&& Objects.equals(directives, other.getDirectives())
176+
&& Objects.equals(attributes, other.getAttributes());
177+
}
178+
return false;
179+
}
180+
156181
}

0 commit comments

Comments
 (0)