Skip to content

Commit

Permalink
add an equivalence proxy for AnnotationInstance
Browse files Browse the repository at this point in the history
An equivalence proxy is like an equivalence key (that is, its `equals()`
and `hashCode()` implement equivalence instead of equality), but it also
holds and provides access to the original (delegate) object.
  • Loading branch information
Ladicek committed Nov 27, 2023
1 parent 4074e82 commit a41de09
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
7 changes: 7 additions & 0 deletions core/src/main/java/org/jboss/jandex/AnnotationInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,11 @@ public int equivalenceHashCode() {
result = 31 * result + Arrays.hashCode(values);
return result;
}

/**
* Returns an {@linkplain AnnotationInstanceEquivalenceProxy equivalence proxy} for this annotation instance.
*/
public AnnotationInstanceEquivalenceProxy createEquivalenceProxy() {
return new AnnotationInstanceEquivalenceProxy(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.jboss.jandex;

import java.util.Objects;

/**
* Holds an {@link AnnotationInstance} and implements equality and hash code as equivalence.
* <p>
* When using equivalence proxies, it is usually a mistake to obtain
* the {@linkplain AnnotationInstance#target() target} of the delegate annotation instance.
* <p>
* <b>Thread-Safety</b>
* </p>
* This class is immutable and can be shared between threads without safe
* publication.
*
* @see AnnotationInstance#equivalentTo(AnnotationInstance)
* @see AnnotationInstance#equivalenceHashCode()
*/
public final class AnnotationInstanceEquivalenceProxy {
private final AnnotationInstance annotation;

AnnotationInstanceEquivalenceProxy(AnnotationInstance annotation) {
this.annotation = Objects.requireNonNull(annotation);
}

public AnnotationInstance get() {
return annotation;
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
return annotation.equivalentTo(((AnnotationInstanceEquivalenceProxy) o).annotation);
}

@Override
public int hashCode() {
return annotation.equivalenceHashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.IOException;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationInstanceEquivalenceProxy;
import org.jboss.jandex.Index;
import org.jboss.jandex.test.util.IndexingUtil;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -51,5 +52,19 @@ private void testEqualityEquivalence(Index index) {
assertFalse(foo2.equivalentTo(bar));

assertEquals(foo.equivalenceHashCode(), foo2.equivalenceHashCode());

AnnotationInstanceEquivalenceProxy fooEquiv = foo.createEquivalenceProxy();
AnnotationInstanceEquivalenceProxy foo2Equiv = foo2.createEquivalenceProxy();
AnnotationInstanceEquivalenceProxy barEquiv = bar.createEquivalenceProxy();

assertNotNull(fooEquiv);
assertNotNull(foo2Equiv);
assertNotNull(barEquiv);

assertEquals(fooEquiv, foo2Equiv);
assertNotEquals(fooEquiv, barEquiv);
assertNotEquals(foo2Equiv, barEquiv);

assertEquals(fooEquiv.hashCode(), foo2Equiv.hashCode());
}
}

0 comments on commit a41de09

Please sign in to comment.