diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java index dd5fb56f8..45037e0fa 100644 --- a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java @@ -12,6 +12,10 @@ *******************************************************************************/ package org.eclipse.passage.lic.internal.api; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluatorsRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessorsRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; import org.eclipse.passage.lic.internal.api.io.KeyKeeperRegistry; @@ -33,4 +37,12 @@ public interface AccessCycleConfiguration { ConditionTransportRegistry transports(); + PermissionEmittersRegistry permissionEmitters(); + + ExpressionPasringRegistry expressionParsers(); + + ExpressionEvaluatorsRegistry expressionEvaluators(); + + ExpressionTokenAssessorsRegistry expressionAssessors(); + } diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/registry/AggregativeServiceId.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/registry/AggregativeServiceId.java new file mode 100644 index 000000000..15f7e780b --- /dev/null +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/registry/AggregativeServiceId.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.internal.api.registry; + +import java.util.Objects; + +public final class AggregativeServiceId implements ServiceId { + + private final I1 first; + private final I2 second; + + public AggregativeServiceId(I1 first, I2 second) { + this.first = first; + this.second = second; + } + + @Override + public boolean equals(Object object) { + if (!AggregativeServiceId.class.isInstance(object)) { + return false; + } + @SuppressWarnings("rawtypes") + AggregativeServiceId another = (AggregativeServiceId) object; + return first.equals(another.first) && second.equals(another.second); + } + + @Override + public int hashCode() { + return Objects.hash(first, second); + } + + @Override + public String toString() { + return String.format("%s/%s", first, second); //$NON-NLS-1$ + } + +} diff --git a/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java index 57dd7fdbe..7ee284be1 100644 --- a/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java +++ b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java @@ -19,6 +19,16 @@ import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; import org.eclipse.passage.lic.internal.api.LicensedProduct; import org.eclipse.passage.lic.internal.api.LicensingException; +import org.eclipse.passage.lic.internal.api.conditions.EvaluationType; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittingService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluationService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluatorsRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessmentService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessorsRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransport; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.ContentType; @@ -32,6 +42,9 @@ import org.eclipse.passage.lic.internal.api.registry.StringServiceId; import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirements; import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry; +import org.eclipse.passage.lic.internal.base.conditions.evaluation.BasePermissionEmittingService; +import org.eclipse.passage.lic.internal.base.conditions.evaluation.AndsProtocolExpressionParseService; +import org.eclipse.passage.lic.internal.base.conditions.evaluation.SimpleMapExpressionEvaluationService; import org.eclipse.passage.lic.internal.base.conditions.mining.MiningEquipment; import org.eclipse.passage.lic.internal.base.conditions.mining.UserHomeResidentConditions; import org.eclipse.passage.lic.internal.base.registry.ReadOnlyRegistry; @@ -56,6 +69,10 @@ final class SealedAccessCycleConfiguration implements AccessCycleConfiguration { private final Registry transports; private final Registry codecs; private final Registry keys; + private final Registry emitters; + private final Registry expressionParsers; + private final Registry expressionEvaluators; + private final Registry tokenEvaluators; SealedAccessCycleConfiguration(Supplier product) { alarm = LicensingException::printStackTrace; @@ -77,7 +94,7 @@ final class SealedAccessCycleConfiguration implements AccessCycleConfiguration { )); transports = new ReadOnlyRegistry<>(Arrays.asList(// new JsonConditionTransport(), // - new XmiConditionTransport() // FIXME: does not do `writing` + new XmiConditionTransport() // )); codecs = new ReadOnlyRegistry<>(Arrays.asList(// new BcStreamCodec(product) // @@ -85,6 +102,25 @@ final class SealedAccessCycleConfiguration implements AccessCycleConfiguration { keys = new ReadOnlyRegistry<>(Arrays.asList(// new BundleKeyKeeper(product, bundle()) // )); + emitters = new ReadOnlyRegistry<>(Arrays.asList(// + new BasePermissionEmittingService(// + expressionParsers(), // + expressionAssessors(), // + expressionEvaluators())// + )); + expressionParsers = new ReadOnlyRegistry<>(Arrays.asList(// + new AndsProtocolExpressionParseService()// + )); + expressionEvaluators = new ReadOnlyRegistry<>(Arrays.asList(// + new SimpleMapExpressionEvaluationService()// + )); + tokenEvaluators = new ReadOnlyRegistry<>(Arrays.asList(// + // FIXME: OSHI-based evaluator for EvaluationType.Hardware + )); + } + + private Bundle bundle() { + return FrameworkUtil.getBundle(getClass()); } @Override @@ -112,8 +148,24 @@ public ConditionTransportRegistry transports() { return () -> transports; } - private Bundle bundle() { - return FrameworkUtil.getBundle(getClass()); + @Override + public PermissionEmittersRegistry permissionEmitters() { + return () -> emitters; + } + + @Override + public ExpressionPasringRegistry expressionParsers() { + return () -> expressionParsers; + } + + @Override + public ExpressionEvaluatorsRegistry expressionEvaluators() { + return () -> expressionEvaluators; + } + + @Override + public ExpressionTokenAssessorsRegistry expressionAssessors() { + return () -> tokenEvaluators; } } diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java index 5e9db4bcd..d979ef2d2 100644 --- a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java @@ -17,17 +17,22 @@ import java.util.Optional; +import org.eclipse.passage.lic.api.tests.fakes.FakeConditionExpressionEvaluator; +import org.eclipse.passage.lic.api.tests.fakes.FakeConditionExpressionParser; import org.eclipse.passage.lic.api.tests.fakes.FakeConditionTransport; +import org.eclipse.passage.lic.api.tests.fakes.FakeExpressionTokenAssessmentService; import org.eclipse.passage.lic.api.tests.fakes.FakeKeyKeeper; import org.eclipse.passage.lic.api.tests.fakes.FakeMinedConditions; import org.eclipse.passage.lic.api.tests.fakes.FakeResolvedRequirements; import org.eclipse.passage.lic.api.tests.fakes.FakeStreamCodec; import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; import org.eclipse.passage.lic.internal.api.Framework; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; import org.eclipse.passage.lic.internal.api.conditions.mining.ContentType; import org.eclipse.passage.lic.internal.api.registry.Registry; import org.eclipse.passage.lic.internal.api.registry.Service; import org.eclipse.passage.lic.internal.api.registry.ServiceId; +import org.junit.Ignore; import org.junit.Test; /** @@ -144,6 +149,64 @@ public final void hasTransportForXml() { assertTrue(config().transports().get().hasService(new ContentType.Xml())); } + @Test + public final void canParseConditionExpressions() { + assertServiceRegistryIsFunctional(config().expressionParsers().get()); + } + + @Test + public final void prohibitsExpressionParseServicesExtension() { + assertTrue(readOnly(config().expressionParsers().get())); + } + + @Test + public final void prohibitsInjectionIntoExpressionParseServices() { + assertServiceInjectionsIsProhibited(config().expressionParsers().get(), new FakeConditionExpressionParser()); + } + + @Test + public final void hasParserForDefaultExpressionFormat() { + assertTrue(config().expressionParsers().get().hasService(new ExpressionProtocol.Default())); + } + + @Test + public final void canEvaluateConditionExpressions() { + assertServiceRegistryIsFunctional(config().expressionEvaluators().get()); + } + + @Test + public final void prohibitsExpressionEvaluationServicesExtension() { + assertTrue(readOnly(config().expressionEvaluators().get())); + } + + @Test + public final void prohibitsInjectionIntoExpressionEvaluationServices() { + assertServiceInjectionsIsProhibited(config().expressionEvaluators().get(), + new FakeConditionExpressionEvaluator()); + } + + @Test + public final void hasEvaluatorForDefaultExpressionFormat() { + assertTrue(config().expressionEvaluators().get().hasService(new ExpressionProtocol.Default())); + } + + @Test + @Ignore // yet to be implemented (OSHI-based) + public final void canAssessConditionExpressionsSegment() { + assertServiceRegistryIsFunctional(config().expressionAssessors().get()); + } + + @Test + public final void prohibitsExpressionSegmentAssessmentServicesExtension() { + assertTrue(readOnly(config().expressionAssessors().get())); + } + + @Test + public final void prohibitsInjectionIntoSegmentAssessmentServices() { + assertServiceInjectionsIsProhibited(config().expressionAssessors().get(), + new FakeExpressionTokenAssessmentService()); + } + private > void assertServiceRegistryIsFunctional( Registry registry) { assertNotNull(registry); diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/conditions/evaluation/EmissionContractTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/conditions/evaluation/EmissionContractTest.java new file mode 100644 index 000000000..fb7793000 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/conditions/evaluation/EmissionContractTest.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.conditions.evaluation; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; + +import org.eclipse.passage.lic.internal.api.conditions.evaluation.Emission; +import org.junit.Test; + +@SuppressWarnings("restriction") +public abstract class EmissionContractTest { + + @Test(expected = Exception.class) + public void failedEmissionCannotHoldPermission() { + Emission failure = failed(); + assumeTrue(failure.failed()); + failure.permissions(); + } + + @Test + public void successfulEmissionMustHoldPermission() { + Emission success = successful(); + assumeFalse(success.failed()); + assertNotNull(success.permissions()); + } + + @Test + public void failedEmissionMustHoldDiagnosis() { + Emission failure = failed(); + assumeTrue(failure.failed()); + assertNotNull(failure.failureDiagnostic()); + } + + @Test(expected = Exception.class) + public void successfulEmissionCannotHoldDiagnosis() { + Emission success = successful(); + assumeFalse(success.failed()); + success.failureDiagnostic(); + + } + + protected abstract Emission failed(); + + protected abstract Emission successful(); +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/conditions/evaluation/ExpressionFormatContractTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/conditions/evaluation/ExpressionFormatContractTest.java new file mode 100644 index 000000000..e01ab235c --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/conditions/evaluation/ExpressionFormatContractTest.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.conditions.evaluation; + +import org.eclipse.passage.lic.api.tests.registry.ServiceIdContractTest; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; +import org.eclipse.passage.lic.internal.api.registry.ServiceId; + +@SuppressWarnings("restriction") +public class ExpressionFormatContractTest extends ServiceIdContractTest { + + @Override + protected ServiceId ofSameData() { + return new ExpressionProtocol.Of("abra-cadabra"); //$NON-NLS-1$ + } + +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeConditionExpressionEvaluator.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeConditionExpressionEvaluator.java new file mode 100644 index 000000000..c98b21459 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeConditionExpressionEvaluator.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.fakes; + +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluationService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessmentService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ParsedExpression; + +@SuppressWarnings("restriction") +public class FakeConditionExpressionEvaluator implements ExpressionEvaluationService { + + @Override + public ExpressionProtocol id() { + return new ExpressionProtocol.Of("brand-new-format"); //$NON-NLS-1$ + } + + @Override + public boolean evaluate(ParsedExpression expression, ExpressionTokenAssessmentService tokenEvaluator) { + throw new UnsupportedOperationException(); + } + +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeConditionExpressionParser.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeConditionExpressionParser.java new file mode 100644 index 000000000..2131eb3d9 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeConditionExpressionParser.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.fakes; + +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionParsingException; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ParsedExpression; + +@SuppressWarnings("restriction") +public final class FakeConditionExpressionParser implements ExpressionPasringService { + + @Override + public ExpressionProtocol id() { + return new ExpressionProtocol.Of("intruder"); //$NON-NLS-1$ + } + + @Override + public ParsedExpression parsed(String expression) throws ExpressionParsingException { + throw new UnsupportedOperationException(); + } + +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeExpressionTokenAssessmentService.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeExpressionTokenAssessmentService.java new file mode 100644 index 000000000..e5b4becc8 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/FakeExpressionTokenAssessmentService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.fakes; + +import org.eclipse.passage.lic.internal.api.conditions.EvaluationType; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessmentService; + +@SuppressWarnings("restriction") +public final class FakeExpressionTokenAssessmentService implements ExpressionTokenAssessmentService { + + @Override + public EvaluationType id() { + return new EvaluationType.Of("air-content-assessment"); //$NON-NLS-1$ + } + + @Override + public boolean equal(String key, String value) { + throw new UnsupportedOperationException(); + } + +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/registry/AggregativeServiceIdContractTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/registry/AggregativeServiceIdContractTest.java new file mode 100644 index 000000000..652fd3f51 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/registry/AggregativeServiceIdContractTest.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.registry; + +import org.eclipse.passage.lic.internal.api.registry.AggregativeServiceId; +import org.eclipse.passage.lic.internal.api.registry.ServiceId; +import org.eclipse.passage.lic.internal.api.registry.StringServiceId; + +@SuppressWarnings("restriction") +public class AggregativeServiceIdContractTest extends ServiceIdContractTest { + + @Override + protected ServiceId ofSameData() { + return new AggregativeServiceId(// + new StringServiceId("first"), //$NON-NLS-1$ + new StringServiceId("second")); //$NON-NLS-1$ + } + +} diff --git a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java index 8b0cfc74b..265f7b4e1 100644 --- a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java +++ b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java @@ -17,6 +17,10 @@ import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; import org.eclipse.passage.lic.internal.api.Framework; import org.eclipse.passage.lic.internal.api.LicensedProduct; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluatorsRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessorsRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; import org.eclipse.passage.lic.internal.api.io.KeyKeeperRegistry; @@ -45,6 +49,9 @@ public AccessCycleConfiguration accessCycleConfiguration() { } private static class SabotagedAccessCycleConfiguration implements AccessCycleConfiguration { + private > Registry noService() { + return new ReadOnlyRegistry(new ArrayList<>()); + } @Override public ResolvedRequirementsRegistry requirementResolvers() { @@ -71,8 +78,24 @@ public ConditionTransportRegistry transports() { return () -> noService(); } - private > Registry noService() { - return new ReadOnlyRegistry(new ArrayList<>()); + @Override + public PermissionEmittersRegistry permissionEmitters() { + return () -> noService(); + } + + @Override + public ExpressionPasringRegistry expressionParsers() { + return () -> noService(); + } + + @Override + public ExpressionEvaluatorsRegistry expressionEvaluators() { + return () -> noService(); + } + + @Override + public ExpressionTokenAssessorsRegistry expressionAssessors() { + return () -> noService(); } }