diff --git a/controller/src/main/java/org/jboss/as/controller/OperationContext.java b/controller/src/main/java/org/jboss/as/controller/OperationContext.java index ce52a017408..6f867f083bb 100644 --- a/controller/src/main/java/org/jboss/as/controller/OperationContext.java +++ b/controller/src/main/java/org/jboss/as/controller/OperationContext.java @@ -712,6 +712,7 @@ default ServiceTarget getServiceTarget() throws UnsupportedOperationException { * manager exists and its {@link SecurityManager#checkPermission checkPermission} method doesn't allow * access to the relevant system property or environment variable */ + @Override ModelNode resolveExpressions(ModelNode node) throws OperationFailedException; /** @@ -837,7 +838,7 @@ default ServiceTarget getServiceTarget() throws UnsupportedOperationException { * * @throws java.lang.IllegalStateException if {@link #getCurrentStage() the current stage} is not {@link Stage#MODEL} */ - void registerCapability(RuntimeCapability capability); + void registerCapability(RuntimeCapability> capability); /** * Registers an additional hard requirement a capability has beyond what it was aware of when {@code capability} @@ -885,6 +886,197 @@ default ServiceTarget getServiceTarget() throws UnsupportedOperationException { */ boolean hasOptionalCapability(String requested, String dependent, String attribute); + /** + * Checks whether one of a capability's optional and runtime-only requirements is present. Only for use in cases + * where the {@code dependent} capability's persistent configuration does not mandate the presence + * of the {@code requested} capability, but the capability will use it at runtime if it is present. + *
+ * This method should be used in preference to {@link #registerAdditionalCapabilityRequirement(String, String, String)} + * when the caller's own configuration doesn't impose a hard requirement for the {@code requested} capability, but, + * if it is present it will be used. Once the caller declares an intent to use the capability by invoking this + * method and getting a {@code true} response, thereafter the system is aware that {@code dependent} is actually + * using {@code requested}, but will not prevent configuration changes that make {@code requested} + * unavailable. + *
+ * + * @param requested the base name of the requested capability. Cannot be {@code null} + * @param dependent the runtime capability that requires the other capability. Cannot be {@code null} + * @param attribute the attribute that triggered this requirement, or {@code null} if no single attribute was responsible + * @return {@code true} if the requested capability is present; {@code false} if not. If {@code true}, hereafter + * {@code dependent}'s requirement for {@code requested} will not be treated as optional. + * @throws IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}. + * The complete set of capabilities is not known until the end of the model stage. + */ + default boolean hasOptionalCapability(String requested, RuntimeCapability> dependent, AttributeDefinition attribute) { + return this.hasOptionalCapability(requested, dependent.isDynamicallyNamed() ? dependent.getDynamicName(this.getCurrentAddress()) : dependent.getName(), (attribute != null) ? attribute.getName() : null); + } + + /** + * Checks whether one of a capability's optional and runtime-only requirements is present. Only for use in cases + * where the {@code dependent} capability's persistent configuration does not mandate the presence + * of the {@code requested} capability, but the capability will use it at runtime if it is present. + *+ * This method should be used in preference to {@link #registerAdditionalCapabilityRequirement(String, String, String)} + * when the caller's own configuration doesn't impose a hard requirement for the {@code requested} capability, but, + * if it is present it will be used. Once the caller declares an intent to use the capability by invoking this + * method and getting a {@code true} response, thereafter the system is aware that {@code dependent} is actually + * using {@code requested}, but will not prevent configuration changes that make {@code requested} + * unavailable. + *
+ * + * @param requested the base name of the requested capability. Cannot be {@code null} + * @param requestedSegments the dynamic segments of the requested capability. Cannot be {@code null} + * @param dependent the runtime capability that requires the other capability. Cannot be {@code null} + * @param attribute the attribute that triggered this requirement, or {@code null} if no single attribute was responsible + * @return {@code true} if the requested capability is present; {@code false} if not. If {@code true}, hereafter + * {@code dependent}'s requirement for {@code requested} will not be treated as optional. + * @throws IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}. + * The complete set of capabilities is not known until the end of the model stage. + */ + default boolean hasOptionalCapability(String requested, String[] requestedSegments, RuntimeCapability> dependent, AttributeDefinition attribute) { + return this.hasOptionalCapability(RuntimeCapability.buildDynamicCapabilityName(requested, requestedSegments), dependent, attribute); + } + + /** + * Checks whether one of a capability's optional and runtime-only requirements is present. Only for use in cases + * where the {@code dependent} capability's persistent configuration does not mandate the presence + * of the {@code requested} capability, but the capability will use it at runtime if it is present. + *+ * This method should be used in preference to {@link #registerAdditionalCapabilityRequirement(String, String, String)} + * when the caller's own configuration doesn't impose a hard requirement for the {@code requested} capability, but, + * if it is present it will be used. Once the caller declares an intent to use the capability by invoking this + * method and getting a {@code true} response, thereafter the system is aware that {@code dependent} is actually + * using {@code requested}, but will not prevent configuration changes that make {@code requested} + * unavailable. + *
+ * + * @param requested the base name of the requested capability. Cannot be {@code null} + * @param requestedSegments the dynamic segments of the requested capability. Cannot be {@code null} + * @param dependent the runtime capability that requires the other capability. Cannot be {@code null} + * @param attribute the attribute that triggered this requirement, or {@code null} if no single attribute was responsible + * @return {@code true} if the requested capability is present; {@code false} if not. If {@code true}, hereafter + * {@code dependent}'s requirement for {@code requested} will not be treated as optional. + * @throws IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}. + * The complete set of capabilities is not known until the end of the model stage. + */ + default boolean hasOptionalCapability(NullaryServiceDescriptor> requested, RuntimeCapability> dependent, AttributeDefinition attribute) { + return this.hasOptionalCapability(requested.getName(), dependent, attribute); + } + + /** + * Checks whether one of a capability's optional and runtime-only requirements is present. Only for use in cases + * where the {@code dependent} capability's persistent configuration does not mandate the presence + * of the {@code requested} capability, but the capability will use it at runtime if it is present. + *+ * This method should be used in preference to {@link #registerAdditionalCapabilityRequirement(String, String, String)} + * when the caller's own configuration doesn't impose a hard requirement for the {@code requested} capability, but, + * if it is present it will be used. Once the caller declares an intent to use the capability by invoking this + * method and getting a {@code true} response, thereafter the system is aware that {@code dependent} is actually + * using {@code requested}, but will not prevent configuration changes that make {@code requested} + * unavailable. + *
+ * + * @param requested the service descriptor of the requested capability. Cannot be {@code null} + * @param name the dynamic name segment of the requested capability. + * @param dependent the runtime capability that requires the other capability. Cannot be {@code null} + * @param attribute the attribute that triggered this requirement, or {@code null} if no single attribute was responsible + * @return {@code true} if the requested capability is present; {@code false} if not. If {@code true}, hereafter + * {@code dependent}'s requirement for {@code requested} will not be treated as optional. + * @throws IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}. + * The complete set of capabilities is not known until the end of the model stage. + */ + default boolean hasOptionalCapability(UnaryServiceDescriptor> requested, String name, RuntimeCapability> dependent, AttributeDefinition attribute) { + Map.Entry+ * This method should be used in preference to {@link #registerAdditionalCapabilityRequirement(String, String, String)} + * when the caller's own configuration doesn't impose a hard requirement for the {@code requested} capability, but, + * if it is present it will be used. Once the caller declares an intent to use the capability by invoking this + * method and getting a {@code true} response, thereafter the system is aware that {@code dependent} is actually + * using {@code requested}, but will not prevent configuration changes that make {@code requested} + * unavailable. + *
+ * + * @param requested the service descriptor of the requested capability. Cannot be {@code null} + * @param parent the first dynamic name segment of the requested capability. + * @param child the second dynamic name segment of the requested capability. + * @param dependent the runtime capability that requires the other capability. Cannot be {@code null} + * @param attribute the attribute that triggered this requirement, or {@code null} if no single attribute was responsible + * @return {@code true} if the requested capability is present; {@code false} if not. If {@code true}, hereafter + * {@code dependent}'s requirement for {@code requested} will not be treated as optional. + * @throws IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}. + * The complete set of capabilities is not known until the end of the model stage. + */ + default boolean hasOptionalCapability(BinaryServiceDescriptor> requested, String parent, String child, RuntimeCapability> dependent, AttributeDefinition attribute) { + Map.Entry+ * This method should be used in preference to {@link #registerAdditionalCapabilityRequirement(String, String, String)} + * when the caller's own configuration doesn't impose a hard requirement for the {@code requested} capability, but, + * if it is present it will be used. Once the caller declares an intent to use the capability by invoking this + * method and getting a {@code true} response, thereafter the system is aware that {@code dependent} is actually + * using {@code requested}, but will not prevent configuration changes that make {@code requested} + * unavailable. + *
+ * + * @param requested the service descriptor of the requested capability. Cannot be {@code null} + * @param grandparent the first dynamic name segment of the requested capability. + * @param parent the second dynamic name segment of the requested capability. + * @param child the third dynamic name segment of the requested capability. + * @param dependent the runtime capability that requires the other capability. Cannot be {@code null} + * @param attribute the attribute that triggered this requirement, or {@code null} if no single attribute was responsible + * @return {@code true} if the requested capability is present; {@code false} if not. If {@code true}, hereafter + * {@code dependent}'s requirement for {@code requested} will not be treated as optional. + * @throws IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}. + * The complete set of capabilities is not known until the end of the model stage. + */ + default boolean hasOptionalCapability(TernaryServiceDescriptor> requested, String grandparent, String parent, String child, RuntimeCapability> dependent, AttributeDefinition attribute) { + Map.Entry+ * This method should be used in preference to {@link #registerAdditionalCapabilityRequirement(String, String, String)} + * when the caller's own configuration doesn't impose a hard requirement for the {@code requested} capability, but, + * if it is present it will be used. Once the caller declares an intent to use the capability by invoking this + * method and getting a {@code true} response, thereafter the system is aware that {@code dependent} is actually + * using {@code requested}, but will not prevent configuration changes that make {@code requested} + * unavailable. + *
+ * + * @param requested the service descriptor of the requested capability. Cannot be {@code null} + * @param greatGrandparent the first dynamic name segment of the requested capability. + * @param grandparent the second dynamic name segment of the requested capability. + * @param parent the third dynamic name segment of the requested capability. + * @param child the fourth dynamic name segment of the requested capability. + * @param dependent the runtime capability that requires the other capability. Cannot be {@code null} + * @param attribute the attribute that triggered this requirement, or {@code null} if no single attribute was responsible + * @return {@code true} if the requested capability is present; {@code false} if not. If {@code true}, hereafter + * {@code dependent}'s requirement for {@code requested} will not be treated as optional. + * @throws IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}. + * The complete set of capabilities is not known until the end of the model stage. + */ + default boolean hasOptionalCapability(QuaternaryServiceDescriptor> requested, String greatGrandparent, String grandparent, String parent, String child, RuntimeCapability> dependent, AttributeDefinition attribute) { + Map.Entry