diff --git a/controller/src/main/java/org/jboss/as/controller/capability/RuntimeCapability.java b/controller/src/main/java/org/jboss/as/controller/capability/RuntimeCapability.java index 0c60c5e1082..822770e7a24 100644 --- a/controller/src/main/java/org/jboss/as/controller/capability/RuntimeCapability.java +++ b/controller/src/main/java/org/jboss/as/controller/capability/RuntimeCapability.java @@ -5,12 +5,12 @@ package org.jboss.as.controller.capability; -import java.util.Collections; -import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.ServiceNameFactory; @@ -133,7 +133,7 @@ private RuntimeCapability(Builder builder) { assert builder.baseName != null; this.name = builder.baseName; this.dynamic = builder.dynamic; - this.requirements = establishRequirements(builder.requirements); + this.requirements = builder.requirements; this.dynamicNameMapper = Objects.requireNonNullElse(builder.dynamicNameMapper, UnaryCapabilityNameResolver.DEFAULT); this.runtimeAPI = builder.runtimeAPI; this.serviceValueType = builder.serviceValueType; @@ -141,14 +141,6 @@ private RuntimeCapability(Builder builder) { this.stability = builder.stability; } - private static Set establishRequirements(Set input) { - if (input != null && !input.isEmpty()) { - return Set.copyOf(input); - } else { - return Collections.emptySet(); - } - } - /** * Constructor for use by {@link #fromBaseCapability(String...)} */ @@ -161,7 +153,7 @@ private RuntimeCapability(String baseName, Class serviceValueType, ServiceNam ) { this.name = buildDynamicCapabilityName(baseName, dynamicElement); this.dynamic = false; - this.requirements = establishRequirements(requirements); + this.requirements = requirements; this.dynamicNameMapper = Objects.requireNonNullElse(dynamicNameMapper, UnaryCapabilityNameResolver.DEFAULT); this.runtimeAPI = runtimeAPI; this.serviceValueType = serviceValueType; @@ -321,8 +313,8 @@ public RuntimeCapability fromBaseCapability(String ... dynamicElement) { assert isDynamicallyNamed(); assert dynamicElement != null; assert dynamicElement.length > 0; - return new RuntimeCapability<>(getName(), serviceValueType, getServiceName(), runtimeAPI, - getRequirements(), allowMultipleRegistrations,dynamicNameMapper, this.stability, dynamicElement); + return new RuntimeCapability<>(this.name, serviceValueType, getServiceName(), runtimeAPI, + this.requirements, allowMultipleRegistrations, dynamicNameMapper, this.stability, dynamicElement); } @@ -349,8 +341,8 @@ public RuntimeCapability fromBaseCapability(PathAddress path) { assert path != null; String[] dynamicElement = dynamicNameMapper.apply(path); assert dynamicElement.length > 0; - return new RuntimeCapability<>(getName(), serviceValueType, getServiceName(), runtimeAPI, - getRequirements(), allowMultipleRegistrations, dynamicNameMapper, this.stability, dynamicElement); + return new RuntimeCapability<>(this.name, serviceValueType, getServiceName(), runtimeAPI, + this.requirements, allowMultipleRegistrations, dynamicNameMapper, this.stability, dynamicElement); } @Override @@ -420,7 +412,7 @@ public static class Builder { private final T runtimeAPI; private final boolean dynamic; private Class serviceValueType; - private Set requirements; + private Set requirements = Set.of(); private boolean allowMultipleRegistrations = ALLOW_MULTIPLE; private Function dynamicNameMapper = UnaryCapabilityNameResolver.DEFAULT; private Stability stability = Stability.DEFAULT; @@ -562,13 +554,35 @@ public Builder setServiceType(Class type) { */ public Builder addRequirements(String... requirements) { assert requirements != null; - if (this.requirements == null) { - this.requirements = new HashSet<>(requirements.length); + if (requirements.length > 0) { + this.requirements = this.requirements.isEmpty() ? Set.of(requirements) : Stream.concat(this.requirements.stream(), Stream.of(requirements)).collect(Collectors.toUnmodifiableSet()); } - Collections.addAll(this.requirements, requirements); return this; } + /** + * Adds the names of other capabilities that this capability requires. The requirement + * for these capabilities will automatically be registered when this capability is registered. + * + * @param requirements the capability names + * @return the builder + */ + public Builder addRequirements(NullaryServiceDescriptor... requirements) { + assert requirements != null; + switch (requirements.length) { + case 0: + return this; + case 1: + return this.addRequirements(requirements[0].getName()); + case 2: + return this.addRequirements(requirements[0].getName(), requirements[1].getName()); + default: + Stream mapped = Stream.of(requirements).map(NullaryServiceDescriptor::getName); + this.requirements = (this.requirements.isEmpty() ? mapped : Stream.concat(this.requirements.stream(), mapped)).collect(Collectors.toUnmodifiableSet()); + return this; + } + } + /** * Sets whether this capability can be registered at more than one point within the same * overall scope.