Deprecate mutable API of PrimitiveSet.
Some package-private methods that are not used anymore in the package can be removed completely:
- newPrimitiveSetWithAnnotations: Now annotations can only be set with the builder API.
- makeImmutable: Immutable objects can now only be created with the builder API. And we can make the isMutable variable final.
Also, annotate getPrimary with @Nullable, and add a test that shows that indeed null is returned when no primary is set.
PiperOrigin-RevId: 455380275
Change-Id: If208f869b0418e14c653001f5f0263c0b136db6d
diff --git a/src/main/java/com/google/crypto/tink/BUILD.bazel b/src/main/java/com/google/crypto/tink/BUILD.bazel
index 254e4c5..30d7107 100644
--- a/src/main/java/com/google/crypto/tink/BUILD.bazel
+++ b/src/main/java/com/google/crypto/tink/BUILD.bazel
@@ -464,6 +464,7 @@
"//src/main/java/com/google/crypto/tink/annotations:alpha",
"//src/main/java/com/google/crypto/tink/monitoring:monitoring_annotations",
"//src/main/java/com/google/crypto/tink/subtle:hex",
+ "@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_errorprone_error_prone_annotations",
],
)
@@ -478,6 +479,7 @@
"//src/main/java/com/google/crypto/tink/annotations:alpha-android",
"//src/main/java/com/google/crypto/tink/monitoring:monitoring_annotations-android",
"//src/main/java/com/google/crypto/tink/subtle:hex-android",
+ "@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_errorprone_error_prone_annotations",
],
)
diff --git a/src/main/java/com/google/crypto/tink/PrimitiveSet.java b/src/main/java/com/google/crypto/tink/PrimitiveSet.java
index 1ab1bdd..9a8595b 100644
--- a/src/main/java/com/google/crypto/tink/PrimitiveSet.java
+++ b/src/main/java/com/google/crypto/tink/PrimitiveSet.java
@@ -31,6 +31,7 @@
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import javax.annotation.Nullable;
/**
* A container class for a set of primitives -- implementations of cryptographic primitives offered
@@ -168,6 +169,7 @@
}
/** @return the entry with the primary primitive. */
+ @Nullable
public Entry<P> getPrimary() {
return primary;
}
@@ -207,8 +209,9 @@
private Entry<P> primary;
private final Class<P> primitiveClass;
private final MonitoringAnnotations annotations;
- private boolean isMutable;
+ private final boolean isMutable;
+ @Deprecated
private PrimitiveSet(Class<P> primitiveClass) {
this.primitives = new ConcurrentHashMap<>();
this.primitiveClass = primitiveClass;
@@ -216,13 +219,6 @@
this.isMutable = true;
}
- private PrimitiveSet(MonitoringAnnotations annotations, Class<P> primitiveClass) {
- this.primitives = new ConcurrentHashMap<>();
- this.primitiveClass = primitiveClass;
- this.annotations = annotations;
- this.isMutable = true;
- }
-
/** Creates an immutable PrimitiveSet. It is used by the Builder.*/
private PrimitiveSet(ConcurrentMap<Prefix, List<Entry<P>>> primitives,
Entry<P> primary, MonitoringAnnotations annotations, Class<P> primitiveClass) {
@@ -233,30 +229,22 @@
this.isMutable = false;
}
+ /**
+ * Creates a new mutable PrimitiveSet.
+ *
+ * @deprecated use {@link Builder} instead.
+ */
+ @Deprecated
public static <P> PrimitiveSet<P> newPrimitiveSet(Class<P> primitiveClass) {
return new PrimitiveSet<P>(primitiveClass);
}
- // Only used by KeysetHandle.
- static <P> PrimitiveSet<P> newPrimitiveSetWithAnnotations(
- MonitoringAnnotations annotations, Class<P> primitiveClass) {
- return new PrimitiveSet<P>(annotations, primitiveClass);
- }
-
- /**
- * Makes the object immutable.
- *
- * <p>Calls to the methods {@link setPrimary} or {@link addPrimitive} after calling this method
- * will throw an {@code IllegalStateException}.
- */
- void makeImmutable() {
- this.isMutable = false;
- }
-
/** Sets given Entry {@code primary} as the primary one.
*
- * @throws IllegalStateException if {@link makeImmutable} has been called before.
+ * @throws IllegalStateException if object has been created by the {@link Builder}.
+ * @deprecated use {@link Builder.addPrimaryPrimitive} instead.
*/
+ @Deprecated
public void setPrimary(final Entry<P> primary) {
if (!isMutable) {
throw new IllegalStateException("setPrimary cannot be called on an immutable primitive set");
@@ -280,8 +268,10 @@
*
* @return the added {@link Entry}
*
- * @throws IllegalStateException if {@link makeImmutable} has been called before.
+ * @throws IllegalStateException if object has been created by the {@link Builder}.
+ * @deprecated use {@link Builder.addPrimitive} or {@link Builder.addPrimaryPrimitive} instead.
*/
+ @Deprecated
public Entry<P> addPrimitive(final P primitive, Keyset.Key key)
throws GeneralSecurityException {
if (!isMutable) {
diff --git a/src/test/java/com/google/crypto/tink/PrimitiveSetTest.java b/src/test/java/com/google/crypto/tink/PrimitiveSetTest.java
index 047181d..ac05dc3 100644
--- a/src/test/java/com/google/crypto/tink/PrimitiveSetTest.java
+++ b/src/test/java/com/google/crypto/tink/PrimitiveSetTest.java
@@ -70,7 +70,7 @@
}
@Test
- public void testBasicFunctionality() throws Exception {
+ public void testBasicFunctionalityWithDeprecatedMutableInterface() throws Exception {
PrimitiveSet<Mac> pset = PrimitiveSet.newPrimitiveSet(Mac.class);
Key key1 =
Key.newBuilder()
@@ -92,24 +92,7 @@
.setStatus(KeyStatusType.ENABLED)
.setOutputPrefixType(OutputPrefixType.LEGACY)
.build();
- PrimitiveSet.Entry<Mac> lastEntry = pset.addPrimitive(new DummyMac1(), key3);
-
- // After the primitive set has been built, it is preferable to call makeImmutable() to make it
- // immutable.
- pset.makeImmutable();
-
- // Check that setPrimary and addPrimitive now throw an Exception.
- assertThrows(IllegalStateException.class, () -> pset.setPrimary(lastEntry));
- assertThrows(
- IllegalStateException.class,
- () ->
- pset.addPrimitive(
- new DummyMac1(),
- Key.newBuilder()
- .setKeyId(4)
- .setStatus(KeyStatusType.ENABLED)
- .setOutputPrefixType(OutputPrefixType.TINK)
- .build()));
+ pset.addPrimitive(new DummyMac1(), key3);
assertThat(pset.getAll()).hasSize(3);
@@ -261,6 +244,21 @@
}
@Test
+ public void testNoPrimary_getPrimaryReturnsNull() throws Exception {
+ Key key =
+ Key.newBuilder()
+ .setKeyId(1)
+ .setStatus(KeyStatusType.ENABLED)
+ .setOutputPrefixType(OutputPrefixType.TINK)
+ .build();
+ PrimitiveSet<Mac> pset =
+ PrimitiveSet.newBuilder(Mac.class)
+ .addPrimitive(new DummyMac1(), key)
+ .build();
+ assertThat(pset.getPrimary()).isNull();
+ }
+
+ @Test
public void testEntryGetKeyFormatToString() throws Exception {
PrimitiveSet<Mac> pset = PrimitiveSet.newPrimitiveSet(Mac.class);
Key key1 =
@@ -286,15 +284,11 @@
public void testWithAnnotations() throws Exception {
MonitoringAnnotations annotations =
MonitoringAnnotations.newBuilder().add("name", "value").build();
- PrimitiveSet<Mac> pset = PrimitiveSet.newPrimitiveSetWithAnnotations(annotations, Mac.class);
+ PrimitiveSet<Mac> pset = PrimitiveSet.newBuilder(Mac.class).setAnnotations(annotations).build();
HashMap<String, String> expected = new HashMap<>();
expected.put("name", "value");
assertThat(pset.getAnnotations().toMap()).containsExactlyEntriesIn(expected);
-
- PrimitiveSet<Mac> pset2 =
- PrimitiveSet.newBuilder(Mac.class).setAnnotations(annotations).build();
- assertThat(pset2.getAnnotations().toMap()).containsExactlyEntriesIn(expected);
}
@Test