From dfd69a49fcb89abd4f7aa8bde16a006c5d93a4eb Mon Sep 17 00:00:00 2001 From: Mark Adamcin Date: Sun, 19 Apr 2020 18:02:05 -0700 Subject: [PATCH] Constants refactoring --- .travis.yml | 6 +- .../net/adamcin/oakpal/api/ApiConstants.java | 62 +++++++ .../main/java/net/adamcin/oakpal/api/Fun.java | 3 +- .../net/adamcin/oakpal/api/ProgressCheck.java | 2 +- .../oakpal/api/ProgressCheckFactory.java | 2 +- .../java/net/adamcin/oakpal/api/Rule.java | 38 ++++- .../java/net/adamcin/oakpal/api/Severity.java | 78 +++++++++ .../oakpal/api/SimpleProgressCheck.java | 8 +- .../adamcin/oakpal/api/SimpleViolation.java | 8 +- .../net/adamcin/oakpal/api/Violation.java | 68 +------- .../java/net/adamcin/oakpal/api/FunTest.java | 12 ++ .../adamcin/oakpal/api/ProgressCheckTest.java | 2 + .../java/net/adamcin/oakpal/api/RuleTest.java | 127 ++++++++++---- .../oakpal/api/SimpleProgressCheckTest.java | 14 +- .../net/adamcin/oakpal/api/ViolationTest.java | 26 +-- .../java/net/adamcin/oakpal/cli/Command.java | 5 +- .../java/net/adamcin/oakpal/cli/Options.java | 14 +- .../net/adamcin/oakpal/cli/CommandTest.java | 36 ++-- .../net/adamcin/oakpal/cli/OptionsTest.java | 4 +- .../net/adamcin/oakpal/core/CheckReport.java | 10 +- .../net/adamcin/oakpal/core/CheckSpec.java | 113 +++++++++---- .../net/adamcin/oakpal/core/Checklist.java | 153 ++++++++++++----- .../adamcin/oakpal/core/CoreConstants.java | 57 +++++++ .../oakpal/core/DefaultErrorListener.java | 21 +-- .../oakpal/core/DefaultPackagingService.java | 1 - .../net/adamcin/oakpal/core/ForcedRoot.java | 56 +++++-- .../java/net/adamcin/oakpal/core/JcrNs.java | 38 ++++- .../net/adamcin/oakpal/core/OakpalPlan.java | 137 ++++++++++----- .../net/adamcin/oakpal/core/ReportMapper.java | 41 ++++- .../oakpal/core/ScriptProgressCheck.java | 7 +- .../net/adamcin/oakpal/core/SimpleReport.java | 4 +- .../oakpal/core/checks/AcHandling.java | 43 ++++- .../oakpal/core/checks/ExpectAces.java | 156 +++++++++++++----- .../oakpal/core/checks/ExpectPaths.java | 67 ++++++-- .../oakpal/core/checks/FilterSets.java | 67 ++++++-- .../oakpal/core/checks/JcrProperties.java | 58 ++++++- .../core/checks/JcrPropertyConstraints.java | 114 ++++++++++--- .../adamcin/oakpal/core/checks/Overlaps.java | 39 +++-- .../net/adamcin/oakpal/core/checks/Paths.java | 59 +++++-- .../oakpal/core/checks/Subpackages.java | 40 ++++- .../adamcin/oakpal/core/CheckReportTest.java | 27 +-- .../adamcin/oakpal/core/CheckSpecTest.java | 60 +++---- .../adamcin/oakpal/core/ChecklistTest.java | 105 ++++++------ .../oakpal/core/DefaultErrorListenerTest.java | 8 +- .../adamcin/oakpal/core/ForcedRootTest.java | 36 ++-- .../net/adamcin/oakpal/core/JcrNsTest.java | 11 +- .../net/adamcin/oakpal/core/LocatorTest.java | 6 +- .../adamcin/oakpal/core/ReportMapperTest.java | 14 +- .../oakpal/core/ScriptProgressCheckTest.java | 7 +- .../adamcin/oakpal/core/SimpleReportTest.java | 29 ++-- .../oakpal/core/checks/ExpectAcesTest.java | 22 +-- .../oakpal/core/checks/ExpectPathsTest.java | 23 +-- .../oakpal/core/checks/FilterSetsTest.java | 8 +- .../oakpal/core/checks/OverlapsTest.java | 2 +- .../adamcin/oakpal/core/checks/PathsTest.java | 11 +- .../oakpal/maven/mojo/AbstractITestMojo.java | 9 +- .../oakpal/maven/checks/SimpleJavaCheck.java | 4 +- .../maven/mojo/AbstractITestMojoTest.java | 14 +- .../adamcin/oakpal/testing/TestUtilTest.java | 42 +++++ .../oakpal/webster/ChecklistExporter.java | 8 +- .../oakpal/webster/ChecklistExporterTest.java | 28 ++-- 61 files changed, 1607 insertions(+), 663 deletions(-) create mode 100644 api/src/main/java/net/adamcin/oakpal/api/ApiConstants.java create mode 100644 api/src/main/java/net/adamcin/oakpal/api/Severity.java create mode 100644 core/src/main/java/net/adamcin/oakpal/core/CoreConstants.java create mode 100644 testing/src/test/java/net/adamcin/oakpal/testing/TestUtilTest.java diff --git a/.travis.yml b/.travis.yml index 3ed8ce7e5..99d38d659 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,9 @@ matrix: dist: trusty language: java jdk: oraclejdk8 - script: ./mvnw -B -e verify site site:stage + script: ./mvnw -B -e -fae verify site site:stage after_success: - - ./mvnw -B -Pcoverage clean verify coveralls:report + - ./mvnw -B -fae -Pcoverage clean verify coveralls:report - os: linux dist: trusty language: java @@ -39,7 +39,7 @@ matrix: # for jdk 11.0.1+13 osx_image: xcode10.1 script: - - ./mvnw -B -e verify + - ./mvnw -B -e -fae verify cache: directories: - $HOME/.m2 diff --git a/api/src/main/java/net/adamcin/oakpal/api/ApiConstants.java b/api/src/main/java/net/adamcin/oakpal/api/ApiConstants.java new file mode 100644 index 000000000..db7b9eb65 --- /dev/null +++ b/api/src/main/java/net/adamcin/oakpal/api/ApiConstants.java @@ -0,0 +1,62 @@ +/* + * Copyright 2020 Mark Adamcin + * + * Licensed 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 + * + * http://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. + */ + +package net.adamcin.oakpal.api; + +import org.jetbrains.annotations.NotNull; + +/** + * Hosts constants as static singleton getter methods defined by interfaces. This reduces the impact on semantic + * versioning rules of adding or modifying interface constants. + */ +public final class ApiConstants { + private ApiConstants() { + /* no construction */ + } + + private static final ViolationKeys VIOLATION_KEYS = new ViolationKeys() { + @Override + public String description() { + return "description"; + } + + @Override + public String severity() { + return "severity"; + } + + @Override + public String packages() { + return "packages"; + } + }; + + /** + * Json key constant accessors for violations. + */ + public interface ViolationKeys { + String description(); + + String severity(); + + String packages(); + } + + @NotNull + public static ViolationKeys violationKeys() { + return VIOLATION_KEYS; + } +} diff --git a/api/src/main/java/net/adamcin/oakpal/api/Fun.java b/api/src/main/java/net/adamcin/oakpal/api/Fun.java index 695ccd214..d0bae5ad6 100644 --- a/api/src/main/java/net/adamcin/oakpal/api/Fun.java +++ b/api/src/main/java/net/adamcin/oakpal/api/Fun.java @@ -855,8 +855,7 @@ private FunRuntimeException(final @NotNull Throwable cause) { final @Nullable BiConsumer onError) { final BiConsumer consumeError = onError != null ? onError - : (e, t) -> { - }; + : (e, t) -> { /* do nothing */ }; return element -> { try { diff --git a/api/src/main/java/net/adamcin/oakpal/api/ProgressCheck.java b/api/src/main/java/net/adamcin/oakpal/api/ProgressCheck.java index 291b483ff..4b64a860b 100644 --- a/api/src/main/java/net/adamcin/oakpal/api/ProgressCheck.java +++ b/api/src/main/java/net/adamcin/oakpal/api/ProgressCheck.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Mark Adamcin + * Copyright 2020 Mark Adamcin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/api/src/main/java/net/adamcin/oakpal/api/ProgressCheckFactory.java b/api/src/main/java/net/adamcin/oakpal/api/ProgressCheckFactory.java index a2099bb1c..2f5cc13e3 100644 --- a/api/src/main/java/net/adamcin/oakpal/api/ProgressCheckFactory.java +++ b/api/src/main/java/net/adamcin/oakpal/api/ProgressCheckFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Mark Adamcin + * Copyright 2020 Mark Adamcin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/api/src/main/java/net/adamcin/oakpal/api/Rule.java b/api/src/main/java/net/adamcin/oakpal/api/Rule.java index 907e41810..f1091a9b1 100644 --- a/api/src/main/java/net/adamcin/oakpal/api/Rule.java +++ b/api/src/main/java/net/adamcin/oakpal/api/Rule.java @@ -16,6 +16,8 @@ package net.adamcin.oakpal.api; +import org.jetbrains.annotations.NotNull; + import javax.json.JsonArray; import javax.json.JsonObject; import java.util.List; @@ -38,6 +40,29 @@ * */ public final class Rule implements JsonObjectConvertible { + public interface JsonKeys { + String type(); + + String pattern(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String type() { + return "type"; + } + + @Override + public String pattern() { + return "pattern"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + static final Pattern PATTERN_MATCH_ALL = Pattern.compile(".*"); /** @@ -60,8 +85,11 @@ public final class Rule implements JsonObjectConvertible { */ public static final Rule DEFAULT_DENY = new Rule(RuleType.DENY, PATTERN_MATCH_ALL); - public static final String CONFIG_TYPE = "type"; - public static final String CONFIG_PATTERN = "pattern"; + @Deprecated + public static final String CONFIG_TYPE = keys().type(); + @Deprecated + public static final String CONFIG_PATTERN = keys().pattern(); + private final RuleType type; private final Pattern pattern; @@ -149,7 +177,7 @@ public boolean matches(String value) { */ @Override public JsonObject toJson() { - return JavaxJson.key(CONFIG_TYPE, getType().name()).key(CONFIG_PATTERN, getPattern().pattern()).get(); + return JavaxJson.key(keys().type(), getType().name()).key(keys().pattern(), getPattern().pattern()).get(); } @Override @@ -203,8 +231,8 @@ public static List fromJsonArray(final JsonArray rulesArray) { * @return a new rule */ public static Rule fromJson(final JsonObject ruleJson) { - return new Rule(Rule.RuleType.fromName(ruleJson.getString(CONFIG_TYPE)), - Pattern.compile(ruleJson.getString(CONFIG_PATTERN))); + return new Rule(Rule.RuleType.fromName(ruleJson.getString(keys().type())), + Pattern.compile(ruleJson.getString(keys().pattern()))); } /** diff --git a/api/src/main/java/net/adamcin/oakpal/api/Severity.java b/api/src/main/java/net/adamcin/oakpal/api/Severity.java new file mode 100644 index 000000000..22bc1dc3b --- /dev/null +++ b/api/src/main/java/net/adamcin/oakpal/api/Severity.java @@ -0,0 +1,78 @@ +/* + * Copyright 2020 Mark Adamcin + * + * Licensed 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 + * + * http://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. + */ + +package net.adamcin.oakpal.api; + +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +/** + * Levels of severity for violations detected during package scans. + */ +public enum Severity { + /** + * Unlikely to disrupt application functionality. Appropriate for reporting violations of + * code or style conventions, or inconsistency between modes of installation. + */ + MINOR(2), + + /** + * Likely to be the source of component instability. Appropriate for importer errors, mistaken + * assumptions about root path dependencies or namespaces, or failures related to unit testing of + * application packages. + */ + MAJOR(1), + + /** + * Likely to be the source of platform instability. Appropriate for reporting cross-package filter + * overlap, destructive ACL handling modes, destruction of authorable content, or security violations. + */ + SEVERE(0); + + private final int ordinal; + + Severity(int ordinal) { + this.ordinal = ordinal; + } + + /** + * Runtime throwing function to lookup severity codes by name. + * + * @param name the severity level name + * @return the associated severity level + */ + public static Severity byName(final @NotNull String name) { + for (Severity value : values()) { + if (value.name().equalsIgnoreCase(name)) { + return value; + } + } + throw new IllegalArgumentException("Unknown severity level: " + name); + } + + public boolean isLessSevereThan(Severity other) { + return this.ordinal > other.ordinal; + } + + public Predicate meetsMinimumSeverity() { + return other -> !other.isLessSevereThan(this); + } + + public Severity maxSeverity(final @NotNull Severity other) { + return this.isLessSevereThan(other) ? other : this; + } +} diff --git a/api/src/main/java/net/adamcin/oakpal/api/SimpleProgressCheck.java b/api/src/main/java/net/adamcin/oakpal/api/SimpleProgressCheck.java index 787d009de..5e8edf99f 100644 --- a/api/src/main/java/net/adamcin/oakpal/api/SimpleProgressCheck.java +++ b/api/src/main/java/net/adamcin/oakpal/api/SimpleProgressCheck.java @@ -30,22 +30,22 @@ protected void reportViolation(final Violation violation) { collector.reportViolation(violation); } - protected final void reportViolation(final Violation.Severity severity, + protected final void reportViolation(final Severity severity, final String description, final PackageId... packages) { this.reportViolation(new SimpleViolation(severity, description, packages)); } protected final void minorViolation(final String description, final PackageId... packages) { - this.reportViolation(new SimpleViolation(Violation.Severity.MINOR, description, packages)); + this.reportViolation(new SimpleViolation(Severity.MINOR, description, packages)); } protected final void majorViolation(final String description, final PackageId... packages) { - this.reportViolation(new SimpleViolation(Violation.Severity.MAJOR, description, packages)); + this.reportViolation(new SimpleViolation(Severity.MAJOR, description, packages)); } protected final void severeViolation(final String description, final PackageId... packages) { - this.reportViolation(new SimpleViolation(Violation.Severity.SEVERE, description, packages)); + this.reportViolation(new SimpleViolation(Severity.SEVERE, description, packages)); } @Override diff --git a/api/src/main/java/net/adamcin/oakpal/api/SimpleViolation.java b/api/src/main/java/net/adamcin/oakpal/api/SimpleViolation.java index 88373c146..aa7bc19b6 100644 --- a/api/src/main/java/net/adamcin/oakpal/api/SimpleViolation.java +++ b/api/src/main/java/net/adamcin/oakpal/api/SimpleViolation.java @@ -71,10 +71,10 @@ public static SimpleViolation fromReported(final Violation violation) { } public static SimpleViolation fromJson(final JsonObject jsonViolation) { - String vSeverity = jsonViolation.getString(KEY_SEVERITY, Violation.Severity.MINOR.name()); - Violation.Severity severity = Violation.Severity.valueOf(vSeverity); - String description = jsonViolation.getString(KEY_DESCRIPTION, ""); - List packages = optArray(jsonViolation, KEY_PACKAGES) + String vSeverity = jsonViolation.getString(ApiConstants.violationKeys().severity(), Severity.MINOR.name()); + Severity severity = Severity.valueOf(vSeverity); + String description = jsonViolation.getString(ApiConstants.violationKeys().description(), ""); + List packages = optArray(jsonViolation, ApiConstants.violationKeys().packages()) .map(array -> mapArrayOfStrings(array, PackageId::fromString, true)) .orElseGet(Collections::emptyList); diff --git a/api/src/main/java/net/adamcin/oakpal/api/Violation.java b/api/src/main/java/net/adamcin/oakpal/api/Violation.java index 13de89836..aa2d7351c 100644 --- a/api/src/main/java/net/adamcin/oakpal/api/Violation.java +++ b/api/src/main/java/net/adamcin/oakpal/api/Violation.java @@ -17,79 +17,17 @@ package net.adamcin.oakpal.api; import org.apache.jackrabbit.vault.packaging.PackageId; -import org.jetbrains.annotations.NotNull; import javax.json.Json; import javax.json.JsonArrayBuilder; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; import java.util.Collection; -import java.util.function.Predicate; /** * Report type for validations. */ public interface Violation extends JsonObjectConvertible { - String KEY_DESCRIPTION = "description"; - String KEY_SEVERITY = "severity"; - String KEY_PACKAGES = "packages"; - - /** - * Levels of severity for violations detected during package scans. - */ - enum Severity { - /** - * Unlikely to disrupt application functionality. Appropriate for reporting violations of - * code or style conventions, or inconsistency between modes of installation. - */ - MINOR(2), - - /** - * Likely to be the source of component instability. Appropriate for importer errors, mistaken - * assumptions about root path dependencies or namespaces, or failures related to unit testing of - * application packages. - */ - MAJOR(1), - - /** - * Likely to be the source of platform instability. Appropriate for reporting cross-package filter - * overlap, destructive ACL handling modes, destruction of authorable content, or security violations. - */ - SEVERE(0); - - private final int ordinal; - - Severity(int ordinal) { - this.ordinal = ordinal; - } - - /** - * Runtime throwing function to lookup severity codes by name. - * - * @param name the severity level name - * @return the associated severity level - */ - public static Severity byName(final @NotNull String name) { - for (Severity value : values()) { - if (value.name().equalsIgnoreCase(name)) { - return value; - } - } - throw new IllegalArgumentException("Unknown severity level: " + name); - } - - public boolean isLessSevereThan(Severity other) { - return this.ordinal > other.ordinal; - } - - public Predicate meetsMinimumSeverity() { - return other -> !other.isLessSevereThan(this); - } - - public Severity maxSeverity(final @NotNull Severity other) { - return this.isLessSevereThan(other) ? other : this; - } - } /** * Describe the severity of the violation. @@ -121,17 +59,17 @@ public Severity maxSeverity(final @NotNull Severity other) { default JsonObject toJson() { JsonObjectBuilder json = Json.createObjectBuilder(); if (this.getSeverity() != null) { - json.add(KEY_SEVERITY, this.getSeverity().toString()); + json.add(ApiConstants.violationKeys().severity(), this.getSeverity().toString()); } if (this.getDescription() != null) { - json.add(KEY_DESCRIPTION, this.getDescription()); + json.add(ApiConstants.violationKeys().description(), this.getDescription()); } if (this.getPackages() != null && !this.getPackages().isEmpty()) { JsonArrayBuilder array = Json.createArrayBuilder(); for (PackageId packageId : this.getPackages()) { array.add(packageId.toString()); } - json.add(KEY_PACKAGES, array.build()); + json.add(ApiConstants.violationKeys().packages(), array.build()); } return json.build(); } diff --git a/api/src/test/java/net/adamcin/oakpal/api/FunTest.java b/api/src/test/java/net/adamcin/oakpal/api/FunTest.java index 1b9049b50..454eb9705 100644 --- a/api/src/test/java/net/adamcin/oakpal/api/FunTest.java +++ b/api/src/test/java/net/adamcin/oakpal/api/FunTest.java @@ -594,6 +594,18 @@ public void testIsValueIn() { assertArrayEquals("filtered should contain 5 and 4", new Integer[]{5, 4}, filtered); } + @Test + public void testComposeTry_noOnError() { + final Fun.ThrowingFunction> classLoader = this.getClass().getClassLoader()::loadClass; + final Function>> func = + composeTry(Stream::of, Stream::empty, classLoader, null); + final String notARealClassName = "net.adamcin.oakpal.core.NotARealClass"; + final Class[] loadedClasses = Stream.of("java.lang.String", notARealClassName, "java.util.Map") + .flatMap(func).toArray(Class[]::new); + assertArrayEquals("loadedClasses should contain String and Map", + new Class[]{String.class, Map.class}, loadedClasses); + } + @Test public void testComposeTry() { final Fun.ThrowingFunction> classLoader = this.getClass().getClassLoader()::loadClass; diff --git a/api/src/test/java/net/adamcin/oakpal/api/ProgressCheckTest.java b/api/src/test/java/net/adamcin/oakpal/api/ProgressCheckTest.java index 7b4e841a4..5988c4465 100644 --- a/api/src/test/java/net/adamcin/oakpal/api/ProgressCheckTest.java +++ b/api/src/test/java/net/adamcin/oakpal/api/ProgressCheckTest.java @@ -16,6 +16,7 @@ package net.adamcin.oakpal.api; +import org.junit.Assert; import org.junit.Test; import java.util.Collection; @@ -32,6 +33,7 @@ public Collection getReportedViolations() { } }; + Assert.assertNotNull("expect nonnull checkName", mock.getCheckName()); mock.startedScan(); mock.identifyPackage(null, null); mock.identifySubpackage(null, null); diff --git a/api/src/test/java/net/adamcin/oakpal/api/RuleTest.java b/api/src/test/java/net/adamcin/oakpal/api/RuleTest.java index e163e3255..8a53937e1 100644 --- a/api/src/test/java/net/adamcin/oakpal/api/RuleTest.java +++ b/api/src/test/java/net/adamcin/oakpal/api/RuleTest.java @@ -16,55 +16,52 @@ package net.adamcin.oakpal.api; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; +import org.junit.Test; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.regex.Pattern; -import net.adamcin.oakpal.api.Rule; -import org.junit.Test; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static net.adamcin.oakpal.api.JavaxJson.arr; +import static net.adamcin.oakpal.api.JavaxJson.key; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; public class RuleTest { - @Test - public void testConstruct() { - boolean npeForRuleType = false; - try { - Rule rule = new Rule(null, Pattern.compile(".*")); - } catch (final NullPointerException npe) { - npeForRuleType = true; - } - - assertTrue("null ruleType should throw NPE immediately", npeForRuleType); - - boolean npeForPattern = false; - try { - Rule rule = new Rule(Rule.RuleType.DENY, null); - } catch (final NullPointerException npe) { - npeForPattern = true; - } + @Test(expected = NullPointerException.class) + public void testConstruct_nullType() { + new Rule(null, Pattern.compile(".*")); + } - assertTrue("null pattern should throw NPE immediately", npeForPattern); + @Test(expected = NullPointerException.class) + public void testConstruct_nullPattern() { + new Rule(Rule.RuleType.DENY, null); } @Test public void testRuleType() { - boolean illegalForUnknown = false; - try { - Rule.RuleType.fromName("not a thing"); - } catch (IllegalArgumentException iae) { - illegalForUnknown = true; - } + assertSame("expect allow", Rule.RuleType.ALLOW, Rule.RuleType.fromName("allow")); + assertSame("expect allow", Rule.RuleType.ALLOW, Rule.RuleType.fromName("ALLOW")); + assertSame("expect deny", Rule.RuleType.DENY, Rule.RuleType.fromName("deny")); + assertSame("expect deny", Rule.RuleType.DENY, Rule.RuleType.fromName("DENY")); + assertSame("expect include", Rule.RuleType.INCLUDE, Rule.RuleType.fromName("include")); + assertSame("expect include", Rule.RuleType.INCLUDE, Rule.RuleType.fromName("INCLUDE")); + assertSame("expect exclude", Rule.RuleType.EXCLUDE, Rule.RuleType.fromName("exclude")); + assertSame("expect exclude", Rule.RuleType.EXCLUDE, Rule.RuleType.fromName("EXCLUDE")); + } - assertTrue("unknown ruletype name should throw IllegalArgumentException immediately", - illegalForUnknown); + @Test(expected = IllegalArgumentException.class) + public void testRuleType_throws() { + Rule.RuleType.fromName("not a thing"); } @Test @@ -93,6 +90,43 @@ public void testHashCode() { Rule.DEFAULT_INCLUDE.hashCode(), newAllow.hashCode()); } + @Test + public void testMatches() { + assertTrue("default matches all", Rule.DEFAULT_ALLOW.matches("/foo")); + final Rule allowsDigits = new Rule(Rule.RuleType.ALLOW, Pattern.compile("[0-9]*")); + assertTrue("allows digits matches digits", allowsDigits.matches("123")); + assertFalse("allows digits doesn't match letters", allowsDigits.matches("abc")); + } + + @Test + public void testToJson() { + final Rule allowsDigits = new Rule(Rule.RuleType.ALLOW, Pattern.compile("[0-9]*")); + assertEquals("expect json", key(Rule.keys().type(), "ALLOW") + .key(Rule.keys().pattern(), "[0-9]*").get(), allowsDigits.toJson()); + } + + @Test + public void testFromJson() { + final Rule allowsDigits = Rule.fromJson(key(Rule.keys().type(), "ALLOW") + .key(Rule.keys().pattern(), "[0-9]*").get()); + assertEquals("expect type", Rule.RuleType.ALLOW, allowsDigits.getType()); + assertEquals("expect pattern", "[0-9]*", allowsDigits.getPattern().pattern()); + } + + @Test + public void testFromJsonArray() { + final Rule allowsDigits = Rule.fromJson(key(Rule.keys().type(), "ALLOW") + .key(Rule.keys().pattern(), "[0-9]*").get()); + final Rule allowsLetters = Rule.fromJson(key(Rule.keys().type(), "ALLOW") + .key(Rule.keys().pattern(), "[a-z]*").get()); + + final List expectRules = Arrays.asList(allowsDigits, allowsLetters); + assertEquals("exect same rules", expectRules, Rule.fromJsonArray(arr() + .val(key(Rule.keys().type(), "allow").key(Rule.keys().pattern(), "[0-9]*")) + .val(key(Rule.keys().type(), "allow").key(Rule.keys().pattern(), "[a-z]*")) + .get())); + } + @Test public void testRuleDefaultAllow() { final Rule rule = Rule.DEFAULT_ALLOW; @@ -169,8 +203,8 @@ public void testFuzzyDefaults() { }); fuzzyDefaultExcFns.entrySet().forEach(fuzzyFnPair -> { - final String fuzzyFnName = fuzzyFnPair.getKey(); - final Function, Rule> fuzzyFn = fuzzyFnPair.getValue(); + final String fuzzyFnName = fuzzyFnPair.getKey(); + final Function, Rule> fuzzyFn = fuzzyFnPair.getValue(); defaultExcRules.forEach(rule -> { final Rule defaultRule = fuzzyFn.apply(singletonList(rule)); assertEquals(fuzzyFnName + ": invert default exclude when first rule is exclude-like: " + rule, @@ -183,4 +217,27 @@ public void testFuzzyDefaults() { }); }); } + + @Test + public void testLastMatch() { + final Rule allowsDigits = Rule.fromJson(key(Rule.keys().type(), "ALLOW") + .key(Rule.keys().pattern(), "[0-9]*").get()); + final Rule deniesLetters = Rule.fromJson(key(Rule.keys().type(), "DENY") + .key(Rule.keys().pattern(), "[a-z]*").get()); + + final List expectRules = Arrays.asList(allowsDigits, deniesLetters); + final Rule adHocDefault = new Rule(Rule.RuleType.ALLOW, Pattern.compile("\\.\\.")); + final Rule matched0 = Rule.lastMatch(expectRules, "...", rules -> adHocDefault); + assertSame("expect specific default", adHocDefault, matched0); + + final Rule matched1 = Rule.lastMatch(expectRules, "...", null); + assertSame("expect globbal default", Rule.DEFAULT_INCLUDE, matched1); + + final Rule matchedDigits = Rule.lastMatch(expectRules, "123"); + assertSame("expect digits rule", allowsDigits, matchedDigits); + + final Rule matchedAlpha = Rule.lastMatch(expectRules, "abc"); + assertSame("expect alpha rule", deniesLetters, matchedAlpha); + + } } diff --git a/api/src/test/java/net/adamcin/oakpal/api/SimpleProgressCheckTest.java b/api/src/test/java/net/adamcin/oakpal/api/SimpleProgressCheckTest.java index b7c38235f..fe7cce10d 100644 --- a/api/src/test/java/net/adamcin/oakpal/api/SimpleProgressCheckTest.java +++ b/api/src/test/java/net/adamcin/oakpal/api/SimpleProgressCheckTest.java @@ -26,7 +26,7 @@ public class SimpleProgressCheckTest { @Test public void testReportViolation() { SimpleProgressCheck check = new SimpleProgressCheck(); - SimpleViolation violation = new SimpleViolation(Violation.Severity.SEVERE, "description"); + SimpleViolation violation = new SimpleViolation(Severity.SEVERE, "description"); check.reportViolation(violation); assertTrue("contains violation", check.getReportedViolations().contains(violation)); } @@ -36,9 +36,9 @@ public void testReportViolation_args() { SimpleProgressCheck check = new SimpleProgressCheck(); PackageId id0 = PackageId.fromString("my_packages:test_0:1.0"); PackageId id1 = PackageId.fromString("my_packages:test_1:1.0"); - check.reportViolation(Violation.Severity.MINOR, "description", id0, id1); + check.reportViolation(Severity.MINOR, "description", id0, id1); assertTrue("violation reported", check.getReportedViolations().stream() - .anyMatch(violation -> violation.getSeverity() == Violation.Severity.MINOR + .anyMatch(violation -> violation.getSeverity() == Severity.MINOR && "description".equals(violation.getDescription()) && violation.getPackages().contains(id0) && violation.getPackages().contains(id1) @@ -50,7 +50,7 @@ public void testStartedScan() { SimpleProgressCheck check = new SimpleProgressCheck(); PackageId id0 = PackageId.fromString("my_packages:test_0:1.0"); PackageId id1 = PackageId.fromString("my_packages:test_1:1.0"); - check.reportViolation(Violation.Severity.MINOR, "description", id0, id1); + check.reportViolation(Severity.MINOR, "description", id0, id1); assertEquals("violation reported", 1, check.getReportedViolations().size()); check.startedScan(); assertTrue("violations are now empty", check.getReportedViolations().isEmpty()); @@ -63,7 +63,7 @@ public void testMinorViolation() { PackageId id1 = PackageId.fromString("my_packages:test_1:1.0"); check.minorViolation("description", id0, id1); assertTrue("violation reported", check.getReportedViolations().stream() - .anyMatch(violation -> violation.getSeverity() == Violation.Severity.MINOR + .anyMatch(violation -> violation.getSeverity() == Severity.MINOR && "description".equals(violation.getDescription()) && violation.getPackages().contains(id0) && violation.getPackages().contains(id1) @@ -77,7 +77,7 @@ public void testMajorViolation() { PackageId id1 = PackageId.fromString("my_packages:test_1:1.0"); check.majorViolation("description", id0, id1); assertTrue("violation reported", check.getReportedViolations().stream() - .anyMatch(violation -> violation.getSeverity() == Violation.Severity.MAJOR + .anyMatch(violation -> violation.getSeverity() == Severity.MAJOR && "description".equals(violation.getDescription()) && violation.getPackages().contains(id0) && violation.getPackages().contains(id1) @@ -91,7 +91,7 @@ public void testSevereViolation() { PackageId id1 = PackageId.fromString("my_packages:test_1:1.0"); check.severeViolation("description", id0, id1); assertTrue("violation reported", check.getReportedViolations().stream() - .anyMatch(violation -> violation.getSeverity() == Violation.Severity.SEVERE + .anyMatch(violation -> violation.getSeverity() == Severity.SEVERE && "description".equals(violation.getDescription()) && violation.getPackages().contains(id0) && violation.getPackages().contains(id1) diff --git a/api/src/test/java/net/adamcin/oakpal/api/ViolationTest.java b/api/src/test/java/net/adamcin/oakpal/api/ViolationTest.java index c45ae56a9..75a5f5d60 100644 --- a/api/src/test/java/net/adamcin/oakpal/api/ViolationTest.java +++ b/api/src/test/java/net/adamcin/oakpal/api/ViolationTest.java @@ -25,9 +25,9 @@ import static net.adamcin.oakpal.api.JavaxJson.arr; import static net.adamcin.oakpal.api.JavaxJson.obj; -import static net.adamcin.oakpal.api.Violation.Severity.MAJOR; -import static net.adamcin.oakpal.api.Violation.Severity.MINOR; -import static net.adamcin.oakpal.api.Violation.Severity.SEVERE; +import static net.adamcin.oakpal.api.Severity.MAJOR; +import static net.adamcin.oakpal.api.Severity.MINOR; +import static net.adamcin.oakpal.api.Severity.SEVERE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; @@ -40,17 +40,17 @@ public class ViolationTest { @Test public void testSeverity_byName() { - assertSame("severity for minor is", MINOR, Violation.Severity.byName("minor")); - assertSame("severity for minor is", MINOR, Violation.Severity.byName("MiNoR")); - assertSame("severity for major is", MAJOR, Violation.Severity.byName("major")); - assertSame("severity for major is", MAJOR, Violation.Severity.byName("MaJoR")); - assertSame("severity for severe is", SEVERE, Violation.Severity.byName("severe")); - assertSame("severity for severe is", SEVERE, Violation.Severity.byName("SeVeRe")); + assertSame("severity for minor is", MINOR, Severity.byName("minor")); + assertSame("severity for minor is", MINOR, Severity.byName("MiNoR")); + assertSame("severity for major is", MAJOR, Severity.byName("major")); + assertSame("severity for major is", MAJOR, Severity.byName("MaJoR")); + assertSame("severity for severe is", SEVERE, Severity.byName("severe")); + assertSame("severity for severe is", SEVERE, Severity.byName("SeVeRe")); } @Test(expected = IllegalArgumentException.class) public void testSeverity_byName_throws() { - Violation.Severity.byName("nothing"); + Severity.byName("nothing"); } @Test @@ -101,9 +101,9 @@ public void testToJson() { when(violation.getPackages()).thenReturn(Arrays.asList(id0, id1)); JsonObject expected = obj() - .key(Violation.KEY_SEVERITY, SEVERE) - .key(Violation.KEY_DESCRIPTION, "some failure") - .key(Violation.KEY_PACKAGES, arr().val(id0.toString()).val(id1.toString())) + .key(ApiConstants.violationKeys().severity(), SEVERE) + .key(ApiConstants.violationKeys().description(), "some failure") + .key(ApiConstants.violationKeys().packages(), arr().val(id0.toString()).val(id1.toString())) .get(); assertEquals("same json", expected, violation.toJson()); diff --git a/cli/src/main/java/net/adamcin/oakpal/cli/Command.java b/cli/src/main/java/net/adamcin/oakpal/cli/Command.java index e28bc201a..7fbc530a5 100644 --- a/cli/src/main/java/net/adamcin/oakpal/cli/Command.java +++ b/cli/src/main/java/net/adamcin/oakpal/cli/Command.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Supplier; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.CheckReport; import net.adamcin.oakpal.core.DefaultErrorListener; import net.adamcin.oakpal.core.FileBlobMemoryNodeStore; @@ -105,7 +106,7 @@ Optional getHighestReportSeverity(final @NotNull Options opts, return reports.stream() .flatMap(compose(CheckReport::getViolations, Collection::stream)) .map(Violation::getSeverity) - .reduce(Violation.Severity::maxSeverity) + .reduce(Severity::maxSeverity) .filter(opts.getFailOnSeverity().meetsMinimumSeverity()) .map(severity -> { switch (severity) { @@ -206,7 +207,7 @@ Optional flipOpt(final @NotNull String wholeOpt) { break; } else { final String severityArg = args[++i]; - final Result severityResult = result1(Violation.Severity::byName) + final Result severityResult = result1(Severity::byName) .apply(severityArg); if (severityResult.isFailure()) { return Result.failure(severityResult.getError().get()); diff --git a/cli/src/main/java/net/adamcin/oakpal/cli/Options.java b/cli/src/main/java/net/adamcin/oakpal/cli/Options.java index c194f4931..805a523b6 100644 --- a/cli/src/main/java/net/adamcin/oakpal/cli/Options.java +++ b/cli/src/main/java/net/adamcin/oakpal/cli/Options.java @@ -1,11 +1,11 @@ package net.adamcin.oakpal.cli; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.InstallHookPolicy; import net.adamcin.oakpal.api.Nothing; import net.adamcin.oakpal.core.OakpalPlan; import net.adamcin.oakpal.core.OpearFile; import net.adamcin.oakpal.api.Result; -import net.adamcin.oakpal.api.Violation; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,7 +34,7 @@ final class Options { private final boolean noHooks; private final List scanFiles; private final Function> printer; - private final Violation.Severity failOnSeverity; + private final Severity failOnSeverity; Options() { this(true, true, false, @@ -43,7 +43,7 @@ final class Options { null, null, false, Collections.emptyList(), EMPTY_PRINTER, - Violation.Severity.MAJOR); + Severity.MAJOR); } Options(final boolean justHelp, @@ -57,7 +57,7 @@ final class Options { final boolean noHooks, final @NotNull List scanFiles, final @NotNull Function> printer, - final @NotNull Violation.Severity failOnSeverity) { + final @NotNull Severity failOnSeverity) { this.justHelp = justHelp; this.justVersion = justVersion; this.storeBlobs = storeBlobs; @@ -116,7 +116,7 @@ public Function> getPrinter() { return printer; } - public Violation.Severity getFailOnSeverity() { + public Severity getFailOnSeverity() { return failOnSeverity; } @@ -150,7 +150,7 @@ static final class Builder { private File cacheDir; private File opearFile; private List scanFiles = new ArrayList<>(); - private Violation.Severity failOnSeverity; + private Severity failOnSeverity; public Builder setJustHelp(final boolean justHelp) { this.justHelp = justHelp; @@ -207,7 +207,7 @@ public Builder addScanFile(final @NotNull File scanFile) { return this; } - public Builder setFailOnSeverity(final @Nullable Violation.Severity failOnSeverity) { + public Builder setFailOnSeverity(final @Nullable Severity failOnSeverity) { this.failOnSeverity = failOnSeverity; return this; } diff --git a/cli/src/test/java/net/adamcin/oakpal/cli/CommandTest.java b/cli/src/test/java/net/adamcin/oakpal/cli/CommandTest.java index 6262b4675..24dd957f7 100644 --- a/cli/src/test/java/net/adamcin/oakpal/cli/CommandTest.java +++ b/cli/src/test/java/net/adamcin/oakpal/cli/CommandTest.java @@ -29,6 +29,7 @@ import java.util.function.Function; import javax.json.JsonObject; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.CheckReport; import net.adamcin.oakpal.core.FileBlobMemoryNodeStore; import net.adamcin.oakpal.api.Nothing; @@ -37,7 +38,6 @@ import net.adamcin.oakpal.api.Result; import net.adamcin.oakpal.core.SimpleReport; import net.adamcin.oakpal.api.SimpleViolation; -import net.adamcin.oakpal.api.Violation; import net.adamcin.oakpal.testing.TestPackageUtil; import org.apache.commons.io.FileUtils; import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore; @@ -94,10 +94,10 @@ public void testWriteReports() { final List reports = new ArrayList<>(); reports.add(new SimpleReport("some check", Collections.emptyList())); reports.add(new SimpleReport("check with violations", Arrays.asList( - new SimpleViolation(Violation.Severity.MINOR, "minor violation"), - new SimpleViolation(Violation.Severity.SEVERE, "severe violation with one packageId", + new SimpleViolation(Severity.MINOR, "minor violation"), + new SimpleViolation(Severity.SEVERE, "severe violation with one packageId", PackageId.fromString("my_packages/acme/1.0")), - new SimpleViolation(Violation.Severity.MAJOR, "major violation with several packageIds", + new SimpleViolation(Severity.MAJOR, "major violation with several packageIds", PackageId.fromString("my_packages/alpha/1.0"), PackageId.fromString("my_packages/beta/1.0"), PackageId.fromString("my_packages/gamma/1.0")) @@ -132,27 +132,27 @@ private Console getMockConsole() { @Test public void testGetHighestReportSeverity() { ReportCollector collector1 = new ReportCollector(); - collector1.reportViolation(new SimpleViolation(Violation.Severity.MINOR, "")); - collector1.reportViolation(new SimpleViolation(Violation.Severity.MAJOR, "")); + collector1.reportViolation(new SimpleViolation(Severity.MINOR, "")); + collector1.reportViolation(new SimpleViolation(Severity.MAJOR, "")); CheckReport hasMajor = new SimpleReport("hasMajor", collector1.getReportedViolations()); ReportCollector collector2 = new ReportCollector(); - collector2.reportViolation(new SimpleViolation(Violation.Severity.MINOR, "")); - collector2.reportViolation(new SimpleViolation(Violation.Severity.SEVERE, "")); + collector2.reportViolation(new SimpleViolation(Severity.MINOR, "")); + collector2.reportViolation(new SimpleViolation(Severity.SEVERE, "")); CheckReport hasSevere = new SimpleReport("hasSevere", collector2.getReportedViolations()); ReportCollector collector3 = new ReportCollector(); - collector3.reportViolation(new SimpleViolation(Violation.Severity.MINOR, "")); + collector3.reportViolation(new SimpleViolation(Severity.MINOR, "")); CheckReport hasMinor = new SimpleReport("hasMinor", collector3.getReportedViolations()); final Console console = getMockConsole(); Options optsFailDefault = new Options.Builder() .build(console).getOrDefault(null); Options optsFailMinor = new Options.Builder() - .setFailOnSeverity(Violation.Severity.MINOR) + .setFailOnSeverity(Severity.MINOR) .build(console).getOrDefault(null); Options optsFailMajor = new Options.Builder() - .setFailOnSeverity(Violation.Severity.MAJOR) + .setFailOnSeverity(Severity.MAJOR) .build(console).getOrDefault(null); Options optsFailSevere = new Options.Builder() - .setFailOnSeverity(Violation.Severity.SEVERE) + .setFailOnSeverity(Severity.SEVERE) .build(console).getOrDefault(null); final Command command = new Command(); assertFalse("no exit minor default fail", @@ -267,22 +267,22 @@ public void testParseArgs_simpleOnes() { validator.expectFailure(args("-s", "extreme")); validator.expectSuccess(args(), options -> assertEquals("expect major by default", - Violation.Severity.MAJOR, options.getFailOnSeverity())); + Severity.MAJOR, options.getFailOnSeverity())); validator.expectSuccess(args("-s", "major"), options -> assertEquals("expect MAJOR", - Violation.Severity.MAJOR, options.getFailOnSeverity())); + Severity.MAJOR, options.getFailOnSeverity())); validator.expectSuccess(args("-s", "minor"), options -> assertEquals("expect MINOR", - Violation.Severity.MINOR, options.getFailOnSeverity())); + Severity.MINOR, options.getFailOnSeverity())); validator.expectSuccess(args("-s", "minor", "+s"), options -> assertEquals("expect MAJOR after resetting", - Violation.Severity.MAJOR, options.getFailOnSeverity())); + Severity.MAJOR, options.getFailOnSeverity())); validator.expectSuccess(args("-s", "severe"), options -> assertEquals("expect severe", - Violation.Severity.SEVERE, options.getFailOnSeverity())); + Severity.SEVERE, options.getFailOnSeverity())); validator.expectSuccess(args("-s", "severe", "+s"), options -> assertEquals("expect MAJOR after resetting", - Violation.Severity.MAJOR, options.getFailOnSeverity())); + Severity.MAJOR, options.getFailOnSeverity())); validator.expectSuccess(args("--no-plan"), options -> assertNull("expect no plan", options.getPlanName())); diff --git a/cli/src/test/java/net/adamcin/oakpal/cli/OptionsTest.java b/cli/src/test/java/net/adamcin/oakpal/cli/OptionsTest.java index 729595cfb..b6703e4d5 100644 --- a/cli/src/test/java/net/adamcin/oakpal/cli/OptionsTest.java +++ b/cli/src/test/java/net/adamcin/oakpal/cli/OptionsTest.java @@ -22,11 +22,11 @@ import javax.json.JsonObject; import javax.json.JsonReader; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.InstallHookPolicy; import net.adamcin.oakpal.api.JavaxJson; import net.adamcin.oakpal.core.OakpalPlan; import net.adamcin.oakpal.api.Result; -import net.adamcin.oakpal.api.Violation; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; @@ -65,7 +65,7 @@ public void testSettersAndSimpleBuild() { builder.setJustHelp(false); builder.setJustVersion(false); builder.setStoreBlobs(false); - builder.setFailOnSeverity(Violation.Severity.MAJOR); + builder.setFailOnSeverity(Severity.MAJOR); builder.setPlanName(null); builder.setOutputJson(false); builder.setOutFile(null); diff --git a/core/src/main/java/net/adamcin/oakpal/core/CheckReport.java b/core/src/main/java/net/adamcin/oakpal/core/CheckReport.java index dc6a94dda..0fbb19077 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/CheckReport.java +++ b/core/src/main/java/net/adamcin/oakpal/core/CheckReport.java @@ -19,6 +19,7 @@ import net.adamcin.oakpal.api.JavaxJson; import net.adamcin.oakpal.api.JsonObjectConvertible; import net.adamcin.oakpal.api.ProgressCheck; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.Violation; import org.jetbrains.annotations.NotNull; @@ -33,9 +34,6 @@ * Type for collected {@link Violation}s from a particlular {@link ProgressCheck}. */ public interface CheckReport extends JsonObjectConvertible { - String KEY_CHECK_NAME = "checkName"; - String KEY_VIOLATIONS = "violations"; - /** * The serialized display name of the package check that created the report. * @@ -56,7 +54,7 @@ public interface CheckReport extends JsonObjectConvertible { * @param atLeastAsSevere lower bound for severity * @return the reported violations filtered by severity */ - default Collection getViolations(Violation.Severity atLeastAsSevere) { + default Collection getViolations(Severity atLeastAsSevere) { if (atLeastAsSevere == null) { return getViolations(); } @@ -74,8 +72,8 @@ default Collection getViolations(Violation.Severity atLeastAsSevere) default JsonObject toJson() { JavaxJson.Obj jsonReport = obj(); - jsonReport.key(KEY_CHECK_NAME).opt(this.getCheckName()); - jsonReport.key(KEY_VIOLATIONS).opt(this.getViolations().stream() + jsonReport.key(CoreConstants.checkReportKeys().checkName()).opt(this.getCheckName()); + jsonReport.key(CoreConstants.checkReportKeys().violations()).opt(this.getViolations().stream() .map(Violation::toJson) .collect(JsonCollectors.toJsonArray())); diff --git a/core/src/main/java/net/adamcin/oakpal/core/CheckSpec.java b/core/src/main/java/net/adamcin/oakpal/core/CheckSpec.java index fd530a103..8006c9c1e 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/CheckSpec.java +++ b/core/src/main/java/net/adamcin/oakpal/core/CheckSpec.java @@ -38,13 +38,66 @@ */ @SuppressWarnings("WeakerAccess") public class CheckSpec implements JsonObjectConvertible { - static final String KEY_IMPL = "impl"; - static final String KEY_INLINE_SCRIPT = "inlineScript"; - static final String KEY_INLINE_ENGINE = "inlineEngine"; - static final String KEY_NAME = "name"; - static final String KEY_TEMPLATE = "template"; - static final String KEY_SKIP = "skip"; - static final String KEY_CONFIG = "config"; + /** + * Json keys for CheckSpec. Use {@link #keys()} to access singleton. + */ + public interface JsonKeys { + String impl(); + + String inlineScript(); + + String inlineEngine(); + + String name(); + + String template(); + + String skip(); + + String config(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String impl() { + return "impl"; + } + + @Override + public String inlineScript() { + return "inlineScript"; + } + + @Override + public String inlineEngine() { + return "inlineEngine"; + } + + @Override + public String name() { + return "name"; + } + + @Override + public String template() { + return "template"; + } + + @Override + public String skip() { + return "skip"; + } + + @Override + public String config() { + return "config"; + } + }; + + @NotNull + public static CheckSpec.JsonKeys keys() { + return KEYS; + } private String impl; private String inlineScript; @@ -54,6 +107,7 @@ public class CheckSpec implements JsonObjectConvertible { private boolean skip; private JsonObject config; + /** * The direct classpath lookup name for a particular check. If not provided, indicates that a check should be * looked up by name from a catalog on the classpath. @@ -376,27 +430,28 @@ static JsonObject merge(final JsonObject base, final JsonObject overlay) { * @return a new CheckSpec */ public static CheckSpec fromJson(final @NotNull JsonObject json) { + final JsonKeys keys = keys(); final CheckSpec checkSpec = new CheckSpec(); - if (hasNonNull(json, KEY_IMPL)) { - checkSpec.setImpl(json.getString(KEY_IMPL)); + if (hasNonNull(json, keys.impl())) { + checkSpec.setImpl(json.getString(keys.impl())); } - if (hasNonNull(json, KEY_INLINE_SCRIPT)) { - checkSpec.setInlineScript(json.getString(KEY_INLINE_SCRIPT)); + if (hasNonNull(json, keys.inlineScript())) { + checkSpec.setInlineScript(json.getString(keys.inlineScript())); } - if (hasNonNull(json, KEY_INLINE_ENGINE)) { - checkSpec.setInlineEngine(json.getString(KEY_INLINE_ENGINE)); + if (hasNonNull(json, keys.inlineEngine())) { + checkSpec.setInlineEngine(json.getString(keys.inlineEngine())); } - if (hasNonNull(json, KEY_NAME)) { - checkSpec.setName(json.getString(KEY_NAME)); + if (hasNonNull(json, keys.name())) { + checkSpec.setName(json.getString(keys.name())); } - if (hasNonNull(json, KEY_TEMPLATE)) { - checkSpec.setTemplate(json.getString(KEY_TEMPLATE)); + if (hasNonNull(json, keys.template())) { + checkSpec.setTemplate(json.getString(keys.template())); } - if (hasNonNull(json, KEY_SKIP)) { - checkSpec.setSkip(json.getBoolean(KEY_SKIP)); + if (hasNonNull(json, keys.skip())) { + checkSpec.setSkip(json.getBoolean(keys.skip())); } - if (hasNonNull(json, KEY_CONFIG)) { - checkSpec.setConfig(json.getJsonObject(KEY_CONFIG)); + if (hasNonNull(json, keys.config())) { + checkSpec.setConfig(json.getJsonObject(keys.config())); } return checkSpec; @@ -414,16 +469,17 @@ protected void editJson(final JsonObjectBuilder builder) { @Override public final JsonObject toJson() { + final JsonKeys keys = keys(); final JsonObjectBuilder builder = Json.createObjectBuilder(); final JavaxJson.Obj obj = obj() - .key(KEY_NAME).opt(getName()) - .key(KEY_IMPL).opt(getImpl()) - .key(KEY_INLINE_SCRIPT).opt(getInlineScript()) - .key(KEY_INLINE_ENGINE).opt(getInlineEngine()) - .key(KEY_CONFIG).opt(getConfig()) - .key(KEY_TEMPLATE).opt(getTemplate()); + .key(keys.name()).opt(getName()) + .key(keys.impl()).opt(getImpl()) + .key(keys.inlineScript()).opt(getInlineScript()) + .key(keys.inlineEngine()).opt(getInlineEngine()) + .key(keys.config()).opt(getConfig()) + .key(keys.template()).opt(getTemplate()); if (isSkip()) { - obj.key(KEY_SKIP, true); + obj.key(keys.skip(), true); } final JsonObject base = obj.get(); base.forEach(builder::add); @@ -478,6 +534,7 @@ public static ImmutableSpec immutableCopyOf(final @NotNull CheckSpec original) { original.isSkip()); } + /** * This is an Immutable variant of {@link CheckSpec} for composition in {@link Checklist}. */ diff --git a/core/src/main/java/net/adamcin/oakpal/core/Checklist.java b/core/src/main/java/net/adamcin/oakpal/core/Checklist.java index 93daa0feb..49de8a1c3 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/Checklist.java +++ b/core/src/main/java/net/adamcin/oakpal/core/Checklist.java @@ -55,33 +55,100 @@ */ public final class Checklist implements JsonObjectConvertible { - private static final Logger LOGGER = LoggerFactory.getLogger(Checklist.class); + /** + * Json keys for Checklist. Use {@link #keys()} to access singleton. + */ + public interface JsonKeys { + String name(); + + String cndUrls(); + + String cndNames(); + + String jcrNodetypes(); + + String jcrNamespaces(); + + String jcrPrivileges(); + + String forcedRoots(); + + String checks(); + + List orderedKeys(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + private final List allKeys = Arrays.asList( + name(), + checks(), + forcedRoots(), + cndNames(), + cndUrls(), + jcrNodetypes(), + jcrPrivileges(), + jcrNamespaces()); + + @Override + public String name() { + return "name"; + } + + @Override + public String cndUrls() { + return "cndUrls"; + } + + @Override + public String cndNames() { + return "cndNames"; + } - static final String KEY_NAME = "name"; - static final String KEY_CND_URLS = "cndUrls"; - static final String KEY_CND_NAMES = "cndNames"; - public static final String KEY_JCR_NODETYPES = "jcrNodetypes"; - public static final String KEY_JCR_NAMESPACES = "jcrNamespaces"; - public static final String KEY_JCR_PRIVILEGES = "jcrPrivileges"; - public static final String KEY_FORCED_ROOTS = "forcedRoots"; - static final String KEY_CHECKS = "checks"; - - static final List KEY_ORDER = Arrays.asList( - Checklist.KEY_NAME, - Checklist.KEY_CHECKS, - Checklist.KEY_FORCED_ROOTS, - Checklist.KEY_CND_NAMES, - Checklist.KEY_CND_URLS, - Checklist.KEY_JCR_NODETYPES, - Checklist.KEY_JCR_PRIVILEGES, - Checklist.KEY_JCR_NAMESPACES); + @Override + public String jcrNodetypes() { + return "jcrNodetypes"; + } + + @Override + public String jcrNamespaces() { + return "jcrNamespaces"; + } + + @Override + public String jcrPrivileges() { + return "jcrPrivileges"; + } + + @Override + public String forcedRoots() { + return "forcedRoots"; + } + + @Override + public String checks() { + return "checks"; + } + + @Override + public List orderedKeys() { + return allKeys; + } + }; + + @NotNull + public static Checklist.JsonKeys keys() { + return KEYS; + } + + private static final Logger LOGGER = LoggerFactory.getLogger(Checklist.class); static final Comparator checklistKeyComparator = (s1, s2) -> { - if (KEY_ORDER.contains(s1) && KEY_ORDER.contains(s2)) { - return Integer.compare(KEY_ORDER.indexOf(s1), KEY_ORDER.indexOf(s2)); - } else if (KEY_ORDER.contains(s1)) { + final List keyOrder = keys().orderedKeys(); + if (keyOrder.contains(s1) && keyOrder.contains(s2)) { + return Integer.compare(keyOrder.indexOf(s1), keyOrder.indexOf(s2)); + } else if (keyOrder.contains(s1)) { return -1; - } else if (KEY_ORDER.contains(s2)) { + } else if (keyOrder.contains(s2)) { return 1; } else { return s1.compareTo(s2); @@ -122,6 +189,7 @@ public static Comparator comparingJsonKeys(final @NotNull Function JavaxJson.unwrapArray(cndNames).stream() .map(String::valueOf) @@ -330,28 +399,28 @@ public static Checklist fromJson(final @NotNull String moduleName, } builder.withCndUrls(parseFromArray( - optArray(json, KEY_CND_URLS).orElse(JsonValue.EMPTY_JSON_ARRAY), URL::new, + optArray(json, jsonKeys.cndUrls()).orElse(JsonValue.EMPTY_JSON_ARRAY), URL::new, (element, error) -> LOGGER.debug("[fromJson#cndUrls] (URL ERROR) {}", error.getMessage()))); final List jcrNsList = new ArrayList<>(); - optArray(json, KEY_JCR_NAMESPACES).ifPresent(jsonArray -> { + optArray(json, jsonKeys.jcrNamespaces()).ifPresent(jsonArray -> { jcrNsList.addAll(JavaxJson.mapArrayOfObjects(jsonArray, JcrNs::fromJson)); builder.withJcrNamespaces(jcrNsList); }); - optObject(json, KEY_JCR_NODETYPES).ifPresent(jsonObject -> { + optObject(json, jsonKeys.jcrNodetypes()).ifPresent(jsonObject -> { builder.withJcrNodetypes( JsonCnd.getQTypesFromJson(jsonObject, JsonCnd.toNamespaceMapping(jcrNsList))); }); - if (json.containsKey(KEY_JCR_PRIVILEGES)) { + if (json.containsKey(jsonKeys.jcrPrivileges())) { builder.withJcrPrivileges( - JsonCnd.getPrivilegesFromJson(json.get(KEY_JCR_PRIVILEGES), - JsonCnd.toNamespaceMapping(jcrNsList))); + JsonCnd.getPrivilegesFromJson(json.get(jsonKeys.jcrPrivileges()), + JsonCnd.toNamespaceMapping(jcrNsList))); } - optArray(json, KEY_FORCED_ROOTS).ifPresent(jsonArray -> { + optArray(json, jsonKeys.forcedRoots()).ifPresent(jsonArray -> { builder.withForcedRoots(JavaxJson.mapArrayOfObjects(jsonArray, ForcedRoot::fromJson)); }); - optArray(json, KEY_CHECKS).ifPresent(jsonArray -> { + optArray(json, jsonKeys.checks()).ifPresent(jsonArray -> { builder.withChecks(JavaxJson.mapArrayOfObjects(jsonArray, CheckSpec::fromJson)); }); final Checklist checklist = builder.build(json); diff --git a/core/src/main/java/net/adamcin/oakpal/core/CoreConstants.java b/core/src/main/java/net/adamcin/oakpal/core/CoreConstants.java new file mode 100644 index 000000000..aeda8f526 --- /dev/null +++ b/core/src/main/java/net/adamcin/oakpal/core/CoreConstants.java @@ -0,0 +1,57 @@ +/* + * Copyright 2020 Mark Adamcin + * + * Licensed 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 + * + * http://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. + */ + +package net.adamcin.oakpal.core; + +import org.jetbrains.annotations.NotNull; + +/** + * Hosts constants for interface types as static singleton getter methods defined by associated interfaces. + * This reduces the impact on semantic versioning rules of adding or modifying interface constants. A similar pattern is + * followed on concrete classes when they must define JSON keys, but each concrete class owns its own constants + * interfaces. + */ +public final class CoreConstants { + private CoreConstants() { + /* no constructor */ + } + + /** + * Json keys for CheckReport. Use {@link CoreConstants#checkReportKeys()} to access singleton. + */ + public interface CheckReportKeys { + String checkName(); + + String violations(); + } + + private static final CheckReportKeys CHECK_REPORT_KEYS = new CheckReportKeys() { + @Override + public String checkName() { + return "checkName"; + } + + @Override + public String violations() { + return "violations"; + } + }; + + @NotNull + public static CheckReportKeys checkReportKeys() { + return CHECK_REPORT_KEYS; + } +} diff --git a/core/src/main/java/net/adamcin/oakpal/core/DefaultErrorListener.java b/core/src/main/java/net/adamcin/oakpal/core/DefaultErrorListener.java index af7225f81..0e21cf68e 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/DefaultErrorListener.java +++ b/core/src/main/java/net/adamcin/oakpal/core/DefaultErrorListener.java @@ -18,6 +18,7 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ReportCollector; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleViolation; import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; @@ -54,7 +55,7 @@ public void onNodeTypeRegistrationError(final Throwable e, final URL resource) { final String message = String.format("NodeType registration error (%s): %s \"%s\"", String.valueOf(resource), e.getClass().getName(), e.getMessage()); LOGGER.trace("[onNodeTypeRegistrationError] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message)); + reportViolation(new SimpleViolation(Severity.MAJOR, message)); } } @@ -66,7 +67,7 @@ public void onJcrNamespaceRegistrationError(final Throwable e, final String pref final String message = String.format("JCR namespace registration error (%s=%s): %s \"%s\"", prefix, uri, e.getClass().getName(), e.getMessage()); LOGGER.trace("[onJcrNamespaceRegistrationError] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message)); + reportViolation(new SimpleViolation(Severity.MAJOR, message)); } } @@ -78,7 +79,7 @@ public void onJcrPrivilegeRegistrationError(final Throwable e, final String jcrP final String message = String.format("JCR privilege registration error (%s): %s \"%s\"", jcrPrivilege, e.getClass().getName(), e.getMessage()); LOGGER.trace("[onJcrPrivilegeRegistrationError] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message)); + reportViolation(new SimpleViolation(Severity.MAJOR, message)); } } @@ -90,7 +91,7 @@ public void onForcedRootCreationError(final Throwable e, final ForcedRoot forced final String message = String.format("Forced root creation error (%s): %s \"%s\"", forcedRoot, e.getClass().getName(), e.getMessage()); LOGGER.trace("[onForcedRootCreationError] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message)); + reportViolation(new SimpleViolation(Severity.MAJOR, message)); } } @@ -100,14 +101,14 @@ public void onListenerException(final Exception e, final ProgressCheck listener, Optional.ofNullable(listener).map(lstr -> lstr.getClass().getName()).orElse(null), e.getClass().getName(), e.getMessage()); LOGGER.trace("[onListenerException] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message, packageId)); + reportViolation(new SimpleViolation(Severity.MAJOR, message, packageId)); } @Override public void onSubpackageException(final Exception e, final PackageId packageId) { final String message = String.format("Package error: %s \"%s\"", e.getClass().getName(), e.getMessage()); LOGGER.trace("[onSubpackageException] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message, packageId)); + reportViolation(new SimpleViolation(Severity.MAJOR, message, packageId)); } @Override @@ -116,7 +117,7 @@ public void onImporterException(final Exception e, final PackageId packageId, fi if (!(e instanceof PathNotFoundException)) { final String message = String.format("%s - Importer error: %s \"%s\"", path, e.getClass().getName(), e.getMessage()); LOGGER.trace("[onImporterException] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message, packageId)); + reportViolation(new SimpleViolation(Severity.MAJOR, message, packageId)); } } @@ -125,7 +126,7 @@ public void onListenerPathException(final Exception e, final ProgressCheck handl final PackageId packageId, final String path) { final String message = String.format("%s - Listener error: %s \"%s\"", path, e.getClass().getName(), e.getMessage()); LOGGER.trace("[onListenerPathException] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message, packageId)); + reportViolation(new SimpleViolation(Severity.MAJOR, message, packageId)); } @Override @@ -133,13 +134,13 @@ public void onInstallHookError(final Throwable e, final PackageId packageId) { final String message = String.format("InstallHook error: %s \"%s\"", Optional.ofNullable(e.getCause()).orElse(e).getClass().getName(), e.getMessage()); LOGGER.trace("[onInstallHookError] stack trace for: " + message, e); - reportViolation(new SimpleViolation(Violation.Severity.MAJOR, message, packageId)); + reportViolation(new SimpleViolation(Severity.MAJOR, message, packageId)); } @Override public void onProhibitedInstallHookRegistration(final PackageId packageId) { reportViolation( - new SimpleViolation(Violation.Severity.MAJOR, + new SimpleViolation(Severity.MAJOR, "Policy prohibits the use of InstallHooks in packages", packageId)); } } diff --git a/core/src/main/java/net/adamcin/oakpal/core/DefaultPackagingService.java b/core/src/main/java/net/adamcin/oakpal/core/DefaultPackagingService.java index 4c6a717ce..42e9dc7b7 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/DefaultPackagingService.java +++ b/core/src/main/java/net/adamcin/oakpal/core/DefaultPackagingService.java @@ -35,7 +35,6 @@ * {@link PackagingService#getPackageManager(Session)} method to avoid the nasty stack trace. * See recommendation here: https://issues.apache.org/jira/browse/JCRVLT-285 */ -@SuppressWarnings("CQRules:CQBP-84--dependencies") // suppress warnings final class DefaultPackagingService implements Packaging { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPackagingService.class); private static final String JCR_PACK_MAN_IMPL_CLASS = "org.apache.jackrabbit.vault.packaging.impl.JcrPackageManagerImpl"; diff --git a/core/src/main/java/net/adamcin/oakpal/core/ForcedRoot.java b/core/src/main/java/net/adamcin/oakpal/core/ForcedRoot.java index c903691a4..f17dba1ca 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/ForcedRoot.java +++ b/core/src/main/java/net/adamcin/oakpal/core/ForcedRoot.java @@ -39,9 +39,38 @@ * Encapsulation of details necessary to force creation of a particular root path. */ public final class ForcedRoot implements JsonObjectConvertible, Comparable { - static final String KEY_PATH = "path"; - static final String KEY_PRIMARY_TYPE = "primaryType"; - static final String KEY_MIXIN_TYPES = "mixinTypes"; + /** + * Json keys for ForcedRoot. Use {@link #keys()} to access singleton. + */ + public interface JsonKeys { + String path(); + + String primaryType(); + + String mixinTypes(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String path() { + return "path"; + } + + @Override + public String primaryType() { + return "primaryType"; + } + + @Override + public String mixinTypes() { + return "mixinTypes"; + } + }; + + @NotNull + public static ForcedRoot.JsonKeys keys() { + return KEYS; + } @Nullable private String path; @@ -52,6 +81,7 @@ public final class ForcedRoot implements JsonObjectConvertible, Comparable mixinTypes = Collections.emptyList(); + public @Nullable String getPath() { return path; } @@ -114,14 +144,15 @@ public final boolean hasPath() { * @return a new forced root */ public static @NotNull ForcedRoot fromJson(final @NotNull JsonObject json) { + final JsonKeys keys = keys(); final ForcedRoot forcedRoot = new ForcedRoot(); - if (json.containsKey(KEY_PATH)) { - forcedRoot.setPath(json.getString(KEY_PATH)); + if (json.containsKey(keys.path())) { + forcedRoot.setPath(json.getString(keys.path())); } - if (json.containsKey(KEY_PRIMARY_TYPE)) { - forcedRoot.setPrimaryType(json.getString(KEY_PRIMARY_TYPE)); + if (json.containsKey(keys.primaryType())) { + forcedRoot.setPrimaryType(json.getString(keys.primaryType())); } - optArray(json, KEY_MIXIN_TYPES).ifPresent(jsonArray -> { + optArray(json, keys.mixinTypes()).ifPresent(jsonArray -> { forcedRoot.setMixinTypes(mapArrayOfStrings(jsonArray, Function.identity())); }); return forcedRoot; @@ -146,9 +177,10 @@ public final boolean hasPath() { @Override public JsonObject toJson() { - return obj().key(KEY_PATH).opt(this.path) - .key(KEY_PRIMARY_TYPE).opt(this.primaryType) - .key(KEY_MIXIN_TYPES).opt(this.mixinTypes) + final JsonKeys keys = keys(); + return obj().key(keys.path()).opt(this.path) + .key(keys.primaryType()).opt(this.primaryType) + .key(keys.mixinTypes()).opt(this.mixinTypes) .get(); } @@ -177,4 +209,6 @@ public int hashCode() { public String toString() { return toJson().toString(); } + + } diff --git a/core/src/main/java/net/adamcin/oakpal/core/JcrNs.java b/core/src/main/java/net/adamcin/oakpal/core/JcrNs.java index 71a85edf2..e71567f8a 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/JcrNs.java +++ b/core/src/main/java/net/adamcin/oakpal/core/JcrNs.java @@ -30,8 +30,31 @@ * Config DTO for JCR Namespace Prefix to URI Mappings. */ public final class JcrNs implements JsonObjectConvertible, Comparable { - static final String KEY_PREFIX = "prefix"; - static final String KEY_URI = "uri"; + /** + * Json keys for JcrNs. Use {@link #keys()} to access singleton. + */ + public interface JsonKeys { + String prefix(); + + String uri(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String prefix() { + return "prefix"; + } + + @Override + public String uri() { + return "uri"; + } + }; + + @NotNull + public static JcrNs.JsonKeys keys() { + return KEYS; + } private String prefix; private String uri; @@ -69,12 +92,12 @@ public void setUri(String uri) { * @return a new JCR NS mapping */ public static @Nullable JcrNs fromJson(final @NotNull JsonObject json) { - if (!json.containsKey(KEY_PREFIX) || !json.containsKey(KEY_URI)) { + if (!json.containsKey(KEYS.prefix()) || !json.containsKey(KEYS.uri())) { return null; } JcrNs jcrNs = new JcrNs(); - jcrNs.setPrefix(json.getString(KEY_PREFIX, "")); - jcrNs.setUri(json.getString(KEY_URI, "")); + jcrNs.setPrefix(json.getString(KEYS.prefix(), "")); + jcrNs.setUri(json.getString(KEYS.uri(), "")); return jcrNs; } @@ -108,7 +131,8 @@ public int hashCode() { @Override public JsonObject toJson() { - return key(KEY_PREFIX, getPrefix()).key(KEY_URI, getUri()).get(); + final JsonKeys keys = keys(); + return key(keys.prefix(), getPrefix()).key(keys.uri(), getUri()).get(); } @Override @@ -121,4 +145,6 @@ public int compareTo(final @NotNull JcrNs o) { return Optional.of(getPrefix().compareTo(o.getPrefix())) .filter(comp -> comp != 0).orElseGet(() -> getUri().compareTo(o.getUri())); } + + } diff --git a/core/src/main/java/net/adamcin/oakpal/core/OakpalPlan.java b/core/src/main/java/net/adamcin/oakpal/core/OakpalPlan.java index 1084dd1c5..febec1fa4 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/OakpalPlan.java +++ b/core/src/main/java/net/adamcin/oakpal/core/OakpalPlan.java @@ -39,6 +39,78 @@ * 4. Can not aggregate multiple plans per execution. */ public final class OakpalPlan implements JsonObjectConvertible { + public interface JsonKeys { + String checklists(); + + String checks(); + + String forcedRoots(); + + String jcrNamespaces(); + + String jcrNodetypes(); + + String jcrPrivileges(); + + String preInstallUrls(); + + String enablePreInstallHooks(); + + String installHookPolicy(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String checklists() { + return "checklists"; + } + + @Override + public String checks() { + return "checks"; + } + + @Override + public String forcedRoots() { + return "forcedRoots"; + } + + @Override + public String jcrNamespaces() { + return "jcrNamespaces"; + } + + @Override + public String jcrNodetypes() { + return "jcrNodetypes"; + } + + @Override + public String jcrPrivileges() { + return "jcrPrivileges"; + } + + @Override + public String preInstallUrls() { + return "preInstallUrls"; + } + + @Override + public String enablePreInstallHooks() { + return "enablePreInstallHooks"; + } + + @Override + public String installHookPolicy() { + return "installHookPolicy"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + private static final Logger LOGGER = LoggerFactory.getLogger(OakpalPlan.class); /** * Preferred default plan when a custom classpath is specified without specifying a plan name. This is also @@ -59,16 +131,6 @@ public final class OakpalPlan implements JsonObjectConvertible { */ public static final String DEFAULT_PLAN_NAME = "plan.json"; - public static final String KEY_CHECKLISTS = "checklists"; - public static final String KEY_CHECKS = "checks"; - public static final String KEY_FORCED_ROOTS = "forcedRoots"; - public static final String KEY_JCR_NAMESPACES = "jcrNamespaces"; - public static final String KEY_JCR_NODETYPES = "jcrNodetypes"; - public static final String KEY_JCR_PRIVILEGES = "jcrPrivileges"; - public static final String KEY_PREINSTALL_URLS = "preInstallUrls"; - public static final String KEY_ENABLE_PRE_INSTALL_HOOKS = "enablePreInstallHooks"; - public static final String KEY_INSTALL_HOOK_POLICY = "installHookPolicy"; - private final URL base; private final String name; private final JsonObject originalJson; @@ -194,15 +256,15 @@ public JsonObject toJson() { final NamespaceMapping mapping = JsonCnd.toNamespaceMapping(jcrNamespaces); return JavaxJson.obj() - .key(KEY_PREINSTALL_URLS).opt(preInstallStrings) - .key(KEY_CHECKLISTS).opt(checklists) - .key(KEY_CHECKS).opt(checks) - .key(KEY_FORCED_ROOTS).opt(forcedRoots) - .key(KEY_JCR_NODETYPES).opt(JsonCnd.toJson(jcrNodetypes, mapping)) - .key(KEY_JCR_PRIVILEGES).opt(JsonCnd.privilegesToJson(jcrPrivileges, mapping)) - .key(KEY_JCR_NAMESPACES).opt(jcrNamespaces) - .key(KEY_ENABLE_PRE_INSTALL_HOOKS).opt(enablePreInstallHooks, false) - .key(KEY_INSTALL_HOOK_POLICY).opt(installHookPolicy) + .key(keys().preInstallUrls()).opt(preInstallStrings) + .key(keys().checklists()).opt(checklists) + .key(keys().checks()).opt(checks) + .key(keys().forcedRoots()).opt(forcedRoots) + .key(keys().jcrNodetypes()).opt(JsonCnd.toJson(jcrNodetypes, mapping)) + .key(keys().jcrPrivileges()).opt(JsonCnd.privilegesToJson(jcrPrivileges, mapping)) + .key(keys().jcrNamespaces()).opt(jcrNamespaces) + .key(keys().enablePreInstallHooks()).opt(enablePreInstallHooks, false) + .key(keys().installHookPolicy()).opt(installHookPolicy) .get(); } @@ -254,40 +316,41 @@ public OakMachine.Builder toOakMachineBuilder(final @Nullable ErrorListener erro private static OakpalPlan fromJson(final @NotNull Builder builder, final @NotNull JsonObject json) { - if (hasNonNull(json, KEY_PREINSTALL_URLS) && builder.base != null) { - builder.withPreInstallUrls(JavaxJson.mapArrayOfStrings(json.getJsonArray(KEY_PREINSTALL_URLS), + if (hasNonNull(json, keys().preInstallUrls()) && builder.base != null) { + builder.withPreInstallUrls(JavaxJson.mapArrayOfStrings(json.getJsonArray(keys().preInstallUrls()), uncheck1(url -> new URL(builder.base, url)))); } - if (hasNonNull(json, KEY_CHECKLISTS)) { - builder.withChecklists(JavaxJson.mapArrayOfStrings(json.getJsonArray(KEY_CHECKLISTS))); + if (hasNonNull(json, keys().checklists())) { + builder.withChecklists(JavaxJson.mapArrayOfStrings(json.getJsonArray(keys().checklists()))); } - if (hasNonNull(json, KEY_CHECKS)) { - builder.withChecks(JavaxJson.mapArrayOfObjects(json.getJsonArray(KEY_CHECKS), CheckSpec::fromJson)); + if (hasNonNull(json, keys().checks())) { + builder.withChecks(JavaxJson.mapArrayOfObjects(json.getJsonArray(keys().checks()), CheckSpec::fromJson)); } - if (hasNonNull(json, KEY_FORCED_ROOTS)) { - builder.withForcedRoots(JavaxJson.mapArrayOfObjects(json.getJsonArray(KEY_FORCED_ROOTS), ForcedRoot::fromJson)); + if (hasNonNull(json, keys().forcedRoots())) { + builder.withForcedRoots(JavaxJson.mapArrayOfObjects(json.getJsonArray(keys().forcedRoots()), + ForcedRoot::fromJson)); } final NamespaceMapping mapping; - if (hasNonNull(json, KEY_JCR_NAMESPACES)) { - final List jcrNsList = JavaxJson.mapArrayOfObjects(json.getJsonArray(KEY_JCR_NAMESPACES), + if (hasNonNull(json, keys().jcrNamespaces())) { + final List jcrNsList = JavaxJson.mapArrayOfObjects(json.getJsonArray(keys().jcrNamespaces()), JcrNs::fromJson); mapping = JsonCnd.toNamespaceMapping(jcrNsList); builder.withJcrNamespaces(jcrNsList); } else { mapping = JsonCnd.BUILTIN_MAPPINGS; } - if (hasNonNull(json, KEY_JCR_NODETYPES)) { - builder.withJcrNodetypes(JsonCnd.getQTypesFromJson(json.getJsonObject(KEY_JCR_NODETYPES), mapping)); + if (hasNonNull(json, keys().jcrNodetypes())) { + builder.withJcrNodetypes(JsonCnd.getQTypesFromJson(json.getJsonObject(keys().jcrNodetypes()), mapping)); } - if (hasNonNull(json, KEY_JCR_PRIVILEGES)) { - builder.withJcrPrivileges(JsonCnd.getPrivilegesFromJson(json.get(KEY_JCR_PRIVILEGES), mapping)); + if (hasNonNull(json, keys().jcrPrivileges())) { + builder.withJcrPrivileges(JsonCnd.getPrivilegesFromJson(json.get(keys().jcrPrivileges()), mapping)); } - if (hasNonNull(json, KEY_ENABLE_PRE_INSTALL_HOOKS)) { - builder.withEnablePreInstallHooks(json.getBoolean(KEY_ENABLE_PRE_INSTALL_HOOKS)); + if (hasNonNull(json, keys().enablePreInstallHooks())) { + builder.withEnablePreInstallHooks(json.getBoolean(keys().enablePreInstallHooks())); } - if (hasNonNull(json, KEY_INSTALL_HOOK_POLICY)) { + if (hasNonNull(json, keys().installHookPolicy())) { builder.withInstallHookPolicy(InstallHookPolicy.forName( - json.getString(KEY_INSTALL_HOOK_POLICY))); + json.getString(keys().installHookPolicy()))); } return builder.build(json); } diff --git a/core/src/main/java/net/adamcin/oakpal/core/ReportMapper.java b/core/src/main/java/net/adamcin/oakpal/core/ReportMapper.java index 3e57da074..918b39691 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/ReportMapper.java +++ b/core/src/main/java/net/adamcin/oakpal/core/ReportMapper.java @@ -49,12 +49,34 @@ * Serialize violations to/from json. */ public final class ReportMapper { - public static final String KEY_REPORTS = "reports"; - public static final String KEY_CHECK_NAME = "checkName"; - public static final String KEY_VIOLATIONS = "violations"; - public static final String KEY_DESCRIPTION = Violation.KEY_DESCRIPTION; - public static final String KEY_SEVERITY = Violation.KEY_SEVERITY; - public static final String KEY_PACKAGES = Violation.KEY_PACKAGES; + public interface JsonKeys { + String reports(); + + String checkName(); + + String violations(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String reports() { + return "reports"; + } + + @Override + public String checkName() { + return "checkName"; + } + + @Override + public String violations() { + return "violations"; + } + }; + + public static JsonKeys keys() { + return KEYS; + } private ReportMapper() { /* No instantiation */ @@ -89,7 +111,7 @@ public static List readReports(final @NotNull ReaderSupplier reader JsonObject json = jsonReader.readObject(); - List reports = optArray(json, KEY_REPORTS) + List reports = optArray(json, keys().reports()) .map(jsonReports -> mapArrayOfObjects(jsonReports, ReportMapper::reportFromJson)) .orElseGet(Collections::emptyList); @@ -144,12 +166,13 @@ public static JsonArray reportsToJson(final @NotNull Collection rep } /** - * Transforms a collection of CheckReports to a JsonArray assigned to a key {@link #KEY_REPORTS} in an outer object. + * Transforms a collection of CheckReports to a JsonArray assigned to a key {@link JsonKeys#reports()} in + * an outer object. * * @param reports the reports to serialize * @return a JsonObject with a JsonArray of CheckReport json objects */ public static JsonObject reportsToJsonObject(final @NotNull Collection reports) { - return key(KEY_REPORTS, reportsToJson(reports)).get(); + return key(keys().reports(), reportsToJson(reports)).get(); } } diff --git a/core/src/main/java/net/adamcin/oakpal/core/ScriptProgressCheck.java b/core/src/main/java/net/adamcin/oakpal/core/ScriptProgressCheck.java index 055dd657c..5dbae6552 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/ScriptProgressCheck.java +++ b/core/src/main/java/net/adamcin/oakpal/core/ScriptProgressCheck.java @@ -21,6 +21,7 @@ import net.adamcin.oakpal.api.ProgressCheckFactory; import net.adamcin.oakpal.api.ReportCollector; import net.adamcin.oakpal.api.Result; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleViolation; import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.fs.config.MetaInf; @@ -264,15 +265,15 @@ public static class ScriptHelper { private final ReportCollector collector = new ReportCollector(); public void minorViolation(String description, PackageId... packageIds) { - collector.reportViolation(new SimpleViolation(Violation.Severity.MINOR, description, packageIds)); + collector.reportViolation(new SimpleViolation(Severity.MINOR, description, packageIds)); } public void majorViolation(String description, PackageId... packageIds) { - collector.reportViolation(new SimpleViolation(Violation.Severity.MAJOR, description, packageIds)); + collector.reportViolation(new SimpleViolation(Severity.MAJOR, description, packageIds)); } public void severeViolation(String description, PackageId... packageIds) { - collector.reportViolation(new SimpleViolation(Violation.Severity.SEVERE, description, packageIds)); + collector.reportViolation(new SimpleViolation(Severity.SEVERE, description, packageIds)); } } diff --git a/core/src/main/java/net/adamcin/oakpal/core/SimpleReport.java b/core/src/main/java/net/adamcin/oakpal/core/SimpleReport.java index ce69551ca..05e852234 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/SimpleReport.java +++ b/core/src/main/java/net/adamcin/oakpal/core/SimpleReport.java @@ -95,8 +95,8 @@ public static SimpleReport generateReport(final @NotNull ErrorListener reporter) } public static SimpleReport fromJson(final @NotNull JsonObject jsonReport) { - String vCheckName = jsonReport.getString(KEY_CHECK_NAME, ""); - List violations = optArray(jsonReport, KEY_VIOLATIONS) + String vCheckName = jsonReport.getString(CoreConstants.checkReportKeys().checkName(), ""); + List violations = optArray(jsonReport, CoreConstants.checkReportKeys().violations()) .map(array -> mapArrayOfObjects(array, ReportMapper::violationFromJson)) .orElseGet(Collections::emptyList); diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/AcHandling.java b/core/src/main/java/net/adamcin/oakpal/core/checks/AcHandling.java index 7e4de5e5e..e1fd2e063 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/AcHandling.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/AcHandling.java @@ -18,8 +18,8 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ProgressCheckFactory; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.fs.config.MetaInf; import org.apache.jackrabbit.vault.fs.io.AccessControlHandling; import org.apache.jackrabbit.vault.packaging.PackageId; @@ -69,18 +69,43 @@ * */ public final class AcHandling implements ProgressCheckFactory { - public static final String CONFIG_ALLOWED_MODES = "allowedModes"; - public static final String CONFIG_LEVEL_SET = "levelSet"; + public interface JsonKeys { + String allowedModes(); + + String levelSet(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String allowedModes() { + return "allowedModes"; + } + + @Override + public String levelSet() { + return "levelSet"; + } + }; + + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_ALLOWED_MODES = keys().allowedModes(); + @Deprecated + public static final String CONFIG_LEVEL_SET = keys().levelSet(); + static final ACHandlingLevelSet DEFAULT_LEVEL_SET = ACHandlingLevelSet.NO_UNSAFE; @Override public ProgressCheck newInstance(final JsonObject config) { - if (hasNonNull(config, CONFIG_ALLOWED_MODES)) { - List allowedModes = mapArrayOfStrings(arrayOrEmpty(config, CONFIG_ALLOWED_MODES), + if (hasNonNull(config, keys().allowedModes())) { + List allowedModes = mapArrayOfStrings(arrayOrEmpty(config, keys().allowedModes()), compose(String::toUpperCase, AccessControlHandling::valueOf), true); return new Check(ACHandlingLevelSet.EXPLICIT, allowedModes); - } else if (hasNonNull(config, CONFIG_LEVEL_SET)) { - ACHandlingLevelSet levelSet = ACHandlingLevelSet.valueOf(config.getString(CONFIG_LEVEL_SET).toUpperCase()); + } else if (hasNonNull(config, keys().levelSet())) { + ACHandlingLevelSet levelSet = ACHandlingLevelSet.valueOf(config.getString(keys().levelSet()).toUpperCase()); return new Check(levelSet, Collections.emptyList()); } else { return new Check(DEFAULT_LEVEL_SET, Collections.emptyList()); @@ -155,13 +180,13 @@ public void beforeExtract(final PackageId packageId, final Session inspectSessio AccessControlHandling packageMode = ofNullable(packageProperties.getACHandling()).orElse(IGNORE); if (this.levelSet == ACHandlingLevelSet.EXPLICIT) { if (!allowedModes.contains(packageMode)) { - reportViolation(Violation.Severity.MAJOR, + reportViolation(Severity.MAJOR, String.format("acHandling mode %s is forbidden. acHandling values in allowedModes are %s", packageMode, allowedModes), packageId); } } else { if (!this.levelSet.getAllowedModes().contains(packageMode)) { - reportViolation(Violation.Severity.MAJOR, + reportViolation(Severity.MAJOR, String.format("acHandling mode %s is forbidden. allowed acHandling values in levelSet:%s are %s", packageMode, this.levelSet.name().toLowerCase(), this.levelSet.getAllowedModes()), packageId); diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectAces.java b/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectAces.java index 281f7e0e8..e81204cd2 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectAces.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectAces.java @@ -22,8 +22,8 @@ import net.adamcin.oakpal.api.ProgressCheckFactory; import net.adamcin.oakpal.api.Result; import net.adamcin.oakpal.api.Rule; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; @@ -121,39 +121,119 @@ * definition so indicates. Otherwise the comma-separated values are treated as an opaque string. */ public final class ExpectAces implements ProgressCheckFactory { + public interface JsonKeys { + String principal(); + + String principals(); + + String expectedAces(); + + String notExpectedAces(); + + String afterPackageIdRules(); + + String severity(); + + String type(); + + String privileges(); + + String path(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String principal() { + return "principal"; + } + + @Override + public String principals() { + return "principals"; + } + + @Override + public String expectedAces() { + return "expectedAces"; + } + + @Override + public String notExpectedAces() { + return "notExpectedAces"; + } + + @Override + public String afterPackageIdRules() { + return "afterPackageIdRules"; + } + + @Override + public String severity() { + return "severity"; + } + + @Override + public String type() { + return "type"; + } + + @Override + public String privileges() { + return "privileges"; + } + + @Override + public String path() { + return "path"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_PRINCIPAL = keys().principal(); + @Deprecated + public static final String CONFIG_PRINCIPALS = keys().principals(); + @Deprecated + public static final String CONFIG_EXPECTED_ACES = keys().expectedAces(); + @Deprecated + public static final String CONFIG_NOT_EXPECTED_ACES = keys().notExpectedAces(); + @Deprecated + public static final String CONFIG_AFTER_PACKAGE_ID_RULES = keys().afterPackageIdRules(); + @Deprecated + public static final String ACE_PARAM_TYPE = keys().type(); + @Deprecated + public static final String ACE_PARAM_PRIVILEGES = keys().privileges(); + @Deprecated + public static final String ACE_PARAM_PATH = keys().path(); + private static final Logger LOGGER = LoggerFactory.getLogger(ExpectAces.class); - public static final String CONFIG_PRINCIPAL = "principal"; - static final String CONFIG_PRINCIPALS = "principals"; - public static final String CONFIG_EXPECTED_ACES = "expectedAces"; - public static final String CONFIG_NOT_EXPECTED_ACES = "notExpectedAces"; - public static final String CONFIG_AFTER_PACKAGE_ID_RULES = "afterPackageIdRules"; - static final String CONFIG_SEVERITY = "severity"; - static final Violation.Severity DEFAULT_SEVERITY = Violation.Severity.MAJOR; - public static final String ACE_PARAM_TYPE = "type"; - public static final String ACE_PARAM_PRIVILEGES = "privileges"; - public static final String ACE_PARAM_PATH = "path"; + static final Severity DEFAULT_SEVERITY = Severity.MAJOR; public static final String DELIM_PARAM = ";"; public static final String DELIM_VALUE = "="; public static final String DELIM_LIST = ","; @Override public ProgressCheck newInstance(final JsonObject config) throws Exception { - final String principal = config.getString(CONFIG_PRINCIPAL, "").trim(); - final String[] principals = JavaxJson.mapArrayOfStrings(JavaxJson.arrayOrEmpty(config, CONFIG_PRINCIPALS)) + final String principal = config.getString(keys().principal(), "").trim(); + final String[] principals = JavaxJson.mapArrayOfStrings(JavaxJson.arrayOrEmpty(config, keys().principals())) .stream().map(String::trim).filter(inferTest1(String::isEmpty).negate()).toArray(String[]::new); final String[] precedingPrincipals = principal.isEmpty() ? principals : new String[]{principal}; - final List expectedAces = parseAceCriteria(config, precedingPrincipals, CONFIG_EXPECTED_ACES); - final List notExpectedAces = parseAceCriteria(config, precedingPrincipals, CONFIG_NOT_EXPECTED_ACES); - final Violation.Severity severity = Violation.Severity.valueOf( - config.getString(CONFIG_SEVERITY, DEFAULT_SEVERITY.name()).toUpperCase()); + final List expectedAces = parseAceCriteria(config, precedingPrincipals, keys().expectedAces()); + final List notExpectedAces = parseAceCriteria(config, precedingPrincipals, keys().notExpectedAces()); + final Severity severity = Severity.valueOf( + config.getString(keys().severity(), DEFAULT_SEVERITY.name()).toUpperCase()); return new Check(expectedAces, notExpectedAces, - Rule.fromJsonArray(JavaxJson.arrayOrEmpty(config, CONFIG_AFTER_PACKAGE_ID_RULES)), severity); + Rule.fromJsonArray(JavaxJson.arrayOrEmpty(config, keys().afterPackageIdRules())), severity); } static boolean isPrincipalSpec(final @NotNull String spec) { - return spec.contains(CONFIG_PRINCIPAL + "="); + return spec.contains(keys().principal() + "="); } static boolean isGeneralSpec(final @NotNull String spec) { @@ -199,12 +279,12 @@ static final class Check extends SimpleProgressCheck { final Map> expectedViolators = new LinkedHashMap<>(); final Map> notExpectedViolators = new LinkedHashMap<>(); final List afterPackageIdRules; - final Violation.Severity severity; + final Severity severity; Check(final @NotNull List expectedAces, final @NotNull List notExpectedAces, final @NotNull List afterPackageIdRules, - final @NotNull Violation.Severity severity) { + final @NotNull Severity severity) { this.expectedAces = expectedAces; this.notExpectedAces = notExpectedAces; this.afterPackageIdRules = afterPackageIdRules; @@ -415,32 +495,32 @@ static Result parse(final @NotNull String principal, final @NotNull .map(Fun.mapValue(Optional::get)) .collect(Fun.entriesToMap()); - final String effectivePrincipal = valueMap.getOrDefault(CONFIG_PRINCIPAL, principal).trim(); + final String effectivePrincipal = valueMap.getOrDefault(keys().principal(), principal).trim(); if (effectivePrincipal.isEmpty()) { return Result.failure("principal must be non-empty: " + spec); } - keys.remove(CONFIG_PRINCIPAL); + keys.remove(keys().principal()); - if (!valueMap.containsKey(ACE_PARAM_TYPE)) { - return Result.failure(ACE_PARAM_TYPE + " is a required ace parameter: " + spec); + if (!valueMap.containsKey(keys().type())) { + return Result.failure(keys().type() + " is a required ace parameter: " + spec); } - final Type type = Type.forName(valueMap.get(ACE_PARAM_TYPE)); + final Type type = Type.forName(valueMap.get(keys().type())); if (type == null) { - return Result.failure(valueMap.get(ACE_PARAM_TYPE) + " is not a valid value for parameter " + ACE_PARAM_TYPE + ": " + spec); + return Result.failure(valueMap.get(keys().type()) + " is not a valid value for parameter " + keys().type() + ": " + spec); } - keys.remove(ACE_PARAM_TYPE); + keys.remove(keys().type()); - if (!keys.contains(ACE_PARAM_PATH)) { - return Result.failure(ACE_PARAM_PATH + " parameter is required, but can be left empty to match rep:repoPolicy aces: " + spec); + if (!keys.contains(keys().path())) { + return Result.failure(keys().path() + " parameter is required, but can be left empty to match rep:repoPolicy aces: " + spec); } - final String path = Optional.ofNullable(valueMap.get(ACE_PARAM_PATH)).map(String::trim).orElse(""); + final String path = Optional.ofNullable(valueMap.get(keys().path())).map(String::trim).orElse(""); if (path.isEmpty()) { LOGGER.debug("empty path param. spec will evaluate /rep:repoPolicy : {}", spec); } - keys.remove(ACE_PARAM_PATH); + keys.remove(keys().path()); - final String[] privileges = Stream.of(Optional.ofNullable(valueMap.get(ACE_PARAM_PRIVILEGES)) + final String[] privileges = Stream.of(Optional.ofNullable(valueMap.get(keys().privileges())) .orElse("").split(DELIM_LIST)) .map(String::trim) .filter(inferTest1(String::isEmpty).negate()) @@ -449,7 +529,7 @@ static Result parse(final @NotNull String principal, final @NotNull if (privileges.length == 0) { return Result.failure("privileges must be specified with at least one element: " + spec); } - keys.remove(ACE_PARAM_PRIVILEGES); + keys.remove(keys().privileges()); RestrictionCriteria[] restrictions = keys.stream() .map(Fun.zipKeysWithValueFunc(valueMap::get)) @@ -465,9 +545,11 @@ String getSpec() { return spec; } else { final StringBuilder common = new StringBuilder() - .append(ACE_PARAM_TYPE + DELIM_VALUE).append(isAllow ? "allow" : "deny") - .append(DELIM_PARAM + ACE_PARAM_PATH + DELIM_VALUE).append(path) - .append(DELIM_PARAM + ACE_PARAM_PRIVILEGES + DELIM_VALUE).append(String.join(DELIM_LIST, privileges)); + .append(keys().type()).append(DELIM_VALUE).append(isAllow ? "allow" : "deny") + .append(DELIM_PARAM) + .append(keys().path()).append(DELIM_VALUE).append(path) + .append(DELIM_PARAM) + .append(keys().privileges()).append(DELIM_VALUE).append(String.join(DELIM_LIST, privileges)); for (RestrictionCriteria restriction : restrictions) { common.append(DELIM_PARAM).append(restriction.name); if (restriction.value != null) { diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectPaths.java b/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectPaths.java index 3fd511ef8..85881ace9 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectPaths.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/ExpectPaths.java @@ -20,8 +20,8 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ProgressCheckFactory; import net.adamcin.oakpal.api.Rule; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; import org.jetbrains.annotations.NotNull; @@ -53,23 +53,64 @@ * */ public final class ExpectPaths implements ProgressCheckFactory { - public static final String CONFIG_EXPECTED_PATHS = "expectedPaths"; - public static final String CONFIG_NOT_EXPECTED_PATHS = "notExpectedPaths"; - public static final String CONFIG_AFTER_PACKAGE_ID_RULES = "afterPackageIdRules"; - static final String CONFIG_SEVERITY = "severity"; - static final Violation.Severity DEFAULT_SEVERITY = Violation.Severity.MAJOR; + public interface JsonKeys { + String expectedPaths(); + + String notExpectedPaths(); + + String afterPackageIdRules(); + + String severity(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String expectedPaths() { + return "expectedPaths"; + } + + @Override + public String notExpectedPaths() { + return "notExpectedPaths"; + } + + @Override + public String afterPackageIdRules() { + return "afterPackageIdRules"; + } + + @Override + public String severity() { + return "severity"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_EXPECTED_PATHS = keys().expectedPaths(); + @Deprecated + public static final String CONFIG_NOT_EXPECTED_PATHS = keys().notExpectedPaths(); + @Deprecated + public static final String CONFIG_AFTER_PACKAGE_ID_RULES = keys().afterPackageIdRules(); + @Deprecated + public static final String CONFIG_SEVERITY = keys().severity(); + static final Severity DEFAULT_SEVERITY = Severity.MAJOR; @Override public ProgressCheck newInstance(final JsonObject config) { - final List expectedPaths = optArray(config, CONFIG_EXPECTED_PATHS) + final List expectedPaths = optArray(config, keys().expectedPaths()) .map(JavaxJson::mapArrayOfStrings) .orElse(Collections.emptyList()); - final List notExpectedPaths = optArray(config, CONFIG_NOT_EXPECTED_PATHS) + final List notExpectedPaths = optArray(config, keys().notExpectedPaths()) .map(JavaxJson::mapArrayOfStrings) .orElse(Collections.emptyList()); - final List afterPackageIdRules = Rule.fromJsonArray(arrayOrEmpty(config, CONFIG_AFTER_PACKAGE_ID_RULES)); - final Violation.Severity severity = Violation.Severity.valueOf( - config.getString(CONFIG_SEVERITY, DEFAULT_SEVERITY.name()).toUpperCase()); + final List afterPackageIdRules = Rule.fromJsonArray(arrayOrEmpty(config, keys().afterPackageIdRules())); + final Severity severity = Severity.valueOf( + config.getString(keys().severity(), DEFAULT_SEVERITY.name()).toUpperCase()); return new Check(expectedPaths, notExpectedPaths, afterPackageIdRules, severity); } @@ -78,14 +119,14 @@ static final class Check extends SimpleProgressCheck { final List expectedPaths; final List notExpectedPaths; final List afterPackageIdRules; - final Violation.Severity severity; + final Severity severity; final Map> expectedViolators = new LinkedHashMap<>(); final Map> notExpectedViolators = new LinkedHashMap<>(); Check(final @NotNull List expectedPaths, final @NotNull List notExpectedPaths, final @NotNull List afterPackageIdRules, - final @NotNull Violation.Severity severity) { + final @NotNull Severity severity) { this.expectedPaths = expectedPaths; this.notExpectedPaths = notExpectedPaths; this.afterPackageIdRules = afterPackageIdRules; diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/FilterSets.java b/core/src/main/java/net/adamcin/oakpal/core/checks/FilterSets.java index dd41d888b..4bbb8ca56 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/FilterSets.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/FilterSets.java @@ -18,14 +18,15 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ProgressCheckFactory; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.fs.api.ImportMode; import org.apache.jackrabbit.vault.fs.api.PathFilterSet; import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter; import org.apache.jackrabbit.vault.fs.config.MetaInf; import org.apache.jackrabbit.vault.packaging.PackageId; import org.apache.jackrabbit.vault.packaging.PackageProperties; +import org.jetbrains.annotations.NotNull; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -40,7 +41,7 @@ * {@code config} options: *
*
{@code importModeSeverity}
- *
(default: {@link Violation.Severity#MINOR}) The default {@link ImportMode} for a + *
(default: {@link Severity#MINOR}) The default {@link ImportMode} for a * filter set is {@link ImportMode#REPLACE}. FileVault also supports {@link ImportMode#UPDATE} and * {@link ImportMode#MERGE}, but it also supports forcing the import mode for an entire package via * {@link org.apache.jackrabbit.vault.fs.io.ImportOptions#setImportMode(ImportMode)}, which certain platforms use to @@ -56,29 +57,63 @@ *
*/ public final class FilterSets implements ProgressCheckFactory { - public static final String CONFIG_IMPORT_MODE_SEVERITY = "importModeSeverity"; - public static final String CONFIG_ALLOW_EMPTY_FILTER = "allowEmptyFilter"; - public static final String CONFIG_ALLOW_ROOT_FILTER = "allowRootFilter"; - public static final Violation.Severity DEFAULT_IMPORT_MODE_SEVERITY = Violation.Severity.MINOR; + public interface JsonKeys { + String importModeSeverity(); + + String allowEmptyFilter(); + + String allowRootFilter(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String importModeSeverity() { + return "importModeSeverity"; + } + + @Override + public String allowEmptyFilter() { + return "allowEmptyFilter"; + } + + @Override + public String allowRootFilter() { + return "allowRootFilter"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_IMPORT_MODE_SEVERITY = keys().importModeSeverity(); + @Deprecated + public static final String CONFIG_ALLOW_EMPTY_FILTER = keys().allowEmptyFilter(); + @Deprecated + public static final String CONFIG_ALLOW_ROOT_FILTER = keys().allowRootFilter(); + + public static final Severity DEFAULT_IMPORT_MODE_SEVERITY = Severity.MINOR; @Override public ProgressCheck newInstance(final JsonObject config) { - final Violation.Severity importModeSeverity = Violation.Severity - .valueOf(config.getString(CONFIG_IMPORT_MODE_SEVERITY, DEFAULT_IMPORT_MODE_SEVERITY.name()) + final Severity importModeSeverity = Severity + .valueOf(config.getString(keys().importModeSeverity(), DEFAULT_IMPORT_MODE_SEVERITY.name()) .toUpperCase()); - final boolean allowEmptyFilter = hasNonNull(config, CONFIG_ALLOW_EMPTY_FILTER) - && config.getBoolean(CONFIG_ALLOW_EMPTY_FILTER); - final boolean allowRootFilter = hasNonNull(config, CONFIG_ALLOW_ROOT_FILTER) - && config.getBoolean(CONFIG_ALLOW_ROOT_FILTER); + final boolean allowEmptyFilter = hasNonNull(config, keys().allowEmptyFilter()) + && config.getBoolean(keys().allowEmptyFilter()); + final boolean allowRootFilter = hasNonNull(config, keys().allowRootFilter()) + && config.getBoolean(keys().allowRootFilter()); return new Check(importModeSeverity, allowEmptyFilter, allowRootFilter); } static final class Check extends SimpleProgressCheck { - final Violation.Severity importModeSeverity; + final Severity importModeSeverity; final boolean allowEmptyFilter; final boolean allowRootFilter; - Check(final Violation.Severity importModeSeverity, final boolean allowEmptyFilter, final boolean allowRootFilter) { + Check(final Severity importModeSeverity, final boolean allowEmptyFilter, final boolean allowRootFilter) { this.importModeSeverity = importModeSeverity; this.allowEmptyFilter = allowEmptyFilter; this.allowRootFilter = allowRootFilter; @@ -96,7 +131,7 @@ public void beforeExtract(final PackageId packageId, final Session inspectSessio final WorkspaceFilter filter = metaInf.getFilter(); if (filter == null || filter.getFilterSets().isEmpty()) { if (!allowEmptyFilter) { - reportViolation(Violation.Severity.MAJOR, + reportViolation(Severity.MAJOR, "empty workspace filter is not allowed", packageId); } } else { @@ -108,7 +143,7 @@ public void beforeExtract(final PackageId packageId, final Session inspectSessio packageId); } if (!allowRootFilter && "/".equals(filterSet.getRoot())) { - reportViolation(Violation.Severity.MAJOR, + reportViolation(Severity.MAJOR, "root filter sets are not allowed", packageId); } } diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/JcrProperties.java b/core/src/main/java/net/adamcin/oakpal/core/checks/JcrProperties.java index a35a9e009..24694c691 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/JcrProperties.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/JcrProperties.java @@ -24,6 +24,7 @@ import org.apache.jackrabbit.vault.fs.config.MetaInf; import org.apache.jackrabbit.vault.packaging.PackageId; import org.apache.jackrabbit.vault.packaging.PackageProperties; +import org.jetbrains.annotations.NotNull; import javax.jcr.Node; import javax.jcr.RepositoryException; @@ -92,19 +93,60 @@ * */ public final class JcrProperties implements ProgressCheckFactory { - public static final String CONFIG_SCOPE_PATHS = "scopePaths"; - public static final String CONFIG_DENY_NODE_TYPES = "denyNodeTypes"; - public static final String CONFIG_SCOPE_NODE_TYPES = "scopeNodeTypes"; - public static final String CONFIG_PROPERTIES = "properties"; + public interface JsonKeys { + String scopePaths(); + + String denyNodeTypes(); + + String scopeNodeTypes(); + + String properties(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String scopePaths() { + return "scopePaths"; + } + + @Override + public String denyNodeTypes() { + return "denyNodeTypes"; + } + + @Override + public String scopeNodeTypes() { + return "scopeNodeTypes"; + } + + @Override + public String properties() { + return "properties"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_SCOPE_PATHS = keys().scopePaths(); + @Deprecated + public static final String CONFIG_DENY_NODE_TYPES = keys().denyNodeTypes(); + @Deprecated + public static final String CONFIG_SCOPE_NODE_TYPES = keys().scopeNodeTypes(); + @Deprecated + public static final String CONFIG_PROPERTIES = keys().properties(); @Override public ProgressCheck newInstance(final JsonObject config) { - List pathScope = Rule.fromJsonArray(arrayOrEmpty(config, CONFIG_SCOPE_PATHS)); + List pathScope = Rule.fromJsonArray(arrayOrEmpty(config, keys().scopePaths())); - List denyNodeTypes = mapArrayOfStrings(arrayOrEmpty(config, CONFIG_DENY_NODE_TYPES)); - List nodeTypeScope = mapArrayOfStrings(arrayOrEmpty(config, CONFIG_SCOPE_NODE_TYPES)); + List denyNodeTypes = mapArrayOfStrings(arrayOrEmpty(config, keys().denyNodeTypes())); + List nodeTypeScope = mapArrayOfStrings(arrayOrEmpty(config, keys().scopeNodeTypes())); List propertyChecks = JcrPropertyConstraints - .fromJsonArray(arrayOrEmpty(config, CONFIG_PROPERTIES)); + .fromJsonArray(arrayOrEmpty(config, keys().properties())); return new Check(pathScope, denyNodeTypes, nodeTypeScope, propertyChecks); } diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/JcrPropertyConstraints.java b/core/src/main/java/net/adamcin/oakpal/core/checks/JcrPropertyConstraints.java index 9ade3b728..a36bdc473 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/JcrPropertyConstraints.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/JcrPropertyConstraints.java @@ -17,9 +17,11 @@ package net.adamcin.oakpal.core.checks; import net.adamcin.oakpal.api.Rule; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleViolation; import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; +import org.jetbrains.annotations.NotNull; import javax.jcr.Node; import javax.jcr.Property; @@ -59,32 +61,98 @@ *
A list of patterns to match against string values of this property. All rules are applied in sequence to each * value of the property. If the type of the last rule to match any value is DENY, a violation is reported.
*
{@code severity}
- *
(default: {@link Violation.Severity#MAJOR}) specify the severity if a violation is + *
(default: {@link Severity#MAJOR}) specify the severity if a violation is * reported by this set of constraints.
* */ public final class JcrPropertyConstraints { - public static final String CONFIG_NAME = "name"; - public static final String CONFIG_DENY_IF_ABSENT = "denyIfAbsent"; - public static final String CONFIG_DENY_IF_PRESENT = "denyIfPresent"; - public static final String CONFIG_DENY_IF_MULTIVALUED = "denyIfMultivalued"; - public static final String CONFIG_REQUIRE_TYPE = "requireType"; - public static final String CONFIG_VALUE_RULES = "valueRules"; - public static final String CONFIG_SEVERITY = "severity"; - public static final Violation.Severity DEFAULT_SEVERITY = Violation.Severity.MAJOR; + public interface JsonKeys { + String name(); + + String denyIfAbsent(); + + String denyIfPresent(); + + String denyIfMultivalued(); + + String requireType(); + + String valueRules(); + + String severity(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String name() { + return "name"; + } + + @Override + public String denyIfAbsent() { + return "denyIfAbsent"; + } + + @Override + public String denyIfPresent() { + return "denyIfPresent"; + } + + @Override + public String denyIfMultivalued() { + return "denyIfMultivalued"; + } + + @Override + public String requireType() { + return "requireType"; + } + + @Override + public String valueRules() { + return "valueRules"; + } + + @Override + public String severity() { + return "severity"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_NAME = keys().name(); + @Deprecated + public static final String CONFIG_DENY_IF_ABSENT = keys().denyIfAbsent(); + @Deprecated + public static final String CONFIG_DENY_IF_PRESENT = keys().denyIfPresent(); + @Deprecated + public static final String CONFIG_DENY_IF_MULTIVALUED = keys().denyIfMultivalued(); + @Deprecated + public static final String CONFIG_REQUIRE_TYPE = keys().requireType(); + @Deprecated + public static final String CONFIG_VALUE_RULES = keys().valueRules(); + @Deprecated + public static final String CONFIG_SEVERITY = keys().severity(); + + public static final Severity DEFAULT_SEVERITY = Severity.MAJOR; public static JcrPropertyConstraints fromJson(final JsonObject checkJson) { - final String name = checkJson.getString(CONFIG_NAME); - final boolean denyIfAbsent = hasNonNull(checkJson, CONFIG_DENY_IF_ABSENT) - && checkJson.getBoolean(CONFIG_DENY_IF_ABSENT); - final boolean denyIfPresent = hasNonNull(checkJson, CONFIG_DENY_IF_PRESENT) - && checkJson.getBoolean(CONFIG_DENY_IF_PRESENT); - final boolean denyIfMultivalued = hasNonNull(checkJson, CONFIG_DENY_IF_MULTIVALUED) - && checkJson.getBoolean(CONFIG_DENY_IF_MULTIVALUED); - final String requireType = checkJson.getString(CONFIG_REQUIRE_TYPE, null); - final List valueRules = Rule.fromJsonArray(arrayOrEmpty(checkJson, CONFIG_VALUE_RULES)); - final Violation.Severity severity = Violation.Severity - .valueOf(checkJson.getString(CONFIG_SEVERITY, DEFAULT_SEVERITY.name()).toUpperCase()); + final String name = checkJson.getString(keys().name()); + final boolean denyIfAbsent = hasNonNull(checkJson, keys().denyIfAbsent()) + && checkJson.getBoolean(keys().denyIfAbsent()); + final boolean denyIfPresent = hasNonNull(checkJson, keys().denyIfPresent()) + && checkJson.getBoolean(keys().denyIfPresent()); + final boolean denyIfMultivalued = hasNonNull(checkJson, keys().denyIfMultivalued()) + && checkJson.getBoolean(keys().denyIfMultivalued()); + final String requireType = checkJson.getString(keys().requireType(), null); + final List valueRules = Rule.fromJsonArray(arrayOrEmpty(checkJson, keys().valueRules())); + final Severity severity = Severity + .valueOf(checkJson.getString(keys().severity(), DEFAULT_SEVERITY.name()).toUpperCase()); return new JcrPropertyConstraints(name, denyIfAbsent, denyIfPresent, denyIfMultivalued, requireType, valueRules, severity); @@ -100,7 +168,7 @@ public static List fromJsonArray(final JsonArray rulesAr private final boolean denyIfMultivalued; private final String requireType; private final List valueRules; - private final Violation.Severity severity; + private final Severity severity; public JcrPropertyConstraints(final String name, final boolean denyIfAbsent, @@ -108,7 +176,7 @@ public JcrPropertyConstraints(final String name, final boolean denyIfMultivalued, final String requireType, final List valueRules, - final Violation.Severity severity) { + final Severity severity) { this.name = name; this.denyIfAbsent = denyIfAbsent; this.denyIfPresent = denyIfPresent; @@ -142,7 +210,7 @@ public List getValueRules() { return valueRules; } - public Violation.Severity getSeverity() { + public Severity getSeverity() { return severity; } diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/Overlaps.java b/core/src/main/java/net/adamcin/oakpal/core/checks/Overlaps.java index 77478e64d..624fe20b5 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/Overlaps.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/Overlaps.java @@ -18,12 +18,13 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ProgressCheckFactory; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter; import org.apache.jackrabbit.vault.fs.config.MetaInf; import org.apache.jackrabbit.vault.packaging.PackageId; import org.apache.jackrabbit.vault.packaging.PackageProperties; +import org.jetbrains.annotations.NotNull; import javax.jcr.Node; import javax.jcr.RepositoryException; @@ -36,12 +37,13 @@ import java.util.stream.Collectors; import static net.adamcin.oakpal.api.JavaxJson.hasNonNull; +import static net.adamcin.oakpal.api.JavaxJson.key; /** * The {@code overlaps} check keeps track of installed package workspace filters, and checks every affected path going * forward against previous workspace filters for overlap, using {@link WorkspaceFilter#contains(String)}. Overlapping - * deletions are reported as {@link Violation.Severity#MAJOR}, whereas other affected paths are - * reported as {@link Violation.Severity#MINOR}. + * deletions are reported as {@link Severity#MAJOR}, whereas other affected paths are + * reported as {@link Severity#MINOR}. *

* This check is sequence-dependent, in that changing the sequence of packages in the scan may result in a different * outcome. It is recommended to test multiple sequences if the actual process for package deployment is undefined or @@ -56,19 +58,36 @@ * */ public final class Overlaps implements ProgressCheckFactory { - public static final String CONFIG_REPORT_ALL_OVERLAPS = "reportAllOverlaps"; + public interface JsonKeys { + String reportAllOverlaps(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String reportAllOverlaps() { + return "reportAllOverlaps"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_REPORT_ALL_OVERLAPS = keys().reportAllOverlaps(); @Override public ProgressCheck newInstance(final JsonObject config) { - final boolean reportAllOverlaps = hasNonNull(config, CONFIG_REPORT_ALL_OVERLAPS) - && config.getBoolean(CONFIG_REPORT_ALL_OVERLAPS); + final boolean reportAllOverlaps = hasNonNull(config, keys().reportAllOverlaps()) + && config.getBoolean(keys().reportAllOverlaps()); return new Check(reportAllOverlaps); } static final class Check extends SimpleProgressCheck { final Map filters = new HashMap<>(); - final Map reported = new HashMap<>(); + final Map reported = new HashMap<>(); final boolean reportAllOverlaps; @@ -100,7 +119,7 @@ Predicate> overlaps(final String p } void findOverlaps(final PackageId currentPackageId, final String path, - final Violation.Severity severity) { + final Severity severity) { // fast escape! no need to belabor the point. if (!reportAllOverlaps && reported.containsKey(currentPackageId) @@ -131,7 +150,7 @@ public void importedPath(final PackageId packageId, final String path, final Nod throws RepositoryException { // don't worry about nodes outside of our own scope. if (filters.get(packageId).contains(path)) { - findOverlaps(packageId, path, Violation.Severity.MINOR); + findOverlaps(packageId, path, Severity.MINOR); } } @@ -139,7 +158,7 @@ public void importedPath(final PackageId packageId, final String path, final Nod public void deletedPath(final PackageId packageId, final String path, final Session inspectSession) throws RepositoryException { // any deletions should be considered major overlap violations. - findOverlaps(packageId, path, Violation.Severity.MAJOR); + findOverlaps(packageId, path, Severity.MAJOR); } } } diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/Paths.java b/core/src/main/java/net/adamcin/oakpal/core/checks/Paths.java index 13a2462a6..9c6decb09 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/Paths.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/Paths.java @@ -19,9 +19,10 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ProgressCheckFactory; import net.adamcin.oakpal.api.Rule; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; +import org.jetbrains.annotations.NotNull; import javax.jcr.Node; import javax.jcr.RepositoryException; @@ -66,20 +67,54 @@ * */ public final class Paths implements ProgressCheckFactory { - public static final String CONFIG_RULES = "rules"; - public static final String CONFIG_DENY_ALL_DELETES = "denyAllDeletes"; - public static final String CONFIG_SEVERITY = "severity"; - public static final Violation.Severity DEFAULT_SEVERITY = Violation.Severity.MAJOR; + public interface JsonKeys { + String rules(); + + String denyAllDeletes(); + + String severity(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String rules() { + return "rules"; + } + + @Override + public String denyAllDeletes() { + return "denyAllDeletes"; + } + + @Override + public String severity() { + return "severity"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_RULES = keys().rules(); + @Deprecated + public static final String CONFIG_DENY_ALL_DELETES = keys().denyAllDeletes(); + @Deprecated + public static final String CONFIG_SEVERITY = keys().severity(); + + public static final Severity DEFAULT_SEVERITY = Severity.MAJOR; @Override public ProgressCheck newInstance(final JsonObject config) { - List rules = Rule.fromJsonArray(arrayOrEmpty(config, CONFIG_RULES)); + List rules = Rule.fromJsonArray(arrayOrEmpty(config, keys().rules())); - final boolean denyAllDeletes = hasNonNull(config, CONFIG_DENY_ALL_DELETES) - && config.getBoolean(CONFIG_DENY_ALL_DELETES); + final boolean denyAllDeletes = hasNonNull(config, keys().denyAllDeletes()) + && config.getBoolean(keys().denyAllDeletes()); - final Violation.Severity severity = Violation.Severity.valueOf( - config.getString(CONFIG_SEVERITY, DEFAULT_SEVERITY.name()).toUpperCase()); + final Severity severity = Severity.valueOf( + config.getString(keys().severity(), DEFAULT_SEVERITY.name()).toUpperCase()); return new Check(rules, denyAllDeletes, severity); } @@ -87,9 +122,9 @@ public ProgressCheck newInstance(final JsonObject config) { static final class Check extends SimpleProgressCheck { private final List rules; private final boolean denyAllDeletes; - private final Violation.Severity severity; + private final Severity severity; - Check(final List rules, final boolean denyAllDeletes, final Violation.Severity severity) { + Check(final List rules, final boolean denyAllDeletes, final Severity severity) { this.rules = rules; this.denyAllDeletes = denyAllDeletes; this.severity = severity; diff --git a/core/src/main/java/net/adamcin/oakpal/core/checks/Subpackages.java b/core/src/main/java/net/adamcin/oakpal/core/checks/Subpackages.java index d894c98e5..5499507cf 100644 --- a/core/src/main/java/net/adamcin/oakpal/core/checks/Subpackages.java +++ b/core/src/main/java/net/adamcin/oakpal/core/checks/Subpackages.java @@ -19,9 +19,10 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ProgressCheckFactory; import net.adamcin.oakpal.api.Rule; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; +import org.jetbrains.annotations.NotNull; import javax.json.JsonObject; import java.util.List; @@ -60,14 +61,39 @@ * */ public final class Subpackages implements ProgressCheckFactory { - public static final String CONFIG_RULES = "rules"; - public static final String CONFIG_DENY_ALL = "denyAll"; + public interface JsonKeys { + String rules(); + + String denyAll(); + } + + private static final JsonKeys KEYS = new JsonKeys() { + @Override + public String rules() { + return "rules"; + } + + @Override + public String denyAll() { + return "denyAll"; + } + }; + + @NotNull + public static JsonKeys keys() { + return KEYS; + } + + @Deprecated + public static final String CONFIG_RULES = keys().rules(); + @Deprecated + public static final String CONFIG_DENY_ALL = keys().denyAll(); @Override public ProgressCheck newInstance(final JsonObject config) { - List rules = Rule.fromJsonArray(arrayOrEmpty(config, CONFIG_RULES)); + List rules = Rule.fromJsonArray(arrayOrEmpty(config, keys().rules())); - final boolean denyAll = hasNonNull(config, CONFIG_DENY_ALL) && config.getBoolean(CONFIG_DENY_ALL); + final boolean denyAll = hasNonNull(config, keys().denyAll()) && config.getBoolean(keys().denyAll()); return new Check(rules, denyAll); } @@ -89,13 +115,13 @@ public String getCheckName() { @Override public void identifySubpackage(final PackageId packageId, final PackageId parentId) { if (denyAll) { - reportViolation(Violation.Severity.MAJOR, + reportViolation(Severity.MAJOR, String.format("subpackage %s included by %s. no subpackages are allowed.", packageId, parentId), packageId); } else { final Rule lastMatch = Rule.lastMatch(rules, packageId.toString()); if (lastMatch.isDeny()) { - reportViolation(Violation.Severity.MAJOR, + reportViolation(Severity.MAJOR, String.format("subpackage %s included by %s matches deny pattern %s", packageId.toString(), parentId.toString(), lastMatch.getPattern().pattern()), packageId); diff --git a/core/src/test/java/net/adamcin/oakpal/core/CheckReportTest.java b/core/src/test/java/net/adamcin/oakpal/core/CheckReportTest.java index e7f58f500..f930e6423 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/CheckReportTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/CheckReportTest.java @@ -31,6 +31,7 @@ import javax.json.JsonObject; import net.adamcin.oakpal.api.JavaxJson; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleViolation; import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; @@ -43,18 +44,18 @@ public void testGetViolationsBySeverity() { final CheckReport report = mock(CheckReport.class); final List violations = new ArrayList<>(); when(report.getViolations()).thenReturn(violations); - doCallRealMethod().when(report).getViolations(nullable(Violation.Severity.class)); + doCallRealMethod().when(report).getViolations(nullable(Severity.class)); assertEquals("violations size", 0, report.getViolations(null).size()); - violations.add(new SimpleViolation(Violation.Severity.MINOR, "minor violation")); - violations.add(new SimpleViolation(Violation.Severity.MAJOR, "major violation")); - violations.add(new SimpleViolation(Violation.Severity.SEVERE, "severe violation")); + violations.add(new SimpleViolation(Severity.MINOR, "minor violation")); + violations.add(new SimpleViolation(Severity.MAJOR, "major violation")); + violations.add(new SimpleViolation(Severity.SEVERE, "severe violation")); assertEquals("violations size after populating", 3, report.getViolations(null).size()); - assertEquals("violations size at or above minor", 3, report.getViolations(Violation.Severity.MINOR).size()); - assertEquals("violations size at or above major", 2, report.getViolations(Violation.Severity.MAJOR).size()); - assertEquals("violations size at or above severe", 1, report.getViolations(Violation.Severity.SEVERE).size()); + assertEquals("violations size at or above minor", 3, report.getViolations(Severity.MINOR).size()); + assertEquals("violations size at or above major", 2, report.getViolations(Severity.MAJOR).size()); + assertEquals("violations size at or above severe", 1, report.getViolations(Severity.SEVERE).size()); } @Test @@ -63,18 +64,18 @@ public void testToJson() { final List violations = new ArrayList<>(); when(report.getViolations()).thenReturn(violations); when(report.getCheckName()).thenReturn("mock"); - doCallRealMethod().when(report).getViolations(nullable(Violation.Severity.class)); + doCallRealMethod().when(report).getViolations(nullable(Severity.class)); doCallRealMethod().when(report).toJson(); final PackageId fooId = PackageId.fromString("test:foo:1.0-SNAPSHOT"); final PackageId barId = PackageId.fromString("test:bar:1.0-SNAPSHOT"); - violations.add(new SimpleViolation(Violation.Severity.MINOR, "minor violation")); - violations.add(new SimpleViolation(Violation.Severity.MAJOR, "major violation", fooId)); - violations.add(new SimpleViolation(Violation.Severity.SEVERE, "severe violation", fooId, barId)); + violations.add(new SimpleViolation(Severity.MINOR, "minor violation")); + violations.add(new SimpleViolation(Severity.MAJOR, "major violation", fooId)); + violations.add(new SimpleViolation(Severity.SEVERE, "severe violation", fooId, barId)); JsonObject json = report.toJson(); assertNotNull("json is not null", json); - assertEquals("checkName should be", "mock", json.getString(ReportMapper.KEY_CHECK_NAME)); - JsonArray violationArray = json.getJsonArray(ReportMapper.KEY_VIOLATIONS); + assertEquals("checkName should be", "mock", json.getString(ReportMapper.keys().checkName())); + JsonArray violationArray = json.getJsonArray(ReportMapper.keys().violations()); List fromJson = JavaxJson.mapArrayOfObjects(violationArray, SimpleViolation::fromJson); assertEquals("fromJson should be an array of three simple violations", 3, fromJson.size()); assertEquals("foo package is reported twice", 2, diff --git a/core/src/test/java/net/adamcin/oakpal/core/CheckSpecTest.java b/core/src/test/java/net/adamcin/oakpal/core/CheckSpecTest.java index 387e98329..672f4fe2f 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/CheckSpecTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/CheckSpecTest.java @@ -16,6 +16,16 @@ package net.adamcin.oakpal.core; +import net.adamcin.oakpal.api.ProgressCheck; +import org.junit.Test; + +import javax.json.JsonObject; +import javax.json.JsonValue; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import static net.adamcin.oakpal.api.JavaxJson.key; import static net.adamcin.oakpal.api.JavaxJson.obj; import static org.junit.Assert.assertEquals; @@ -24,16 +34,6 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import javax.json.JsonObject; -import javax.json.JsonValue; - -import net.adamcin.oakpal.api.ProgressCheck; -import org.junit.Test; - public class CheckSpecTest { @Test @@ -349,21 +349,22 @@ public void testGetters() { @Test public void testFromJson() { + final CheckSpec.JsonKeys keys = CheckSpec.keys(); final JsonObject specJson = obj() - .key(CheckSpec.KEY_NAME, CheckSpec.KEY_NAME) - .key(CheckSpec.KEY_IMPL, CheckSpec.KEY_IMPL) - .key(CheckSpec.KEY_INLINE_SCRIPT, CheckSpec.KEY_INLINE_SCRIPT) - .key(CheckSpec.KEY_INLINE_ENGINE, CheckSpec.KEY_INLINE_ENGINE) - .key(CheckSpec.KEY_CONFIG, key("foo", "bar")) - .key(CheckSpec.KEY_TEMPLATE, CheckSpec.KEY_TEMPLATE) - .key(CheckSpec.KEY_SKIP, true) + .key(keys.name(), keys.name()) + .key(keys.impl(), keys.impl()) + .key(keys.inlineScript(), keys.inlineScript()) + .key(keys.inlineEngine(), keys.inlineEngine()) + .key(keys.config(), key("foo", "bar")) + .key(keys.template(), keys.template()) + .key(keys.skip(), true) .get(); final CheckSpec spec = CheckSpec.fromJson(specJson); - assertEquals("fromJson getName same", CheckSpec.KEY_NAME, spec.getName()); - assertEquals("fromJson getImpl same", CheckSpec.KEY_IMPL, spec.getImpl()); - assertEquals("fromJson getTemplate same", CheckSpec.KEY_TEMPLATE, spec.getTemplate()); - assertEquals("fromJson getInlineScript same", CheckSpec.KEY_INLINE_SCRIPT, spec.getInlineScript()); - assertEquals("fromJson getInlineEngine same", CheckSpec.KEY_INLINE_ENGINE, spec.getInlineEngine()); + assertEquals("fromJson getName same", keys.name(), spec.getName()); + assertEquals("fromJson getImpl same", keys.impl(), spec.getImpl()); + assertEquals("fromJson getTemplate same", keys.template(), spec.getTemplate()); + assertEquals("fromJson getInlineScript same", keys.inlineScript(), spec.getInlineScript()); + assertEquals("fromJson getInlineEngine same", keys.inlineEngine(), spec.getInlineEngine()); assertEquals("fromJson getConfig same", key("foo", "bar").get(), spec.getConfig()); assertTrue("fromJson isSkip true", spec.isSkip()); assertEquals("json should be equal", specJson, spec.toJson()); @@ -373,14 +374,15 @@ public void testFromJson() { @Test public void testCopyOf() { + final CheckSpec.JsonKeys keys = CheckSpec.keys(); final JsonObject specJson = obj() - .key(CheckSpec.KEY_NAME, CheckSpec.KEY_NAME) - .key(CheckSpec.KEY_IMPL, CheckSpec.KEY_IMPL) - .key(CheckSpec.KEY_INLINE_SCRIPT, CheckSpec.KEY_INLINE_SCRIPT) - .key(CheckSpec.KEY_INLINE_ENGINE, CheckSpec.KEY_INLINE_ENGINE) - .key(CheckSpec.KEY_CONFIG, key("foo", "bar")) - .key(CheckSpec.KEY_TEMPLATE, CheckSpec.KEY_TEMPLATE) - .key(CheckSpec.KEY_SKIP, true) + .key(keys.name(), keys.name()) + .key(keys.impl(), keys.impl()) + .key(keys.inlineScript(), keys.inlineScript()) + .key(keys.inlineEngine(), keys.inlineEngine()) + .key(keys.config(), key("foo", "bar")) + .key(keys.template(), keys.template()) + .key(keys.skip(), true) .get(); final CheckSpec spec = CheckSpec.fromJson(specJson); assertEquals("copy should equal copied", spec, CheckSpec.copyOf(spec)); diff --git a/core/src/test/java/net/adamcin/oakpal/core/ChecklistTest.java b/core/src/test/java/net/adamcin/oakpal/core/ChecklistTest.java index 8df07b126..de7019c28 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/ChecklistTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/ChecklistTest.java @@ -77,20 +77,21 @@ public void testFromJSON() throws Exception { @Test public void testChecklistKeyComparator() { - final String[] inputValues1 = Checklist.KEY_ORDER.toArray(new String[0]); + final Checklist.JsonKeys keys = Checklist.keys(); + final String[] inputValues1 = keys.orderedKeys().toArray(new String[0]); Arrays.sort(inputValues1, Checklist.checklistKeyComparator.reversed()); Arrays.sort(inputValues1, Checklist.checklistKeyComparator); assertArrayEquals("sort reverse sort should be stable", - Checklist.KEY_ORDER.toArray(new String[0]), inputValues1); + keys.orderedKeys().toArray(new String[0]), inputValues1); - final String[] inputValues2 = new String[]{"foo", Checklist.KEY_NAME}; - final String[] expectValues2 = new String[]{Checklist.KEY_NAME, "foo"}; + final String[] inputValues2 = new String[]{"foo", keys.name()}; + final String[] expectValues2 = new String[]{keys.name(), "foo"}; Arrays.sort(inputValues2, Checklist.checklistKeyComparator); assertArrayEquals("sort unknown keys after known keys", expectValues2, inputValues2); - final String[] inputValues2b = new String[]{Checklist.KEY_NAME, "foo"}; - final String[] expectValues2b = new String[]{Checklist.KEY_NAME, "foo"}; + final String[] inputValues2b = new String[]{keys.name(), "foo"}; + final String[] expectValues2b = new String[]{keys.name(), "foo"}; Arrays.sort(inputValues2b, Checklist.checklistKeyComparator); assertArrayEquals("sort unknown keys after known keys", expectValues2b, inputValues2b); @@ -104,9 +105,10 @@ public void testChecklistKeyComparator() { @Test public void testComparingJsonKeys() { - final JsonObject obj1 = key("id", Checklist.KEY_CHECKS).get(); - final JsonObject obj2 = key("id", Checklist.KEY_CND_NAMES).get(); - final JsonObject obj3 = key("id", Checklist.KEY_CND_URLS).get(); + final Checklist.JsonKeys keys = Checklist.keys(); + final JsonObject obj1 = key("id", keys.checks()).get(); + final JsonObject obj2 = key("id", keys.cndNames()).get(); + final JsonObject obj3 = key("id", keys.cndUrls()).get(); final JsonObject[] inputValues1 = new JsonObject[]{obj2, obj3, obj1}; final JsonObject[] expectValues1 = new JsonObject[]{obj1, obj2, obj3}; Arrays.sort(inputValues1, Checklist.comparingJsonKeys(obj -> obj.getString("id"))); @@ -190,12 +192,12 @@ public void testBuilderWithForcedRoots() { Checklist.Builder builderWithForcedRoots = new Checklist.Builder("test"); final List forcedRoots = Arrays.asList( ForcedRoot.fromJson(obj() - .key(ForcedRoot.KEY_PATH, "/test/foo") - .key(ForcedRoot.KEY_PRIMARY_TYPE, "foo:primaryType") + .key(ForcedRoot.keys().path(), "/test/foo") + .key(ForcedRoot.keys().primaryType(), "foo:primaryType") .get()), ForcedRoot.fromJson(obj() - .key(ForcedRoot.KEY_PATH, "/test/bar") - .key(ForcedRoot.KEY_PRIMARY_TYPE, "bar:primaryType") + .key(ForcedRoot.keys().path(), "/test/bar") + .key(ForcedRoot.keys().primaryType(), "bar:primaryType") .get())); builderWithForcedRoots.withForcedRoots(forcedRoots); assertEquals("forced roots pass thru", @@ -205,23 +207,23 @@ public void testBuilderWithForcedRoots() { @Test public void testBuilderIsValidCheckSpec() { Checklist.Builder builder = new Checklist.Builder("test"); - CheckSpec validSpec = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid") - .key(CheckSpec.KEY_IMPL, "impl").get()); + CheckSpec validSpec = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid") + .key(CheckSpec.keys().impl(), "impl").get()); assertTrue("valid spec isValid: " + validSpec.getName(), builder.isValidCheckspec(validSpec)); - CheckSpec abstractSpec = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid").get()); + CheckSpec abstractSpec = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid").get()); assertFalse("abstract spec not isValid: " + abstractSpec.getName(), builder.isValidCheckspec(abstractSpec)); - CheckSpec nullNameSpec = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, null) - .key(CheckSpec.KEY_IMPL, "impl").get()); + CheckSpec nullNameSpec = CheckSpec.fromJson(key(CheckSpec.keys().name(), null) + .key(CheckSpec.keys().impl(), "impl").get()); assertFalse("nullName spec not isValid: " + nullNameSpec.getName(), builder.isValidCheckspec(nullNameSpec)); - CheckSpec emptyNameSpec = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "") - .key(CheckSpec.KEY_IMPL, "impl").get()); + CheckSpec emptyNameSpec = CheckSpec.fromJson(key(CheckSpec.keys().name(), "") + .key(CheckSpec.keys().impl(), "impl").get()); assertFalse("emptyName spec not isValid: " + emptyNameSpec.getName(), builder.isValidCheckspec(emptyNameSpec)); - CheckSpec slashNameSpec = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid/notValid") - .key(CheckSpec.KEY_IMPL, "impl").get()); + CheckSpec slashNameSpec = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid/notValid") + .key(CheckSpec.keys().impl(), "impl").get()); assertFalse("slashName spec not isValid: " + slashNameSpec.getName(), builder.isValidCheckspec(slashNameSpec)); } @@ -229,12 +231,12 @@ public void testBuilderIsValidCheckSpec() { @Test public void testBuilderWithChecks() { final Checklist.Builder builder = new Checklist.Builder("test"); - CheckSpec validSpec1 = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid1") - .key(CheckSpec.KEY_IMPL, "impl").get()); - CheckSpec validSpec2 = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid2") - .key(CheckSpec.KEY_IMPL, "impl").get()); - CheckSpec slashNameSpec = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid/notValid") - .key(CheckSpec.KEY_IMPL, "impl").get()); + CheckSpec validSpec1 = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid1") + .key(CheckSpec.keys().impl(), "impl").get()); + CheckSpec validSpec2 = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid2") + .key(CheckSpec.keys().impl(), "impl").get()); + CheckSpec slashNameSpec = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid/notValid") + .key(CheckSpec.keys().impl(), "impl").get()); assertFalse("slashName spec not isValid: " + slashNameSpec.getName(), builder.isValidCheckspec(slashNameSpec)); final String prefix = "test/"; @@ -276,14 +278,14 @@ public void testAsInitStage() throws Exception { builder.withJcrPrivileges(privileges); final List forcedRoots = Arrays.asList( ForcedRoot.fromJson(obj() - .key(ForcedRoot.KEY_PATH, "/test/foo") - .key(ForcedRoot.KEY_PRIMARY_TYPE, "foo:primaryType") - .key(ForcedRoot.KEY_MIXIN_TYPES, arr().val("foo:mixinType")) + .key(ForcedRoot.keys().path(), "/test/foo") + .key(ForcedRoot.keys().primaryType(), "foo:primaryType") + .key(ForcedRoot.keys().mixinTypes(), arr().val("foo:mixinType")) .get()), ForcedRoot.fromJson(obj() - .key(ForcedRoot.KEY_PATH, "/test/bar") - .key(ForcedRoot.KEY_PRIMARY_TYPE, "bar:primaryType") - .key(ForcedRoot.KEY_MIXIN_TYPES, arr().val("bar:mixinType")) + .key(ForcedRoot.keys().path(), "/test/bar") + .key(ForcedRoot.keys().primaryType(), "bar:primaryType") + .key(ForcedRoot.keys().mixinTypes(), arr().val("bar:mixinType")) .get())); builder.withForcedRoots(forcedRoots); InitStage initStage = builder.build().asInitStage(); @@ -338,33 +340,34 @@ public void testToJsonFromBuilder() { builder.withJcrPrivileges(privileges); final List forcedRoots = Arrays.asList( ForcedRoot.fromJson(obj() - .key(ForcedRoot.KEY_PATH, "/test/foo") - .key(ForcedRoot.KEY_PRIMARY_TYPE, "foo:primaryType") - .key(ForcedRoot.KEY_MIXIN_TYPES, arr().val("foo:mixinType")) + .key(ForcedRoot.keys().path(), "/test/foo") + .key(ForcedRoot.keys().primaryType(), "foo:primaryType") + .key(ForcedRoot.keys().mixinTypes(), arr().val("foo:mixinType")) .get()), ForcedRoot.fromJson(obj() - .key(ForcedRoot.KEY_PATH, "/test/bar") - .key(ForcedRoot.KEY_PRIMARY_TYPE, "bar:primaryType") - .key(ForcedRoot.KEY_MIXIN_TYPES, arr().val("bar:mixinType")) + .key(ForcedRoot.keys().path(), "/test/bar") + .key(ForcedRoot.keys().primaryType(), "bar:primaryType") + .key(ForcedRoot.keys().mixinTypes(), arr().val("bar:mixinType")) .get())); final JsonArray forcedRootsJson = JavaxJson.wrap(forcedRoots).asJsonArray(); builder.withForcedRoots(forcedRoots); - CheckSpec validSpec1 = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid1") - .key(CheckSpec.KEY_IMPL, "impl").get()); - CheckSpec validSpec2 = CheckSpec.fromJson(key(CheckSpec.KEY_NAME, "valid2") - .key(CheckSpec.KEY_IMPL, "impl").get()); + CheckSpec validSpec1 = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid1") + .key(CheckSpec.keys().impl(), "impl").get()); + CheckSpec validSpec2 = CheckSpec.fromJson(key(CheckSpec.keys().name(), "valid2") + .key(CheckSpec.keys().impl(), "impl").get()); final List checks = Arrays.asList(validSpec1, validSpec2); final JsonArray checksJson = JavaxJson.wrap(checks).asJsonArray(); builder.withChecks(checks); final Checklist checklist = builder.build(); + final Checklist.JsonKeys keys = Checklist.keys(); final JsonObject expectJson = obj() - .key(Checklist.KEY_NAME, "name") - .key(Checklist.KEY_CHECKS, checksJson) - .key(Checklist.KEY_FORCED_ROOTS, forcedRootsJson) - .key(Checklist.KEY_CND_URLS, cndUrlsJson) - .key(Checklist.KEY_JCR_NODETYPES, nodetypesJson) - .key(Checklist.KEY_JCR_PRIVILEGES, privilegesJson) - .key(Checklist.KEY_JCR_NAMESPACES, jcrNamespacesJson) + .key(keys.name(), "name") + .key(keys.checks(), checksJson) + .key(keys.forcedRoots(), forcedRootsJson) + .key(keys.cndUrls(), cndUrlsJson) + .key(keys.jcrNodetypes(), nodetypesJson) + .key(keys.jcrPrivileges(), privilegesJson) + .key(keys.jcrNamespaces(), jcrNamespacesJson) .get(); final JsonObject json = checklist.toJson(); assertEquals("toJson should match", expectJson, json); diff --git a/core/src/test/java/net/adamcin/oakpal/core/DefaultErrorListenerTest.java b/core/src/test/java/net/adamcin/oakpal/core/DefaultErrorListenerTest.java index 2cbdf328d..c432a4666 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/DefaultErrorListenerTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/DefaultErrorListenerTest.java @@ -18,8 +18,8 @@ import static org.junit.Assert.assertEquals; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleViolation; -import net.adamcin.oakpal.api.Violation; import org.junit.Test; public class DefaultErrorListenerTest { @@ -29,9 +29,9 @@ public class DefaultErrorListenerTest { @Test public void testGetReportedViolations() { final DefaultErrorListener errorListener = new DefaultErrorListener(); - errorListener.reportViolation(new SimpleViolation(Violation.Severity.MINOR, "minor")); - errorListener.reportViolation(new SimpleViolation(Violation.Severity.MAJOR, "major")); - errorListener.reportViolation(new SimpleViolation(Violation.Severity.SEVERE, "severe")); + errorListener.reportViolation(new SimpleViolation(Severity.MINOR, "minor")); + errorListener.reportViolation(new SimpleViolation(Severity.MAJOR, "major")); + errorListener.reportViolation(new SimpleViolation(Severity.SEVERE, "severe")); assertEquals("should have reported", 3, errorListener.getReportedViolations().size()); } diff --git a/core/src/test/java/net/adamcin/oakpal/core/ForcedRootTest.java b/core/src/test/java/net/adamcin/oakpal/core/ForcedRootTest.java index 4afe5d820..9450a4e2b 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/ForcedRootTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/ForcedRootTest.java @@ -16,15 +16,20 @@ package net.adamcin.oakpal.core; -import static net.adamcin.oakpal.api.JavaxJson.key; -import static net.adamcin.oakpal.api.JavaxJson.obj; -import static org.junit.Assert.*; +import org.junit.Test; +import javax.json.JsonValue; import java.util.Collections; import java.util.List; -import javax.json.JsonValue; -import org.junit.Test; +import static net.adamcin.oakpal.api.JavaxJson.key; +import static net.adamcin.oakpal.api.JavaxJson.obj; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; public class ForcedRootTest { @@ -92,6 +97,7 @@ public void testGetNamespacePrefixes() { @Test public void testFromJson() { + final ForcedRoot.JsonKeys keys = ForcedRoot.keys(); final String path = "/correct/path"; final String primaryType = "primaryType"; final List mixinTypes = Collections.singletonList("mixinType"); @@ -101,18 +107,18 @@ public void testFromJson() { assertTrue("empty root has empty mixinTypes", rootEmpty.getMixinTypes().isEmpty()); final ForcedRoot rootPath = ForcedRoot.fromJson( - obj().key(ForcedRoot.KEY_PATH, path).get()); + obj().key(keys.path(), path).get()); assertEquals("path root has correct path", path, rootPath.getPath()); final ForcedRoot rootPrimaryType = ForcedRoot.fromJson( - obj().key(ForcedRoot.KEY_PRIMARY_TYPE, primaryType).get()); + obj().key(keys.primaryType(), primaryType).get()); assertEquals("primaryType root has correct primaryType", primaryType, rootPrimaryType.getPrimaryType()); final ForcedRoot rootMixinTypes = ForcedRoot.fromJson( - obj().key(ForcedRoot.KEY_MIXIN_TYPES, mixinTypes).get()); + obj().key(keys.mixinTypes(), mixinTypes).get()); assertEquals("mixinTypes root has correct mixinTypes", mixinTypes, rootMixinTypes.getMixinTypes()); @@ -120,6 +126,7 @@ public void testFromJson() { @Test public void testToJson() { + final ForcedRoot.JsonKeys keys = ForcedRoot.keys(); final String path = "/correct/path"; final String primaryType = "primaryType"; final List mixinTypes = Collections.singletonList("mixinType"); @@ -130,15 +137,15 @@ public void testToJson() { final ForcedRoot pathRoot = new ForcedRoot().withPath(path); assertEquals("path root toJson should have path", - key(ForcedRoot.KEY_PATH, path).get(), pathRoot.toJson()); + key(keys.path(), path).get(), pathRoot.toJson()); final ForcedRoot primaryTypeRoot = new ForcedRoot().withPrimaryType(primaryType); assertEquals("primaryType root toJson should have primaryType", - key(ForcedRoot.KEY_PRIMARY_TYPE, primaryType).get(), primaryTypeRoot.toJson()); + key(keys.primaryType(), primaryType).get(), primaryTypeRoot.toJson()); final ForcedRoot mixinTypeRoot = new ForcedRoot().withMixinTypes(mixinTypes.get(0)); assertEquals("mixinTypes root toJson should have mixinTypes", - key(ForcedRoot.KEY_MIXIN_TYPES, mixinTypes).get(), mixinTypeRoot.toJson()); + key(keys.mixinTypes(), mixinTypes).get(), mixinTypeRoot.toJson()); } @Test @@ -151,6 +158,7 @@ public void testCompareTo() { @Test public void testToString() { + final ForcedRoot.JsonKeys keys = ForcedRoot.keys(); final String path = "/correct/path"; final String primaryType = "primaryType"; final List mixinTypes = Collections.singletonList("mixinType"); @@ -159,9 +167,9 @@ public void testToString() { .withPrimaryType(primaryType) .withMixinTypes(mixinTypes.get(0)); final String jsonString = root.toString(); - final String expectString = key(ForcedRoot.KEY_PATH, path) - .key(ForcedRoot.KEY_PRIMARY_TYPE, primaryType) - .key(ForcedRoot.KEY_MIXIN_TYPES, mixinTypes) + final String expectString = key(keys.path(), path) + .key(keys.primaryType(), primaryType) + .key(keys.mixinTypes(), mixinTypes) .get().toString(); assertEquals("expect json string for toString", expectString, jsonString); } diff --git a/core/src/test/java/net/adamcin/oakpal/core/JcrNsTest.java b/core/src/test/java/net/adamcin/oakpal/core/JcrNsTest.java index d485a0b2f..80ab6ba20 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/JcrNsTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/JcrNsTest.java @@ -27,16 +27,17 @@ public class JcrNsTest { final String prefix = "foo"; final String uri = "http://foo.com"; + private static final JcrNs.JsonKeys KEYS = JcrNs.keys(); @Test public void testFromJson() { assertNull("should be null if either prefix and uri are missing", JcrNs.fromJson(JsonValue.EMPTY_JSON_OBJECT)); assertNull("should be null prefix is missing", - JcrNs.fromJson(key(JcrNs.KEY_PREFIX, prefix).get())); + JcrNs.fromJson(key(KEYS.prefix(), prefix).get())); assertNull("should be null if uri is missing", - JcrNs.fromJson(key(JcrNs.KEY_URI, uri).get())); - JcrNs complete = JcrNs.fromJson(key(JcrNs.KEY_PREFIX, prefix).key(JcrNs.KEY_URI, uri).get()); + JcrNs.fromJson(key(KEYS.uri(), uri).get())); + JcrNs complete = JcrNs.fromJson(key(KEYS.prefix(), prefix).key(KEYS.uri(), uri).get()); assertNotNull("complete should not be null", complete); assertEquals("complete prefix should be", prefix, complete.getPrefix()); assertEquals("complete prefix should be", uri, complete.getUri()); @@ -52,14 +53,14 @@ public void testCreate() { @Test public void testToJson() { - JsonObject expect = key(JcrNs.KEY_PREFIX, prefix).key(JcrNs.KEY_URI, uri).get(); + JsonObject expect = key(KEYS.prefix(), prefix).key(KEYS.uri(), uri).get(); JcrNs complete = JcrNs.create(prefix, uri); assertEquals("expect json", expect, complete.toJson()); } @Test public void testToString() { - String expect = key(JcrNs.KEY_PREFIX, prefix).key(JcrNs.KEY_URI, uri).get().toString(); + String expect = key(KEYS.prefix(), prefix).key(KEYS.uri(), uri).get().toString(); JcrNs complete = JcrNs.create(prefix, uri); assertEquals("expect json string", expect, complete.toString()); } diff --git a/core/src/test/java/net/adamcin/oakpal/core/LocatorTest.java b/core/src/test/java/net/adamcin/oakpal/core/LocatorTest.java index 2d5df8d49..19d5f46b6 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/LocatorTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/LocatorTest.java @@ -16,9 +16,10 @@ package net.adamcin.oakpal.core; -import net.adamcin.oakpal.core.checks.Echo; import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.Violation; +import net.adamcin.oakpal.core.checks.Echo; +import net.adamcin.oakpal.core.checks.Paths; import org.junit.Test; import java.util.ArrayList; @@ -62,6 +63,9 @@ public void testLoadProgressCheck() throws Exception { assertNotNull("echo should load by class name, with config, with cl", Locator.loadProgressCheck(Echo.class.getName(), obj().get(), getClass().getClassLoader())); + assertNotNull("paths should load by factory class name, with config, with cl", + Locator.loadProgressCheck(Paths.class.getName(), obj().get(), getClass().getClassLoader())); + assertNotNull("simpleHandler.js should load by resource name, with config, with cl", Locator.loadProgressCheck("simpleHandler.js", obj().get(), getClass().getClassLoader())); diff --git a/core/src/test/java/net/adamcin/oakpal/core/ReportMapperTest.java b/core/src/test/java/net/adamcin/oakpal/core/ReportMapperTest.java index 09a1d32d7..32a8df5c6 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/ReportMapperTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/ReportMapperTest.java @@ -26,8 +26,8 @@ import java.util.ArrayList; import java.util.List; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleViolation; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; import org.junit.Before; import org.junit.Test; @@ -46,15 +46,15 @@ public void testReportsToJson() throws Exception { final List originalReports = asList( new SimpleReport("test/first", singletonList( - new SimpleViolation(Violation.Severity.MINOR, + new SimpleViolation(Severity.MINOR, "one", PackageId.fromString("test:first"))) ), new SimpleReport("test/second", asList( - new SimpleViolation(Violation.Severity.MINOR, + new SimpleViolation(Severity.MINOR, "one", PackageId.fromString("test:first")), - new SimpleViolation(Violation.Severity.MINOR, + new SimpleViolation(Severity.MINOR, "two", PackageId.fromString("test:first"), PackageId.fromString("test:second")) @@ -75,15 +75,15 @@ public void testWriteThenRead() throws Exception { final List originalReports = asList( new SimpleReport("test/first", singletonList( - new SimpleViolation(Violation.Severity.MINOR, + new SimpleViolation(Severity.MINOR, "one", PackageId.fromString("test:first"))) ), new SimpleReport("test/second", asList( - new SimpleViolation(Violation.Severity.MINOR, + new SimpleViolation(Severity.MINOR, "one", PackageId.fromString("test:first")), - new SimpleViolation(Violation.Severity.MINOR, + new SimpleViolation(Severity.MINOR, "two", PackageId.fromString("test:first"), PackageId.fromString("test:second")) diff --git a/core/src/test/java/net/adamcin/oakpal/core/ScriptProgressCheckTest.java b/core/src/test/java/net/adamcin/oakpal/core/ScriptProgressCheckTest.java index 6a94434dd..e0a4bd3ce 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/ScriptProgressCheckTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/ScriptProgressCheckTest.java @@ -18,6 +18,7 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.ProgressCheckFactory; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.fs.config.MetaInf; import org.apache.jackrabbit.vault.packaging.PackageId; @@ -100,11 +101,11 @@ public void testScriptHelper() { assertEquals("violations size", 3, violations.size()); assertTrue("test_0 minor violation", violations.stream() - .anyMatch(viol -> viol.getSeverity() == Violation.Severity.MINOR && viol.getPackages().contains(id0))); + .anyMatch(viol -> viol.getSeverity() == Severity.MINOR && viol.getPackages().contains(id0))); assertTrue("test_1 major violation", violations.stream() - .anyMatch(viol -> viol.getSeverity() == Violation.Severity.MAJOR && viol.getPackages().contains(id1))); + .anyMatch(viol -> viol.getSeverity() == Severity.MAJOR && viol.getPackages().contains(id1))); assertTrue("test_2 severe violation", violations.stream() - .anyMatch(viol -> viol.getSeverity() == Violation.Severity.SEVERE && viol.getPackages().contains(id2))); + .anyMatch(viol -> viol.getSeverity() == Severity.SEVERE && viol.getPackages().contains(id2))); check.startedScan(); diff --git a/core/src/test/java/net/adamcin/oakpal/core/SimpleReportTest.java b/core/src/test/java/net/adamcin/oakpal/core/SimpleReportTest.java index c9cc0ed5c..c46e4e417 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/SimpleReportTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/SimpleReportTest.java @@ -16,6 +16,7 @@ package net.adamcin.oakpal.core; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; import net.adamcin.oakpal.api.SimpleViolation; import net.adamcin.oakpal.api.Violation; @@ -42,8 +43,8 @@ public void testConstruct() { assertTrue("violations are empty", report.getViolations().isEmpty()); final PackageId id = PackageId.fromString("my_packages:test:1.0"); SimpleReport reportMore = new SimpleReport("moreReport", Arrays.asList( - new SimpleViolation(Violation.Severity.SEVERE, "severe", id), - new SimpleViolation(Violation.Severity.MINOR, "minor", id))); + new SimpleViolation(Severity.SEVERE, "severe", id), + new SimpleViolation(Severity.MINOR, "minor", id))); assertEquals("check name is", "moreReport", reportMore.getCheckName()); assertEquals("violations are 2", 2, reportMore.getViolations().size()); @@ -53,8 +54,8 @@ public void testConstruct() { public void testEqualsAndHash() { final PackageId id = PackageId.fromString("my_packages:test:1.0"); SimpleReport original = new SimpleReport("moreReport", Arrays.asList( - new SimpleViolation(Violation.Severity.SEVERE, "severe", id), - new SimpleViolation(Violation.Severity.MINOR, "minor", id))); + new SimpleViolation(Severity.SEVERE, "severe", id), + new SimpleViolation(Severity.MINOR, "minor", id))); assertFalse("null not equal", original.equals(null)); assertNotEquals("other not equal", original, new Object()); @@ -65,7 +66,7 @@ public void testEqualsAndHash() { assertEquals("copy hash is equal", original.hashCode(), copy.hashCode()); SimpleReport different = new SimpleReport("different", Arrays.asList( - new SimpleViolation(Violation.Severity.MAJOR, "major", id))); + new SimpleViolation(Severity.MAJOR, "major", id))); assertNotEquals("different is not equal", original, different); assertNotEquals("different hash is not equal", original.hashCode(), different.hashCode()); } @@ -83,19 +84,19 @@ public void testGenerateReportFromProgressCheck() { assertNotNull("report not null", report); assertEquals("report name", check.getClass().getSimpleName(), report.getCheckName()); assertEquals("violations are", - Collections.singletonList(new SimpleViolation(Violation.Severity.MINOR, "minor")), + Collections.singletonList(new SimpleViolation(Severity.MINOR, "minor")), report.getViolations()); } @Test public void testGenerateReportFromErrorListener() { TestErrorListener errorListener = new TestErrorListener(); - errorListener.reportViolation(new SimpleViolation(Violation.Severity.MINOR, "minor")); + errorListener.reportViolation(new SimpleViolation(Severity.MINOR, "minor")); SimpleReport report = SimpleReport.generateReport(errorListener); assertNotNull("report not null", report); assertEquals("report name", errorListener.getClass().getSimpleName(), report.getCheckName()); assertEquals("violations are", - Collections.singletonList(new SimpleViolation(Violation.Severity.MINOR, "minor")), + Collections.singletonList(new SimpleViolation(Severity.MINOR, "minor")), report.getViolations()); } @@ -105,10 +106,10 @@ public void testFromJson() { assertEquals("empty report name is empty", "", emptyReport.getCheckName()); assertTrue("empty report violations are empty", emptyReport.getViolations().isEmpty()); - SimpleViolation violation = new SimpleViolation(Violation.Severity.MINOR, "minor"); + SimpleViolation violation = new SimpleViolation(Severity.MINOR, "minor"); SimpleReport moreReport = SimpleReport.fromJson(obj() - .key(ReportMapper.KEY_CHECK_NAME, "more") - .key(ReportMapper.KEY_VIOLATIONS, arr().val(violation)) + .key(ReportMapper.keys().checkName(), "more") + .key(ReportMapper.keys().violations(), arr().val(violation)) .get()); assertEquals("more report name is more", "more", moreReport.getCheckName()); @@ -123,15 +124,15 @@ public void reportViolation(final Violation violation) { } public final void minor(final String description, final PackageId... packages) { - this.reportViolation(new SimpleViolation(Violation.Severity.MINOR, description, packages)); + this.reportViolation(new SimpleViolation(Severity.MINOR, description, packages)); } public final void major(final String description, final PackageId... packages) { - this.reportViolation(new SimpleViolation(Violation.Severity.MAJOR, description, packages)); + this.reportViolation(new SimpleViolation(Severity.MAJOR, description, packages)); } public final void severe(final String description, final PackageId... packages) { - this.reportViolation(new SimpleViolation(Violation.Severity.SEVERE, description, packages)); + this.reportViolation(new SimpleViolation(Severity.SEVERE, description, packages)); } } diff --git a/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectAcesTest.java b/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectAcesTest.java index bcbe068eb..64e5df16c 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectAcesTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectAcesTest.java @@ -18,7 +18,7 @@ import net.adamcin.oakpal.api.Result; import net.adamcin.oakpal.api.Rule; -import net.adamcin.oakpal.api.Violation; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.JsonCnd; import net.adamcin.oakpal.core.OakMachine; import org.apache.jackrabbit.api.JackrabbitWorkspace; @@ -119,22 +119,22 @@ public void testNewInstance_severity() throws Exception { .key("principal", "foo") .key("expectedAces", arr("type=allow;path=/foo;privileges=jcr:read")) .get()); - Assert.assertEquals("expect major (default)", Violation.Severity.MAJOR, defaultMajorCheck.severity); + Assert.assertEquals("expect major (default)", Severity.MAJOR, defaultMajorCheck.severity); ExpectAces.Check minorCheck = checkFor(obj() .key("principal", "foo").key("severity", "minor") .key("expectedAces", arr("type=allow;path=/foo;privileges=jcr:read")) .get()); - Assert.assertEquals("expect minor", Violation.Severity.MINOR, minorCheck.severity); + Assert.assertEquals("expect minor", Severity.MINOR, minorCheck.severity); ExpectAces.Check majorCheck = checkFor(obj() .key("principal", "foo").key("severity", "major") .key("expectedAces", arr("type=allow;path=/foo;privileges=jcr:read")) .get()); - Assert.assertEquals("expect major", Violation.Severity.MAJOR, majorCheck.severity); + Assert.assertEquals("expect major", Severity.MAJOR, majorCheck.severity); ExpectAces.Check severeCheck = checkFor(obj() .key("principal", "foo").key("severity", "severe") .key("expectedAces", arr("type=allow;path=/foo;privileges=jcr:read")) .get()); - Assert.assertEquals("expect severe", Violation.Severity.SEVERE, severeCheck.severity); + Assert.assertEquals("expect severe", Severity.SEVERE, severeCheck.severity); } @Test @@ -167,7 +167,7 @@ public void testNewInstance_expectedAces() throws Exception { ExpectAces.AceCriteria.parse(principal, spec).getOrDefault(null) ); ExpectAces.Check check1 = checkFor(key("principal", principal) - .key(ExpectAces.CONFIG_EXPECTED_ACES, arr(spec)).get()); + .key(ExpectAces.keys().expectedAces(), arr(spec)).get()); Assert.assertEquals("expect expectedAces", expectCriterias, check1.expectedAces); } @@ -179,7 +179,7 @@ public void testNewInstance_notExpectedAces() throws Exception { ExpectAces.AceCriteria.parse(principal, spec).getOrDefault(null) ); ExpectAces.Check check1 = checkFor(key("principal", principal) - .key(ExpectAces.CONFIG_NOT_EXPECTED_ACES, arr(spec)).get()); + .key(ExpectAces.keys().notExpectedAces(), arr(spec)).get()); Assert.assertEquals("expect notExpectedAces", expectCriterias, check1.notExpectedAces); } @@ -191,12 +191,12 @@ public void testParseAceCriteria_throws() throws Exception { @Test public void testCheck_startedScan() throws Exception { ExpectAces.Check check = checkFor(obj() - .key(ExpectAces.CONFIG_PRINCIPAL, "nouser") - .key(ExpectAces.CONFIG_EXPECTED_ACES, arr() + .key(ExpectAces.keys().principal(), "nouser") + .key(ExpectAces.keys().expectedAces(), arr() .val("type=allow;path=/foo1;privileges=jcr:read") .val("type=allow;path=/foo1;privileges=rep:write") ) - .key(ExpectAces.CONFIG_NOT_EXPECTED_ACES, arr() + .key(ExpectAces.keys().notExpectedAces(), arr() .val("type=allow;path=/foo2;privileges=jcr:read") .val("type=allow;path=/foo2;privileges=rep:write") // foo3 is not created. a non-existent path should satisfy not-expected aces @@ -262,7 +262,7 @@ public void testShouldExpectAfterExtract() throws Exception { assertTrue("expect true for empty", check1.shouldExpectAfterExtract(PackageId.fromString("foo"))); ExpectAces.Check check2 = checkFor(key("principal", "nouser") - .key(ExpectAces.CONFIG_AFTER_PACKAGE_ID_RULES, + .key(ExpectAces.keys().afterPackageIdRules(), arr().val(key("type", "include").key("pattern", "^my_packages:.*"))).get()); assertFalse("expect false", check2.shouldExpectAfterExtract(PackageId.fromString("adamcin:test:1.0"))); assertTrue("expect true", check2.shouldExpectAfterExtract(PackageId.fromString("my_packages:test:1.0"))); diff --git a/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectPathsTest.java b/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectPathsTest.java index 4b2ec2c64..04c2d8a47 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectPathsTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/checks/ExpectPathsTest.java @@ -17,6 +17,7 @@ package net.adamcin.oakpal.core.checks; import net.adamcin.oakpal.api.Rule; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; import org.junit.Assert; @@ -57,17 +58,17 @@ public void testNewInstance_empty() throws Exception { @Test public void testNewInstance_expectedPaths() { - ExpectPaths.Check check1 = checkFor(key(ExpectPaths.CONFIG_EXPECTED_PATHS, arr("/foo1", "/foo2")).get()); + ExpectPaths.Check check1 = checkFor(key(ExpectPaths.keys().expectedPaths(), arr("/foo1", "/foo2")).get()); Assert.assertEquals("expect expectedPaths", Arrays.asList("/foo1", "/foo2"), check1.expectedPaths); - ExpectPaths.Check check2 = checkFor(key(ExpectPaths.CONFIG_EXPECTED_PATHS, arr("/foo2", "/foo1")).get()); + ExpectPaths.Check check2 = checkFor(key(ExpectPaths.keys().expectedPaths(), arr("/foo2", "/foo1")).get()); Assert.assertEquals("expect expectedPaths", Arrays.asList("/foo2", "/foo1"), check2.expectedPaths); } @Test public void testNewInstance_notExpectedPaths() { - ExpectPaths.Check check1 = checkFor(key(ExpectPaths.CONFIG_NOT_EXPECTED_PATHS, arr("/foo1", "/foo2")).get()); + ExpectPaths.Check check1 = checkFor(key(ExpectPaths.keys().notExpectedPaths(), arr("/foo1", "/foo2")).get()); Assert.assertEquals("expect notExpectedPaths", Arrays.asList("/foo1", "/foo2"), check1.notExpectedPaths); - ExpectPaths.Check check2 = checkFor(key(ExpectPaths.CONFIG_NOT_EXPECTED_PATHS, arr("/foo2", "/foo1")).get()); + ExpectPaths.Check check2 = checkFor(key(ExpectPaths.keys().notExpectedPaths(), arr("/foo2", "/foo1")).get()); Assert.assertEquals("expect notExpectedPaths", Arrays.asList("/foo2", "/foo1"), check2.notExpectedPaths); } @@ -77,7 +78,7 @@ public void testNewInstance_afterPackageIdRules() { new Rule(Rule.RuleType.INCLUDE, Pattern.compile("whua")), new Rule(Rule.RuleType.EXCLUDE, Pattern.compile("heyy"))); - ExpectPaths.Check check1 = checkFor(key(ExpectPaths.CONFIG_AFTER_PACKAGE_ID_RULES, expectedRules).get()); + ExpectPaths.Check check1 = checkFor(key(ExpectPaths.keys().afterPackageIdRules(), expectedRules).get()); Assert.assertEquals("expect afterPackageIdRules", expectedRules, check1.afterPackageIdRules); } @@ -86,22 +87,22 @@ public void testNewInstance_severity() { ExpectPaths.Check defaultMajorCheck = checkFor(obj() .key("expectedPaths", arr("/foo")) .get()); - Assert.assertEquals("expect major (default)", Violation.Severity.MAJOR, defaultMajorCheck.severity); + Assert.assertEquals("expect major (default)", Severity.MAJOR, defaultMajorCheck.severity); ExpectPaths.Check minorCheck = checkFor(obj() .key("severity", "minor") .key("expectedPaths", arr("/foo")) .get()); - Assert.assertEquals("expect minor", Violation.Severity.MINOR, minorCheck.severity); + Assert.assertEquals("expect minor", Severity.MINOR, minorCheck.severity); ExpectPaths.Check majorCheck = checkFor(obj() .key("severity", "major") .key("expectedPaths", arr("/foo")) .get()); - Assert.assertEquals("expect major", Violation.Severity.MAJOR, majorCheck.severity); + Assert.assertEquals("expect major", Severity.MAJOR, majorCheck.severity); ExpectPaths.Check severeCheck = checkFor(obj() .key("severity", "severe") .key("expectedPaths", arr("/foo")) .get()); - Assert.assertEquals("expect severe", Violation.Severity.SEVERE, severeCheck.severity); + Assert.assertEquals("expect severe", Severity.SEVERE, severeCheck.severity); } @Test @@ -109,7 +110,7 @@ public void testShouldExpectAfterExtract() { ExpectPaths.Check check1 = checkFor(obj().get()); assertTrue("expect true for empty", check1.shouldExpectAfterExtract(PackageId.fromString("foo"))); - ExpectPaths.Check check2 = checkFor(key(ExpectPaths.CONFIG_AFTER_PACKAGE_ID_RULES, arr() + ExpectPaths.Check check2 = checkFor(key(ExpectPaths.keys().afterPackageIdRules(), arr() .val(key("type", "include").key("pattern", "^my_packages:.*"))).get()); assertFalse("expect false", check2.shouldExpectAfterExtract(PackageId.fromString("adamcin:test:1.0"))); assertTrue("expect true", check2.shouldExpectAfterExtract(PackageId.fromString("my_packages:test:1.0"))); @@ -144,7 +145,7 @@ public void testAfterExtract() throws Exception { @Test public void testStartedScan() throws Exception { - ExpectPaths.Check check = checkFor(key(ExpectPaths.CONFIG_EXPECTED_PATHS, arr("/foo")).get()); + ExpectPaths.Check check = checkFor(key(ExpectPaths.keys().expectedPaths(), arr("/foo")).get()); final PackageId pid = PackageId.fromString("foo"); final Session session = mock(Session.class); check.afterExtract(pid, session); diff --git a/core/src/test/java/net/adamcin/oakpal/core/checks/FilterSetsTest.java b/core/src/test/java/net/adamcin/oakpal/core/checks/FilterSetsTest.java index 76f1e32bd..ccb0e6042 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/checks/FilterSetsTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/checks/FilterSetsTest.java @@ -17,7 +17,7 @@ package net.adamcin.oakpal.core.checks; import net.adamcin.oakpal.api.ProgressCheck; -import net.adamcin.oakpal.api.Violation; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.CheckReport; import net.adamcin.oakpal.testing.TestUtil; import org.junit.Assert; @@ -56,7 +56,7 @@ public void testModeMerge() throws Exception { CheckReport report = scanWithCheck(handler, "tmp_mode_merge.zip"); Assert.assertEquals("one violation", 1, report.getViolations().size()); - Assert.assertEquals("is severity", Violation.Severity.MINOR, + Assert.assertEquals("is severity", Severity.MINOR, report.getViolations().iterator().next().getSeverity()); assertTrue("all violations have packageIds", report.getViolations().stream() .allMatch(viol -> !viol.getPackages().isEmpty())); @@ -66,7 +66,7 @@ public void testModeMerge() throws Exception { CheckReport report = scanWithCheck(handler, "tmp_mode_merge.zip"); Assert.assertEquals("one violation", 1, report.getViolations().size()); - Assert.assertEquals("is severity", Violation.Severity.SEVERE, + Assert.assertEquals("is severity", Severity.SEVERE, report.getViolations().iterator().next().getSeverity()); assertTrue("all violations have packageIds", report.getViolations().stream() .allMatch(viol -> !viol.getPackages().isEmpty())); @@ -80,7 +80,7 @@ public void testEmptyFilter() throws Exception { CheckReport report = scanWithCheck(handler, "tmp_foo_bar_test_nofilter.zip"); Assert.assertEquals("one violation", 1, report.getViolations().size()); - Assert.assertEquals("is severity", Violation.Severity.MAJOR, + Assert.assertEquals("is severity", Severity.MAJOR, report.getViolations().iterator().next().getSeverity()); assertTrue("all violations have packageIds", report.getViolations().stream() .allMatch(viol -> !viol.getPackages().isEmpty())); diff --git a/core/src/test/java/net/adamcin/oakpal/core/checks/OverlapsTest.java b/core/src/test/java/net/adamcin/oakpal/core/checks/OverlapsTest.java index 49d75d83d..c031f6a96 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/checks/OverlapsTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/checks/OverlapsTest.java @@ -53,7 +53,7 @@ public void testOverlaps() throws Exception { .allMatch(viol -> !viol.getPackages().isEmpty())); }); TestUtil.testBlock(() -> { - ProgressCheck check = new Overlaps().newInstance(obj().key(Overlaps.CONFIG_REPORT_ALL_OVERLAPS, true).get()); + ProgressCheck check = new Overlaps().newInstance(obj().key(Overlaps.keys().reportAllOverlaps(), true).get()); CheckReport report = scanWithCheck(check, "tmp_foo_bar_test.zip", "tmp_foo_bar.zip", "tmp_foo.zip"); logViolations("testOverlaps:[foo_bar_test, foo_bar, foo]:reportAllOverlaps", report); Assert.assertEquals("three violations", 3, report.getViolations().size()); diff --git a/core/src/test/java/net/adamcin/oakpal/core/checks/PathsTest.java b/core/src/test/java/net/adamcin/oakpal/core/checks/PathsTest.java index c661f3054..79440c228 100644 --- a/core/src/test/java/net/adamcin/oakpal/core/checks/PathsTest.java +++ b/core/src/test/java/net/adamcin/oakpal/core/checks/PathsTest.java @@ -18,7 +18,7 @@ import net.adamcin.oakpal.api.ProgressCheck; import net.adamcin.oakpal.api.Rule; -import net.adamcin.oakpal.api.Violation; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.CheckReport; import net.adamcin.oakpal.testing.TestUtil; import org.junit.Assert; @@ -45,7 +45,7 @@ public void testDefaultSeverity() throws Exception { logViolations("level_set:no_unsafe", report); Assert.assertEquals("violations", 6, report.getViolations().size()); assertTrue("all violations are MAJOR", report.getViolations().stream() - .allMatch(viol -> viol.getSeverity().equals(Violation.Severity.MAJOR))); + .allMatch(viol -> viol.getSeverity().equals(Severity.MAJOR))); }); } @@ -57,7 +57,7 @@ public void testCustomSeverity() throws Exception { logViolations("level_set:no_unsafe", report); Assert.assertEquals("violations", 6, report.getViolations().size()); assertTrue("all violations are SEVERE", report.getViolations().stream() - .allMatch(viol -> viol.getSeverity().equals(Violation.Severity.SEVERE))); + .allMatch(viol -> viol.getSeverity().equals(Severity.SEVERE))); }); } @@ -69,7 +69,7 @@ public void testCustomSeverityMixedCase() throws Exception { logViolations("level_set:no_unsafe", report); Assert.assertEquals("violations", 6, report.getViolations().size()); assertTrue("all violations are MINOR", report.getViolations().stream() - .allMatch(viol -> viol.getSeverity().equals(Violation.Severity.MINOR))); + .allMatch(viol -> viol.getSeverity().equals(Severity.MINOR))); }); } @@ -94,7 +94,8 @@ public void testDeletedPath() throws Exception { allDeletesCheck.deletedPath(null, "/foo", null); assertFalse("reported violations should not be empty after deletedPath", allDeletesCheck.getReportedViolations().isEmpty()); - Paths.Check allDeletesCheckByConfig = (Paths.Check) new Paths().newInstance(key(Paths.CONFIG_DENY_ALL_DELETES, true).get()); + Paths.Check allDeletesCheckByConfig = (Paths.Check) new Paths() + .newInstance(key(Paths.keys().denyAllDeletes(), true).get()); assertTrue("reported violations should be empty before deletedPath", allDeletesCheckByConfig.getReportedViolations().isEmpty()); allDeletesCheckByConfig.deletedPath(null, "/foo", null); diff --git a/maven/src/main/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojo.java b/maven/src/main/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojo.java index 5d3a1eafe..41fc2aea8 100644 --- a/maven/src/main/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojo.java +++ b/maven/src/main/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojo.java @@ -21,6 +21,7 @@ import java.util.Set; import java.util.stream.Collectors; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.core.CheckReport; import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.packaging.PackageId; @@ -54,9 +55,9 @@ abstract class AbstractITestMojo extends AbstractCommonMojo { /** * Specify the minimum violation severity level that will trigger plugin execution failure. Valid options are - * {@link Violation.Severity#MINOR}, - * {@link Violation.Severity#MAJOR}, and - * {@link Violation.Severity#SEVERE}. + * {@link Severity#MINOR}, + * {@link Severity#MAJOR}, and + * {@link Severity#SEVERE}. *

* FYI: FileVault Importer errors are reported as MAJOR by default. *

@@ -64,7 +65,7 @@ abstract class AbstractITestMojo extends AbstractCommonMojo { * @since 0.1.0 */ @Parameter(defaultValue = "MAJOR") - protected Violation.Severity failOnSeverity = Violation.Severity.MAJOR; + protected Severity failOnSeverity = Severity.MAJOR; protected abstract boolean isIndividuallySkipped(); diff --git a/maven/src/test/java/net/adamcin/oakpal/maven/checks/SimpleJavaCheck.java b/maven/src/test/java/net/adamcin/oakpal/maven/checks/SimpleJavaCheck.java index 2e582be7e..0e7b52fe7 100644 --- a/maven/src/test/java/net/adamcin/oakpal/maven/checks/SimpleJavaCheck.java +++ b/maven/src/test/java/net/adamcin/oakpal/maven/checks/SimpleJavaCheck.java @@ -20,9 +20,9 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleProgressCheck; import net.adamcin.oakpal.api.SimpleViolation; -import net.adamcin.oakpal.api.Violation; import org.apache.jackrabbit.vault.fs.config.MetaInf; import org.apache.jackrabbit.vault.packaging.PackageId; import org.apache.jackrabbit.vault.packaging.PackageProperties; @@ -34,7 +34,7 @@ public void beforeExtract(final PackageId packageId, final Session inspectSessio final PackageProperties packageProperties, final MetaInf metaInf, final List subpackages) throws RepositoryException { - reportViolation(new SimpleViolation(Violation.Severity.MINOR, + reportViolation(new SimpleViolation(Severity.MINOR, packageProperties.getACHandling().toString(), packageId)); } } diff --git a/maven/src/test/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojoTest.java b/maven/src/test/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojoTest.java index 066d6c601..3434ed826 100644 --- a/maven/src/test/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojoTest.java +++ b/maven/src/test/java/net/adamcin/oakpal/maven/mojo/AbstractITestMojoTest.java @@ -16,8 +16,8 @@ package net.adamcin.oakpal.maven.mojo; +import net.adamcin.oakpal.api.Severity; import net.adamcin.oakpal.api.SimpleViolation; -import net.adamcin.oakpal.api.Violation; import net.adamcin.oakpal.core.CheckReport; import net.adamcin.oakpal.core.SimpleReport; import org.apache.commons.io.FileUtils; @@ -90,10 +90,10 @@ public void testReactToReports_nonEmptyReports_noFail() throws Exception { mojo.setLog(log); mojo.reactToReports(Arrays.asList( new SimpleReport("one", Collections - .singletonList(new SimpleViolation(Violation.Severity.MINOR, "one", + .singletonList(new SimpleViolation(Severity.MINOR, "one", packageId))), new SimpleReport("two", Collections - .singletonList(new SimpleViolation(Violation.Severity.MINOR, "two"))))); + .singletonList(new SimpleViolation(Severity.MINOR, "two"))))); assertFalse("no error messages", log.any(MockMojoLog.MockMojoLogEntry::isError)); assertTrue("expect log header", log.any(entry -> "OakPAL Check Reports".equals(entry.message))); assertTrue("expect report one", log.any(entry -> " one".equals(entry.message))); @@ -108,14 +108,14 @@ public void testReactToReports_nonEmptyReports_fail() { final PackageId packageId = PackageId.fromString("my_packages:example-one:1.0"); MockMojoLog log = new MockMojoLog(); ConcreteMojo mojo = new ConcreteMojo(); - mojo.setFailOnSeverity(Violation.Severity.MINOR); + mojo.setFailOnSeverity(Severity.MINOR); mojo.setLog(log); final List reports = Arrays.asList( new SimpleReport("one", Collections - .singletonList(new SimpleViolation(Violation.Severity.MINOR, "one", + .singletonList(new SimpleViolation(Severity.MINOR, "one", packageId))), new SimpleReport("two", Collections - .singletonList(new SimpleViolation(Violation.Severity.MINOR, "two")))); + .singletonList(new SimpleViolation(Severity.MINOR, "two")))); boolean failed = false; try { mojo.reactToReports(reports); @@ -203,7 +203,7 @@ public void setSummaryFile(File summaryFile) { this.summaryFile = summaryFile; } - public void setFailOnSeverity(Violation.Severity failOnSeverity) { + public void setFailOnSeverity(Severity failOnSeverity) { this.failOnSeverity = failOnSeverity; } diff --git a/testing/src/test/java/net/adamcin/oakpal/testing/TestUtilTest.java b/testing/src/test/java/net/adamcin/oakpal/testing/TestUtilTest.java new file mode 100644 index 000000000..9252564c3 --- /dev/null +++ b/testing/src/test/java/net/adamcin/oakpal/testing/TestUtilTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Mark Adamcin + * + * Licensed 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 + * + * http://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. + */ + +package net.adamcin.oakpal.testing; + +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; + +import static org.junit.Assert.assertTrue; + +public class TestUtilTest { + + @Test + public void testTestBlock() throws Exception { + CompletableFuture latch = new CompletableFuture<>(); + TestUtil.testBlock(() -> { + latch.complete(true); + }); + assertTrue("expect completed true", latch.getNow(false)); + } + + @Test(expected = Exception.class) + public void testTestBlock_throws() throws Exception { + TestUtil.testBlock(() -> { + throw new Exception("Expected"); + }); + } +} \ No newline at end of file diff --git a/webster/src/main/java/net/adamcin/oakpal/webster/ChecklistExporter.java b/webster/src/main/java/net/adamcin/oakpal/webster/ChecklistExporter.java index c0d920fb1..3235942ef 100644 --- a/webster/src/main/java/net/adamcin/oakpal/webster/ChecklistExporter.java +++ b/webster/src/main/java/net/adamcin/oakpal/webster/ChecklistExporter.java @@ -449,7 +449,7 @@ public void updateChecklist(final WriterOpener writerOpener, //final Set finalPrefixes = new HashSet<>(); final NamespaceMappingRequest.Builder request = new NamespaceMappingRequest.Builder(); if (!privileges.isEmpty()) { - builder.add(Checklist.KEY_JCR_PRIVILEGES, JsonCnd.privilegesToJson(privileges, origMapping)); + builder.add(Checklist.keys().jcrPrivileges(), JsonCnd.privilegesToJson(privileges, origMapping)); privileges.stream().flatMap(JsonCnd::namedBy).forEach(request::withQName); } @@ -462,7 +462,7 @@ public void updateChecklist(final WriterOpener writerOpener, .map(ForcedRoot::toJson) .collect(JsonCollectors.toJsonArray()); - builder.add(Checklist.KEY_FORCED_ROOTS, forcedRootsJson); + builder.add(Checklist.keys().forcedRoots(), forcedRootsJson); // begin nodetype handling @@ -504,7 +504,7 @@ public void updateChecklist(final WriterOpener writerOpener, final JsonObject jcrNodetypes = JsonCnd.toJson(qNodeTypes, new NamespaceMapping(new SessionNamespaceResolver(session))); - builder.add(Checklist.KEY_JCR_NODETYPES, jcrNodetypes); + builder.add(Checklist.keys().jcrNodetypes(), jcrNodetypes); } // begin namespace handling @@ -519,7 +519,7 @@ public void updateChecklist(final WriterOpener writerOpener, .flatMap(Result::stream) .collect(Collectors.toList()); if (!exportNamespaces.isEmpty()) { - builder.add(Checklist.KEY_JCR_NAMESPACES, JavaxJson.wrap(exportNamespaces)); + builder.add(Checklist.keys().jcrNamespaces(), JavaxJson.wrap(exportNamespaces)); } final JsonObject sorted = builder.build().entrySet().stream() diff --git a/webster/src/test/java/net/adamcin/oakpal/webster/ChecklistExporterTest.java b/webster/src/test/java/net/adamcin/oakpal/webster/ChecklistExporterTest.java index ffa1b2628..d120d72d4 100644 --- a/webster/src/test/java/net/adamcin/oakpal/webster/ChecklistExporterTest.java +++ b/webster/src/test/java/net/adamcin/oakpal/webster/ChecklistExporterTest.java @@ -187,10 +187,10 @@ public void testUpdateChecklist() throws Exception { pathExporter.updateChecklist(() -> new OutputStreamWriter( new FileOutputStream(pass1Checklist), StandardCharsets.UTF_8), session, Checklist.fromJson("", null, obj() - .key(Checklist.KEY_JCR_NAMESPACES, Collections + .key(Checklist.keys().jcrNamespaces(), Collections .singletonList(JcrNs.create("sling", "http://sling.apache.org/jcr/sling/1.0"))) - .key(Checklist.KEY_JCR_PRIVILEGES, obj() + .key(Checklist.keys().jcrPrivileges(), obj() .key("sling:doesAll", obj() .key("contains", arr("sling:doOne", "sling:doTwo"))) .get()) @@ -199,11 +199,11 @@ public void testUpdateChecklist() throws Exception { try (JsonReader reader = Json.createReader(new FileInputStream(pass1Checklist))) { JsonObject checklist = reader.readObject(); assertTrue("checklist object should contain the forcedRoots key", - checklist.containsKey(Checklist.KEY_FORCED_ROOTS)); + checklist.containsKey(Checklist.keys().forcedRoots())); assertTrue("checklist object should contain the privileges key", - checklist.containsKey(Checklist.KEY_JCR_PRIVILEGES)); + checklist.containsKey(Checklist.keys().jcrPrivileges())); - JsonArray forcedRoots = checklist.getJsonArray(Checklist.KEY_FORCED_ROOTS); + JsonArray forcedRoots = checklist.getJsonArray(Checklist.keys().forcedRoots()); assertEquals("forcedRoots should be array with expected number of elements", allPaths.size(), forcedRoots.size()); @@ -237,11 +237,11 @@ public void testUpdateChecklist() throws Exception { try (JsonReader reader = Json.createReader(new FileInputStream(fullPassChecklist))) { JsonObject checklist = reader.readObject(); assertTrue("checklist object should contain the forcedRoots key", - checklist.containsKey(Checklist.KEY_FORCED_ROOTS)); + checklist.containsKey(Checklist.keys().forcedRoots())); assertTrue("checklist object should contain the privileges key", - checklist.containsKey(Checklist.KEY_JCR_PRIVILEGES)); + checklist.containsKey(Checklist.keys().jcrPrivileges())); - JsonArray forcedRoots = checklist.getJsonArray(Checklist.KEY_FORCED_ROOTS); + JsonArray forcedRoots = checklist.getJsonArray(Checklist.keys().forcedRoots()); assertEquals("forcedRoots should be array with expected number of elements", allPaths.size(), forcedRoots.size()); @@ -291,9 +291,9 @@ public void testUpdateChecklist() throws Exception { try (JsonReader reader = Json.createReader(new FileInputStream(mergePassChecklist))) { JsonObject checklist = reader.readObject(); assertTrue("checklist object should contain the forcedRoots key", - checklist.containsKey(Checklist.KEY_FORCED_ROOTS)); + checklist.containsKey(Checklist.keys().forcedRoots())); - JsonArray forcedRoots = checklist.getJsonArray(Checklist.KEY_FORCED_ROOTS); + JsonArray forcedRoots = checklist.getJsonArray(Checklist.keys().forcedRoots()); assertEquals("[mergePass] forcedRoots should be array with expected number of elements", allPaths.size(), forcedRoots.size()); @@ -323,9 +323,9 @@ public void testUpdateChecklist() throws Exception { try (JsonReader reader = Json.createReader(new FileInputStream(replacePassChecklist))) { JsonObject checklist = reader.readObject(); assertTrue("checklist object should contain the forcedRoots key", - checklist.containsKey(Checklist.KEY_FORCED_ROOTS)); + checklist.containsKey(Checklist.keys().forcedRoots())); - JsonArray forcedRoots = checklist.getJsonArray(Checklist.KEY_FORCED_ROOTS); + JsonArray forcedRoots = checklist.getJsonArray(Checklist.keys().forcedRoots()); assertEquals("[replacePass] forcedRoots should be array with expected number of elements", 1 + unorderedPaths.size() + orderedPaths.stream().filter(path -> path.matches(".*[02468]$")).count(), forcedRoots.size()); @@ -358,9 +358,9 @@ public void testUpdateChecklist() throws Exception { try (JsonReader reader = Json.createReader(new FileInputStream(truncatePassChecklist))) { JsonObject checklist = reader.readObject(); assertTrue("checklist object should contain the forcedRoots key", - checklist.containsKey(Checklist.KEY_FORCED_ROOTS)); + checklist.containsKey(Checklist.keys().forcedRoots())); - JsonArray forcedRoots = checklist.getJsonArray(Checklist.KEY_FORCED_ROOTS); + JsonArray forcedRoots = checklist.getJsonArray(Checklist.keys().forcedRoots()); assertEquals("[truncatePass] forcedRoots should be array with expected number of elements", orderedPaths.stream().filter(path -> path.matches(".*[02468]$")).count(), forcedRoots.size());