diff --git a/src/main/java/org/apache/accumulo/access/Authorizations.java b/src/main/java/org/apache/accumulo/access/Authorizations.java index f1b1640..2695f25 100644 --- a/src/main/java/org/apache/accumulo/access/Authorizations.java +++ b/src/main/java/org/apache/accumulo/access/Authorizations.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.Set; +import java.util.TreeSet; /** * An immutable collection of authorization strings. @@ -58,9 +59,12 @@ public int hashCode() { return authorizations.hashCode(); } + /** + * @return a String containing the sorted, comma-separated set of authorizations + */ @Override public String toString() { - return authorizations.toString(); + return new TreeSet<>(authorizations).toString(); } public static Authorizations of(String... authorizations) { diff --git a/src/test/java/org/apache/accumulo/access/AccessExpressionTest.java b/src/test/java/org/apache/accumulo/access/AccessExpressionTest.java index c41fdd8..cd9b671 100644 --- a/src/test/java/org/apache/accumulo/access/AccessExpressionTest.java +++ b/src/test/java/org/apache/accumulo/access/AccessExpressionTest.java @@ -35,7 +35,6 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; -import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; @@ -48,24 +47,22 @@ public void testGetAuthorizations() { // is the expected authorization in the expression var testData = new ArrayList>(); - testData.add(List.of("", "")); - testData.add(List.of("a", "a")); - testData.add(List.of("(a)", "a")); - testData.add(List.of("Z|M|A", "A,M,Z")); - testData.add(List.of("Z&M&A", "A,M,Z")); - testData.add(List.of("(Y|B|Y)&(Z|A|Z)", "A,B,Y,Z")); - testData.add(List.of("(Y&B&Y)|(Z&A&Z)", "A,B,Y,Z")); - testData.add(List.of("(A1|B1)&((A1|B2)&(B2|C1))", "A1,B1,B2,C1")); + testData.add(List.of("", "[]")); + testData.add(List.of("a", "[a]")); + testData.add(List.of("(a)", "[a]")); + testData.add(List.of("Z|M|A", "[A, M, Z]")); + testData.add(List.of("Z&M&A", "[A, M, Z]")); + testData.add(List.of("(Y|B|Y)&(Z|A|Z)", "[A, B, Y, Z]")); + testData.add(List.of("(Y&B&Y)|(Z&A&Z)", "[A, B, Y, Z]")); + testData.add(List.of("(A1|B1)&((A1|B2)&(B2|C1))", "[A1, B1, B2, C1]")); for (var testCase : testData) { assertEquals(2, testCase.size()); var expression = testCase.get(0); var expected = testCase.get(1); - var actual = AccessExpression.of(expression).getAuthorizations().asSet().stream().sorted() - .collect(Collectors.joining(",")); + var actual = AccessExpression.of(expression).getAuthorizations().toString(); assertEquals(expected, actual); - actual = AccessExpression.of(expression.getBytes(UTF_8)).getAuthorizations().asSet().stream() - .sorted().collect(Collectors.joining(",")); + actual = AccessExpression.of(expression.getBytes(UTF_8)).getAuthorizations().toString(); assertEquals(expected, actual); } @@ -224,4 +221,14 @@ public void testSpecificationDocumentation() throws IOException, URISyntaxExcept assertFalse(specLinesFromAbnfFile.isEmpty()); // make sure we didn't just compare nothing assertEquals(specLinesFromAbnfFile, specLinesFromMarkdownFile); } + + @Test + public void authSetIsImmutable() { + Authorizations auths = AccessExpression.of("A&B").getAuthorizations(); + var authSet = auths.asSet(); + assertThrows(UnsupportedOperationException.class, () -> authSet.add("C"), + "Set returned by asSet should be immutable"); + assertThrows(UnsupportedOperationException.class, () -> authSet.remove("A"), + "Set returned by asSet should be immutable"); + } }