This is an automated email from the ASF dual-hosted git repository.
dlmarion pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo-access.git
The following commit(s) were added to refs/heads/main by this push:
new 35655cb Separate API and impl (#91)
35655cb is described below
commit 35655cb7c8880a67c4b5ae0ad42dfcb9af7db707
Author: Dave Marion <[email protected]>
AuthorDate: Thu Dec 18 08:16:21 2025 -0500
Separate API and impl (#91)
Implemented java module feature.
Moved impl classes to their own package.
Closes #81
---
.github/workflows/maven.yaml | 2 --
README.md | 7 +++--
pom.xml | 14 +++++-----
src/build/ci/find-unapproved-public.sh | 32 ----------------------
src/it/antlr4-example/pom.xml | 6 ++--
.../antlr/AccessExpressionAntlrEvaluator.java | 2 +-
src/main/java/module-info.java | 21 ++++++++++++++
.../apache/accumulo/access/AccessEvaluator.java | 7 +++--
.../apache/accumulo/access/AccessExpression.java | 25 ++++++++---------
.../accumulo/access/ParsedAccessExpression.java | 12 ++++----
.../access/{ => impl}/AccessEvaluatorImpl.java | 27 ++++++++++--------
.../access/{ => impl}/AccessExpressionImpl.java | 12 ++++----
.../accumulo/access/{ => impl}/ByteUtils.java | 2 +-
.../accumulo/access/{ => impl}/BytesWrapper.java | 6 ++--
.../{ => impl}/MultiAccessEvaluatorImpl.java | 20 ++++++++++----
.../{ => impl}/ParsedAccessExpressionImpl.java | 21 +++++++-------
.../access/{ => impl}/ParserEvaluator.java | 22 ++++++++++++---
.../accumulo/access/{ => impl}/Tokenizer.java | 26 ++++++++++--------
.../access/{ => tests}/AccessEvaluatorTest.java | 14 ++++++----
.../{ => tests}/AccessExpressionBenchmark.java | 8 ++++--
.../access/{ => tests}/AccessExpressionTest.java | 5 +++-
.../access/{ => tests}/AuthorizationTest.java | 3 +-
.../{ => tests}/ParsedAccessExpressionTest.java | 4 ++-
23 files changed, 165 insertions(+), 133 deletions(-)
diff --git a/.github/workflows/maven.yaml b/.github/workflows/maven.yaml
index 72e32d7..db0722e 100644
--- a/.github/workflows/maven.yaml
+++ b/.github/workflows/maven.yaml
@@ -50,8 +50,6 @@ jobs:
run: src/build/ci/find-unapproved-chars.sh
- name: Check for unapproved JUnit API usage
run: src/build/ci/find-unapproved-junit.sh
- - name: Check for unapproved public classes
- run: src/build/ci/find-unapproved-public.sh
- name: Build with Maven (Fast Build)
timeout-minutes: 20
run: mvn -B -V -e -ntp "-Dstyle.color=always" clean package
dependency:resolve -DskipTests -DskipFormat -DverifyFormat
diff --git a/README.md b/README.md
index cccfc26..702fad9 100644
--- a/README.md
+++ b/README.md
@@ -62,8 +62,9 @@ To run
[AccessExample](src/test/java/example/AccessExample.java)
```
mvn clean package
-CLASSPATH=$(ls target/accumulo-access-*.jar) java
src/test/java/example/AccessExample.java
-CLASSPATH=$(ls target/accumulo-access-*.jar) java
src/test/java/example/AccessExample.java RED BLUE
+
+java --module-path=$(ls target/accumulo-access-*.jar)
--add-modules=accumulo.access src/test/java/example/AccessExample.java
+java --module-path=$(ls target/accumulo-access-*.jar)
--add-modules=accumulo.access src/test/java/example/AccessExample.java RED BLUE
```
Note that `data6` is always returned, because it has no access expression. And
@@ -73,7 +74,7 @@ To run
[ParseExamples](src/test/java/example/ParseExamples.java)
```
mvn clean package
-CLASSPATH=$(ls target/accumulo-access-*.jar) java
src/test/java/example/ParseExamples.java
+java --module-path=$(ls target/accumulo-access-*.jar)
--add-modules=accumulo.access src/test/java/example/ParseExamples.java
```
diff --git a/pom.xml b/pom.xml
index 9bdc161..5fb4358 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,9 +88,9 @@
</ciManagement>
<properties>
<extraTestArgs>--add-opens java.base/java.lang=ALL-UNNAMED --add-opens
java.base/java.util=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED --add-opens
java.management/java.lang.management=ALL-UNNAMED --add-opens
java.management/sun.management=ALL-UNNAMED --add-opens
java.base/java.security=ALL-UNNAMED --add-opens
java.base/java.lang.reflect=ALL-UNNAMED --add-opens
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.ut [...]
- <maven.compiler.release>11</maven.compiler.release>
- <maven.compiler.source>11</maven.compiler.source>
- <maven.compiler.target>11</maven.compiler.target>
+ <maven.compiler.release>17</maven.compiler.release>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
<maven.javadoc.failOnWarnings>true</maven.javadoc.failOnWarnings>
<maven.site.deploy.skip>true</maven.site.deploy.skip>
<maven.site.skip>true</maven.site.skip>
@@ -113,7 +113,7 @@
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
- <version>4.8.3</version>
+ <version>4.9.3</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -289,7 +289,7 @@
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
- <version>4.8.3.1</version>
+ <version>4.9.3.0</version>
<configuration>
<excludeFilterFile>src/build/ci/spotbugs-exclude.xml</excludeFilterFile>
<xmlOutput>true</xmlOutput>
@@ -414,7 +414,7 @@
</checkstyleRules>
<violationSeverity>warning</violationSeverity>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
- <excludes>**/jmh_generated/</excludes>
+ <excludes>**/jmh_generated/,**/module-info.java</excludes>
</configuration>
<dependencies>
<dependency>
@@ -778,7 +778,7 @@
<arguments>
<argument>-classpath</argument>
<classpath />
-
<argument>org.apache.accumulo.access.AccessExpressionBenchmark</argument>
+
<argument>org.apache.accumulo.access.tests.AccessExpressionBenchmark</argument>
</arguments>
</configuration>
</execution>
diff --git a/src/build/ci/find-unapproved-public.sh
b/src/build/ci/find-unapproved-public.sh
deleted file mode 100755
index 6a31983..0000000
--- a/src/build/ci/find-unapproved-public.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#! /usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-count=$(grep -E "public.*(class|interface|enum|record)"
src/main/java/org/apache/accumulo/access/*.java |
- grep -v " interface AccessEvaluator " |
- grep -v " class AccessExpression " |
- grep -v " class ParsedAccessExpression " |
- grep -v " enum ExpressionType " |
- grep -v " class Authorizations " |
- grep -c -v " class InvalidAccessExpressionException ")
-
-if [[ 0 -ne $count ]]; then
- echo "$count unapproved public classes found"
- exit 1
-fi
diff --git a/src/it/antlr4-example/pom.xml b/src/it/antlr4-example/pom.xml
index e14db9b..c1ace65 100644
--- a/src/it/antlr4-example/pom.xml
+++ b/src/it/antlr4-example/pom.xml
@@ -31,9 +31,9 @@
<version>@project.version@</version>
<name>Apache Accumulo Access Antlr4 Example</name>
<properties>
- <maven.compiler.release>11</maven.compiler.release>
- <maven.compiler.source>11</maven.compiler.source>
- <maven.compiler.target>11</maven.compiler.target>
+ <maven.compiler.release>17</maven.compiler.release>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
<maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
diff --git
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
b/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
index 5d20d8b..7120150 100644
---
a/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
+++
b/src/it/antlr4-example/src/test/java/org/apache/accumulo/access/grammar/antlr/AccessExpressionAntlrEvaluator.java
@@ -36,7 +36,7 @@ import
org.apache.accumulo.access.grammars.AccessExpressionParser.And_operatorCo
import
org.apache.accumulo.access.grammars.AccessExpressionParser.Or_expressionContext;
import
org.apache.accumulo.access.grammars.AccessExpressionParser.Or_operatorContext;
-public class AccessExpressionAntlrEvaluator implements AccessEvaluator {
+public class AccessExpressionAntlrEvaluator {
private class Entity {
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000..537dec8
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module accumulo.access {
+ exports org.apache.accumulo.access;
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/accumulo/access/AccessEvaluator.java
b/src/main/java/org/apache/accumulo/access/AccessEvaluator.java
index 6857343..ea0fb2c 100644
--- a/src/main/java/org/apache/accumulo/access/AccessEvaluator.java
+++ b/src/main/java/org/apache/accumulo/access/AccessEvaluator.java
@@ -20,6 +20,9 @@ package org.apache.accumulo.access;
import java.util.Collection;
+import org.apache.accumulo.access.impl.AccessEvaluatorImpl;
+import org.apache.accumulo.access.impl.MultiAccessEvaluatorImpl;
+
/**
* This class is used to decide if an entity with a given set of
authorizations can access
* subsequent access expressions.
@@ -52,7 +55,7 @@ import java.util.Collection;
* @see <a href="https://github.com/apache/accumulo-access">Accumulo Access
Documentation</a>
* @since 1.0.0
*/
-public interface AccessEvaluator {
+public sealed interface AccessEvaluator permits AccessEvaluatorImpl,
MultiAccessEvaluatorImpl {
/**
* @param accessExpression for this parameter a valid access expression is
expected.
@@ -149,7 +152,7 @@ public interface AccessEvaluator {
*
*/
static AccessEvaluator of(Collection<Authorizations> authorizationSets) {
- return new MultiAccessEvaluatorImpl(authorizationSets);
+ return MultiAccessEvaluatorImpl.of(authorizationSets);
}
/**
diff --git a/src/main/java/org/apache/accumulo/access/AccessExpression.java
b/src/main/java/org/apache/accumulo/access/AccessExpression.java
index e9d8ab5..cf32670 100644
--- a/src/main/java/org/apache/accumulo/access/AccessExpression.java
+++ b/src/main/java/org/apache/accumulo/access/AccessExpression.java
@@ -25,6 +25,13 @@ import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Predicate;
+import org.apache.accumulo.access.impl.AccessEvaluatorImpl;
+import org.apache.accumulo.access.impl.AccessExpressionImpl;
+import org.apache.accumulo.access.impl.BytesWrapper;
+import org.apache.accumulo.access.impl.ParsedAccessExpressionImpl;
+import org.apache.accumulo.access.impl.ParserEvaluator;
+import org.apache.accumulo.access.impl.Tokenizer;
+
/**
* This class offers the ability to operate on access expressions.
*
@@ -94,16 +101,12 @@ import java.util.function.Predicate;
* @see <a href="https://github.com/apache/accumulo-access">Accumulo Access
Documentation</a>
* @since 1.0.0
*/
-public abstract class AccessExpression implements Serializable {
+public sealed abstract class AccessExpression implements Serializable
+ permits AccessExpressionImpl, ParsedAccessExpression {
private static final long serialVersionUID = 1L;
- /*
- * This is package private so that it can not be extended by classes outside
of this package and
- * create a mutable implementation. In this package all implementations that
extends are
- * immutable.
- */
- AccessExpression() {}
+ protected AccessExpression() {}
/**
* @return the expression that was used to create this object.
@@ -249,13 +252,7 @@ public abstract class AccessExpression implements
Serializable {
*/
public static void findAuthorizations(byte[] expression, Consumer<String>
authorizationConsumer)
throws InvalidAccessExpressionException {
- var bytesWrapper = ParserEvaluator.lookupWrappers.get();
- Predicate<Tokenizer.AuthorizationToken> atp = authToken -> {
- bytesWrapper.set(authToken.data, authToken.start, authToken.len);
- authorizationConsumer.accept(AccessEvaluatorImpl.unescape(bytesWrapper));
- return true;
- };
- ParserEvaluator.parseAccessExpression(expression, atp, atp);
+ ParserEvaluator.findAuthorizations(expression, authorizationConsumer);
}
/**
diff --git
a/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java
b/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java
index a51e8ab..5928b1b 100644
--- a/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java
+++ b/src/main/java/org/apache/accumulo/access/ParsedAccessExpression.java
@@ -20,6 +20,8 @@ package org.apache.accumulo.access;
import java.util.List;
+import org.apache.accumulo.access.impl.ParsedAccessExpressionImpl;
+
/**
* Instances of this class are immutable and wrap a verified access expression
and a parse tree for
* the access expression. To create an instance of this class call
@@ -28,16 +30,12 @@ import java.util.List;
*
* @since 1.0.0
*/
-public abstract class ParsedAccessExpression extends AccessExpression {
+public sealed abstract class ParsedAccessExpression extends AccessExpression
+ permits ParsedAccessExpressionImpl {
private static final long serialVersionUID = 1L;
- /*
- * This is package private so that it can not be extended by classes outside
of this package and
- * create a mutable implementation. In this package all implementations that
extends are
- * immutable.
- */
- ParsedAccessExpression() {}
+ protected ParsedAccessExpression() {}
/**
* @since 1.0.0
diff --git a/src/main/java/org/apache/accumulo/access/AccessEvaluatorImpl.java
b/src/main/java/org/apache/accumulo/access/impl/AccessEvaluatorImpl.java
similarity index 84%
rename from src/main/java/org/apache/accumulo/access/AccessEvaluatorImpl.java
rename to src/main/java/org/apache/accumulo/access/impl/AccessEvaluatorImpl.java
index 11f3f05..d5189c2 100644
--- a/src/main/java/org/apache/accumulo/access/AccessEvaluatorImpl.java
+++ b/src/main/java/org/apache/accumulo/access/impl/AccessEvaluatorImpl.java
@@ -16,33 +16,38 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.accumulo.access.ByteUtils.BACKSLASH;
-import static org.apache.accumulo.access.ByteUtils.QUOTE;
-import static org.apache.accumulo.access.ByteUtils.isQuoteOrSlash;
-import static org.apache.accumulo.access.ByteUtils.isQuoteSymbol;
+import static org.apache.accumulo.access.impl.ByteUtils.BACKSLASH;
+import static org.apache.accumulo.access.impl.ByteUtils.QUOTE;
+import static org.apache.accumulo.access.impl.ByteUtils.isQuoteOrSlash;
+import static org.apache.accumulo.access.impl.ByteUtils.isQuoteSymbol;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
-//this class is intentionally package private and should never be made public
-final class AccessEvaluatorImpl implements AccessEvaluator {
+import org.apache.accumulo.access.AccessEvaluator;
+import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.Authorizations;
+import org.apache.accumulo.access.InvalidAccessExpressionException;
+
+public final class AccessEvaluatorImpl implements AccessEvaluator {
+
private final Predicate<BytesWrapper> authorizedPredicate;
/**
* Create an AccessEvaluatorImpl using an Authorizer object
*/
- AccessEvaluatorImpl(Authorizer authorizationChecker) {
+ public AccessEvaluatorImpl(Authorizer authorizationChecker) {
this.authorizedPredicate = auth ->
authorizationChecker.isAuthorized(unescape(auth));
}
/**
* Create an AccessEvaluatorImpl using a collection of authorizations
*/
- AccessEvaluatorImpl(Authorizations authorizations) {
+ public AccessEvaluatorImpl(Authorizations authorizations) {
var authsSet = authorizations.asSet();
final Set<BytesWrapper> authBytes = new HashSet<>(authsSet.size());
for (String authorization : authsSet) {
@@ -56,7 +61,7 @@ final class AccessEvaluatorImpl implements AccessEvaluator {
authorizedPredicate = authBytes::contains;
}
- static String unescape(BytesWrapper auth) {
+ public static String unescape(BytesWrapper auth) {
int escapeCharCount = 0;
for (int i = 0; i < auth.length(); i++) {
byte b = auth.byteAt(i);
@@ -102,7 +107,7 @@ final class AccessEvaluatorImpl implements AccessEvaluator {
* @param shouldQuote true to wrap escaped authorization in quotes
* @return escaped authorization string
*/
- static byte[] escape(byte[] auth, boolean shouldQuote) {
+ public static byte[] escape(byte[] auth, boolean shouldQuote) {
int escapeCount = 0;
for (byte value : auth) {
diff --git a/src/main/java/org/apache/accumulo/access/AccessExpressionImpl.java
b/src/main/java/org/apache/accumulo/access/impl/AccessExpressionImpl.java
similarity index 85%
rename from src/main/java/org/apache/accumulo/access/AccessExpressionImpl.java
rename to
src/main/java/org/apache/accumulo/access/impl/AccessExpressionImpl.java
index 914e14a..9f60e33 100644
--- a/src/main/java/org/apache/accumulo/access/AccessExpressionImpl.java
+++ b/src/main/java/org/apache/accumulo/access/impl/AccessExpressionImpl.java
@@ -16,27 +16,29 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.util.concurrent.atomic.AtomicReference;
-final class AccessExpressionImpl extends AccessExpression {
+import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.ParsedAccessExpression;
- private static final long serialVersionUID = 1L;
+public final class AccessExpressionImpl extends AccessExpression {
+ private static final long serialVersionUID = 1L;
public static final AccessExpression EMPTY = new AccessExpressionImpl("");
private final String expression;
private final AtomicReference<ParsedAccessExpression> parseTreeRef = new
AtomicReference<>();
- AccessExpressionImpl(String expression) {
+ public AccessExpressionImpl(String expression) {
validate(expression);
this.expression = expression;
}
- AccessExpressionImpl(byte[] expression) {
+ public AccessExpressionImpl(byte[] expression) {
validate(expression);
this.expression = new String(expression, UTF_8);
}
diff --git a/src/main/java/org/apache/accumulo/access/ByteUtils.java
b/src/main/java/org/apache/accumulo/access/impl/ByteUtils.java
similarity index 97%
rename from src/main/java/org/apache/accumulo/access/ByteUtils.java
rename to src/main/java/org/apache/accumulo/access/impl/ByteUtils.java
index 53dfc57..8f3c209 100644
--- a/src/main/java/org/apache/accumulo/access/ByteUtils.java
+++ b/src/main/java/org/apache/accumulo/access/impl/ByteUtils.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
/**
* This class exists to avoid repeat conversions from byte to char as well as
to provide helper
diff --git a/src/main/java/org/apache/accumulo/access/BytesWrapper.java
b/src/main/java/org/apache/accumulo/access/impl/BytesWrapper.java
similarity index 94%
rename from src/main/java/org/apache/accumulo/access/BytesWrapper.java
rename to src/main/java/org/apache/accumulo/access/impl/BytesWrapper.java
index f9b53bb..e034f70 100644
--- a/src/main/java/org/apache/accumulo/access/BytesWrapper.java
+++ b/src/main/java/org/apache/accumulo/access/impl/BytesWrapper.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.checkFromIndexSize;
@@ -24,7 +24,7 @@ import static java.util.Objects.checkIndex;
import java.util.Arrays;
-final class BytesWrapper implements Comparable<BytesWrapper> {
+public final class BytesWrapper implements Comparable<BytesWrapper> {
private byte[] data;
private int offset;
@@ -40,7 +40,7 @@ final class BytesWrapper implements Comparable<BytesWrapper> {
set(data, 0, data.length);
}
- byte byteAt(int i) {
+ public byte byteAt(int i) {
return data[offset + checkIndex(i, length)];
}
diff --git
a/src/main/java/org/apache/accumulo/access/MultiAccessEvaluatorImpl.java
b/src/main/java/org/apache/accumulo/access/impl/MultiAccessEvaluatorImpl.java
similarity index 71%
rename from
src/main/java/org/apache/accumulo/access/MultiAccessEvaluatorImpl.java
rename to
src/main/java/org/apache/accumulo/access/impl/MultiAccessEvaluatorImpl.java
index 067310f..8c268f8 100644
--- a/src/main/java/org/apache/accumulo/access/MultiAccessEvaluatorImpl.java
+++
b/src/main/java/org/apache/accumulo/access/impl/MultiAccessEvaluatorImpl.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -24,10 +24,20 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-class MultiAccessEvaluatorImpl implements AccessEvaluator {
- final List<AccessEvaluatorImpl> evaluators;
+import org.apache.accumulo.access.AccessEvaluator;
+import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.Authorizations;
+import org.apache.accumulo.access.InvalidAccessExpressionException;
- MultiAccessEvaluatorImpl(Collection<Authorizations> authorizationSets) {
+public final class MultiAccessEvaluatorImpl implements AccessEvaluator {
+
+ public static AccessEvaluator of(Collection<Authorizations>
authorizationSets) {
+ return new MultiAccessEvaluatorImpl(authorizationSets);
+ }
+
+ private final List<AccessEvaluator> evaluators;
+
+ private MultiAccessEvaluatorImpl(Collection<Authorizations>
authorizationSets) {
evaluators = new ArrayList<>(authorizationSets.size());
for (Authorizations authorizations : authorizationSets) {
evaluators.add(new AccessEvaluatorImpl(authorizations));
@@ -41,7 +51,7 @@ class MultiAccessEvaluatorImpl implements AccessEvaluator {
@Override
public boolean canAccess(byte[] accessExpression) throws
InvalidAccessExpressionException {
- for (AccessEvaluatorImpl evaluator : evaluators) {
+ for (AccessEvaluator evaluator : evaluators) {
if (!evaluator.canAccess(accessExpression)) {
return false;
}
diff --git
a/src/main/java/org/apache/accumulo/access/ParsedAccessExpressionImpl.java
b/src/main/java/org/apache/accumulo/access/impl/ParsedAccessExpressionImpl.java
similarity index 87%
rename from
src/main/java/org/apache/accumulo/access/ParsedAccessExpressionImpl.java
rename to
src/main/java/org/apache/accumulo/access/impl/ParsedAccessExpressionImpl.java
index efb8cfc..99f6464 100644
--- a/src/main/java/org/apache/accumulo/access/ParsedAccessExpressionImpl.java
+++
b/src/main/java/org/apache/accumulo/access/impl/ParsedAccessExpressionImpl.java
@@ -16,22 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.accumulo.access.ByteUtils.AND_OPERATOR;
-import static org.apache.accumulo.access.ByteUtils.OR_OPERATOR;
-import static org.apache.accumulo.access.ByteUtils.isAndOrOperator;
import static
org.apache.accumulo.access.ParsedAccessExpression.ExpressionType.AND;
import static
org.apache.accumulo.access.ParsedAccessExpression.ExpressionType.AUTHORIZATION;
import static
org.apache.accumulo.access.ParsedAccessExpression.ExpressionType.OR;
+import static org.apache.accumulo.access.impl.ByteUtils.AND_OPERATOR;
+import static org.apache.accumulo.access.impl.ByteUtils.OR_OPERATOR;
+import static org.apache.accumulo.access.impl.ByteUtils.isAndOrOperator;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
-// This class is intentionally package private
-final class ParsedAccessExpressionImpl extends ParsedAccessExpression {
+import org.apache.accumulo.access.ParsedAccessExpression;
+
+public final class ParsedAccessExpressionImpl extends ParsedAccessExpression {
private static final long serialVersionUID = 1L;
@@ -44,9 +45,9 @@ final class ParsedAccessExpressionImpl extends
ParsedAccessExpression {
private final AtomicReference<String> stringExpression = new
AtomicReference<>(null);
- static final ParsedAccessExpression EMPTY = new ParsedAccessExpressionImpl();
+ public static final ParsedAccessExpression EMPTY = new
ParsedAccessExpressionImpl();
- ParsedAccessExpressionImpl(byte operator, byte[] expression, int offset, int
length,
+ private ParsedAccessExpressionImpl(byte operator, byte[] expression, int
offset, int length,
List<ParsedAccessExpression> children) {
if (children.isEmpty()) {
throw new IllegalArgumentException("Must have children with an
operator");
@@ -66,7 +67,7 @@ final class ParsedAccessExpressionImpl extends
ParsedAccessExpression {
this.children = List.copyOf(children);
}
- ParsedAccessExpressionImpl(byte[] expression, int offset, int length) {
+ private ParsedAccessExpressionImpl(byte[] expression, int offset, int
length) {
this.type = AUTHORIZATION;
this.expression = expression;
this.offset = offset;
@@ -108,7 +109,7 @@ final class ParsedAccessExpressionImpl extends
ParsedAccessExpression {
return children;
}
- static ParsedAccessExpression parseExpression(byte[] expression) {
+ public static ParsedAccessExpression parseExpression(byte[] expression) {
if (expression.length == 0) {
return ParsedAccessExpressionImpl.EMPTY;
}
diff --git a/src/main/java/org/apache/accumulo/access/ParserEvaluator.java
b/src/main/java/org/apache/accumulo/access/impl/ParserEvaluator.java
similarity index 86%
rename from src/main/java/org/apache/accumulo/access/ParserEvaluator.java
rename to src/main/java/org/apache/accumulo/access/impl/ParserEvaluator.java
index 3ec67c1..2df624c 100644
--- a/src/main/java/org/apache/accumulo/access/ParserEvaluator.java
+++ b/src/main/java/org/apache/accumulo/access/impl/ParserEvaluator.java
@@ -16,16 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
-import static org.apache.accumulo.access.ByteUtils.isAndOrOperator;
+import static org.apache.accumulo.access.impl.ByteUtils.isAndOrOperator;
+import java.util.function.Consumer;
import java.util.function.Predicate;
+import org.apache.accumulo.access.InvalidAccessExpressionException;
+
/**
* Code for parsing and evaluating an access expression at the same time.
*/
-final class ParserEvaluator {
+public final class ParserEvaluator {
static final byte OPEN_PAREN = (byte) '(';
static final byte CLOSE_PAREN = (byte) ')';
@@ -37,7 +40,18 @@ final class ParserEvaluator {
private static final ThreadLocal<Tokenizer> tokenizers =
ThreadLocal.withInitial(() -> new Tokenizer(EMPTY));
- static boolean parseAccessExpression(byte[] expression,
+ public static void findAuthorizations(byte[] expression, Consumer<String>
authorizationConsumer)
+ throws InvalidAccessExpressionException {
+ var bytesWrapper = ParserEvaluator.lookupWrappers.get();
+ Predicate<Tokenizer.AuthorizationToken> atp = authToken -> {
+ bytesWrapper.set(authToken.data, authToken.start, authToken.len);
+ authorizationConsumer.accept(AccessEvaluatorImpl.unescape(bytesWrapper));
+ return true;
+ };
+ ParserEvaluator.parseAccessExpression(expression, atp, atp);
+ }
+
+ public static boolean parseAccessExpression(byte[] expression,
Predicate<Tokenizer.AuthorizationToken> authorizedPredicate,
Predicate<Tokenizer.AuthorizationToken> shortCircuitPredicate) {
var tokenizer = tokenizers.get();
diff --git a/src/main/java/org/apache/accumulo/access/Tokenizer.java
b/src/main/java/org/apache/accumulo/access/impl/Tokenizer.java
similarity index 87%
rename from src/main/java/org/apache/accumulo/access/Tokenizer.java
rename to src/main/java/org/apache/accumulo/access/impl/Tokenizer.java
index 2b11c92..da5b6ab 100644
--- a/src/main/java/org/apache/accumulo/access/Tokenizer.java
+++ b/src/main/java/org/apache/accumulo/access/impl/Tokenizer.java
@@ -16,21 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.impl;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.accumulo.access.ByteUtils.isBackslashSymbol;
-import static org.apache.accumulo.access.ByteUtils.isQuoteOrSlash;
-import static org.apache.accumulo.access.ByteUtils.isQuoteSymbol;
+import static org.apache.accumulo.access.impl.ByteUtils.isBackslashSymbol;
+import static org.apache.accumulo.access.impl.ByteUtils.isQuoteOrSlash;
+import static org.apache.accumulo.access.impl.ByteUtils.isQuoteSymbol;
import java.util.stream.IntStream;
+import org.apache.accumulo.access.InvalidAccessExpressionException;
+
/**
* A simple wrapper around a byte array that keeps some state and provides
high level operations to
* the {@link ParserEvaluator} class. The purpose of this class is to make
{@link ParserEvaluator}
* as simple and easy to understand as possible while still being performant.
*/
-final class Tokenizer {
+public final class Tokenizer {
private static final boolean[] validAuthChars = new boolean[256];
@@ -45,7 +47,7 @@ final class Tokenizer {
"_-:./".chars().forEach(c -> validAuthChars[c] = true);
}
- static boolean isValidAuthChar(byte b) {
+ public static boolean isValidAuthChar(byte b) {
return validAuthChars[0xff & b];
}
@@ -54,10 +56,10 @@ final class Tokenizer {
private final AuthorizationToken authorizationToken = new
AuthorizationToken();
- static class AuthorizationToken {
- byte[] data;
- int start;
- int len;
+ public static class AuthorizationToken {
+ public byte[] data;
+ public int start;
+ public int len;
}
Tokenizer(byte[] expression) {
@@ -65,7 +67,7 @@ final class Tokenizer {
authorizationToken.data = expression;
}
- public void reset(byte[] expression) {
+ void reset(byte[] expression) {
this.expression = expression;
authorizationToken.data = expression;
this.index = 0;
@@ -102,7 +104,7 @@ final class Tokenizer {
return expression[index];
}
- public byte[] expression() {
+ byte[] expression() {
return expression;
}
diff --git a/src/test/java/org/apache/accumulo/access/AccessEvaluatorTest.java
b/src/test/java/org/apache/accumulo/access/tests/AccessEvaluatorTest.java
similarity index 94%
rename from src/test/java/org/apache/accumulo/access/AccessEvaluatorTest.java
rename to
src/test/java/org/apache/accumulo/access/tests/AccessEvaluatorTest.java
index b71ccb5..35a0d5c 100644
--- a/src/test/java/org/apache/accumulo/access/AccessEvaluatorTest.java
+++ b/src/test/java/org/apache/accumulo/access/tests/AccessEvaluatorTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.tests;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.accumulo.access.AccessExpression.quote;
@@ -34,6 +34,12 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.apache.accumulo.access.AccessEvaluator;
+import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.Authorizations;
+import org.apache.accumulo.access.InvalidAccessExpressionException;
+import org.apache.accumulo.access.impl.AccessEvaluatorImpl;
+import org.apache.accumulo.access.impl.BytesWrapper;
import org.junit.jupiter.api.Test;
import com.google.gson.Gson;
@@ -41,6 +47,8 @@ import com.google.gson.reflect.TypeToken;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+@SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"},
+ justification = "Field is written by Gson")
public class AccessEvaluatorTest {
enum ExpectedResult {
@@ -71,8 +79,6 @@ public class AccessEvaluatorTest {
}
}
- @SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"},
- justification = "Field is written by Gson")
@Test
public void runTestCases() throws IOException {
List<TestDataSet> testData = readTestData();
@@ -100,8 +106,6 @@ public class AccessEvaluatorTest {
}
- @SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"},
- justification = "Field is written by Gson")
private static void runTestCases(TestDataSet testSet, AccessEvaluator
evaluator) {
assertFalse(testSet.tests.isEmpty());
diff --git
a/src/test/java/org/apache/accumulo/access/AccessExpressionBenchmark.java
b/src/test/java/org/apache/accumulo/access/tests/AccessExpressionBenchmark.java
similarity index 96%
rename from
src/test/java/org/apache/accumulo/access/AccessExpressionBenchmark.java
rename to
src/test/java/org/apache/accumulo/access/tests/AccessExpressionBenchmark.java
index 5940b5d..64de076 100644
--- a/src/test/java/org/apache/accumulo/access/AccessExpressionBenchmark.java
+++
b/src/test/java/org/apache/accumulo/access/tests/AccessExpressionBenchmark.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.tests;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -28,6 +28,9 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.apache.accumulo.access.AccessEvaluator;
+import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.Authorizations;
import org.apache.accumulo.core.security.ColumnVisibility;
import org.apache.accumulo.core.security.VisibilityEvaluator;
import org.apache.accumulo.core.security.VisibilityParseException;
@@ -58,6 +61,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
*
* </blockquote>
*/
+@SuppressFBWarnings(value = {"NP_UNWRITTEN_FIELD"}, justification = "Field is
written by Gson")
public class AccessExpressionBenchmark {
public static class VisibilityEvaluatorTests {
@@ -83,8 +87,6 @@ public class AccessExpressionBenchmark {
private ArrayList<VisibilityEvaluatorTests> visibilityEvaluatorTests;
- @SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"},
- justification = "Field is written by Gson")
@Setup
public void loadData() throws IOException {
List<AccessEvaluatorTest.TestDataSet> testData =
AccessEvaluatorTest.readTestData();
diff --git a/src/test/java/org/apache/accumulo/access/AccessExpressionTest.java
b/src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
similarity index 97%
rename from src/test/java/org/apache/accumulo/access/AccessExpressionTest.java
rename to
src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
index af921ac..4bec427 100644
--- a/src/test/java/org/apache/accumulo/access/AccessExpressionTest.java
+++ b/src/test/java/org/apache/accumulo/access/tests/AccessExpressionTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.tests;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
@@ -39,6 +39,9 @@ import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.InvalidAccessExpressionException;
+import org.apache.accumulo.access.ParsedAccessExpression;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
diff --git a/src/test/java/org/apache/accumulo/access/AuthorizationTest.java
b/src/test/java/org/apache/accumulo/access/tests/AuthorizationTest.java
similarity index 95%
rename from src/test/java/org/apache/accumulo/access/AuthorizationTest.java
rename to src/test/java/org/apache/accumulo/access/tests/AuthorizationTest.java
index 1e1e764..53d8164 100644
--- a/src/test/java/org/apache/accumulo/access/AuthorizationTest.java
+++ b/src/test/java/org/apache/accumulo/access/tests/AuthorizationTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.tests;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertSame;
import java.util.Set;
+import org.apache.accumulo.access.Authorizations;
import org.junit.jupiter.api.Test;
public class AuthorizationTest {
diff --git
a/src/test/java/org/apache/accumulo/access/ParsedAccessExpressionTest.java
b/src/test/java/org/apache/accumulo/access/tests/ParsedAccessExpressionTest.java
similarity index 96%
rename from
src/test/java/org/apache/accumulo/access/ParsedAccessExpressionTest.java
rename to
src/test/java/org/apache/accumulo/access/tests/ParsedAccessExpressionTest.java
index a5cc065..3ef9c55 100644
--- a/src/test/java/org/apache/accumulo/access/ParsedAccessExpressionTest.java
+++
b/src/test/java/org/apache/accumulo/access/tests/ParsedAccessExpressionTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.accumulo.access;
+package org.apache.accumulo.access.tests;
import static java.nio.charset.StandardCharsets.UTF_8;
import static
org.apache.accumulo.access.ParsedAccessExpression.ExpressionType.AND;
@@ -30,6 +30,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.List;
+import org.apache.accumulo.access.AccessExpression;
+import org.apache.accumulo.access.ParsedAccessExpression;
import org.junit.jupiter.api.Test;
public class ParsedAccessExpressionTest {