/* * JBoss, Home of Professional Open Source. * Copyright 2014, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.controller.capability; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Base class for a core or subsystem capability. * * @author Brian Stansberry (c) 2014 Red Hat Inc. */ public abstract class AbstractCapability implements Capability { private final String name; private final boolean dynamic; private final Set<String> requirements; private final Set<String> optionalRequirements; private final Set<String> runtimeOnlyRequirements; private final Set<String> dynamicRequirements; private final Set<String> dynamicOptionalRequirements; // note there is no field "dynamicRuntimeOnlyRequirements" as a // dynamic requirement requires some configuration value to // specify the dynamic part of the requirement name, and a // runtime-only requirement by definition cannot be specified // via configuration /** * Creates a new capability * @param name the name of the capability. Cannot be {@code null} * @param requirements names of other capabilities upon which this capability has a hard requirement. May be {@code null} * @param optionalRequirements names of other capabilities upon which this capability has an optional requirement. May be {@code null} * @param runtimeOnlyRequirements names of other capabilities upon which this capability has an optional, runtime-only requirement. May be {@code null} * @param dynamicRequirements names of other dynamically named capabilities upon a concrete instance of which this * capability will have a hard requirement once the full name is known. May be {@code null} * @param dynamicOptionalRequirements names of other dynamically named capabilities upon a concrete instance of which this * capability will have an optional requirement once the full name is known. May be {@code null} */ protected AbstractCapability(final String name, final boolean dynamic, final Set<String> requirements, final Set<String> optionalRequirements, final Set<String> runtimeOnlyRequirements, final Set<String> dynamicRequirements, final Set<String> dynamicOptionalRequirements) { assert name != null; this.name = name; this.dynamic = dynamic; this.requirements = establishRequirements(requirements); this.optionalRequirements = establishRequirements(optionalRequirements); this.runtimeOnlyRequirements = establishRequirements(runtimeOnlyRequirements); this.dynamicRequirements = establishRequirements(dynamicRequirements); this.dynamicOptionalRequirements = establishRequirements(dynamicOptionalRequirements); } private static Set<String> establishRequirements(Set<String> input) { if (input != null && !input.isEmpty()) { return Collections.unmodifiableSet(new HashSet<String>(input)); } else { return Collections.emptySet(); } } /** * Gets the basic name of the capability. If {@link #isDynamicallyNamed()} returns {@code true} * this will be the basic name of the capability, not including any dynamic portions. * * @return the name. Will not be {@code null} * * @see #getDynamicName(String) */ @Override public String getName() { return name; } /** * Gets the names of other capabilities required by this capability. * These are static requirements. * * @return the capability names. Will not be {@code null} but may be empty. */ @Override public Set<String> getRequirements() { return requirements; } /** * Gets the names of other capabilities optionally required by this capability. * Whether this capability will actually require the other capabilities is not * statically known but rather depends on this capability's own configuration. * * @return the capability names. Will not be {@code null} but may be empty. */ @Override public Set<String> getOptionalRequirements() { return optionalRequirements; } /** * Gets the names of other capabilities optionally used by this capability if they * are present in the runtime, but where the use of the other capability will never * be mandated by the persistent configuration. Differs from * {@link #getOptionalRequirements() optional requirements} * in that optional requirements may or may not be specified by the persistent * configuration, but if they are the capability must be present or the configuration * is invalid. * * @return the capability names. Will not be {@code null} but may be empty. */ @Override public Set<String> getRuntimeOnlyRequirements() { return runtimeOnlyRequirements; } /** * Gets the names of other dynamically named capabilities upon a concrete instance of which this * capability will have a hard requirement once the full name is known. It is statically * known that some variant of these base capability names will be required, but the * exact name will not be known until this capability's configuration is read. * * @return the capability names. Will not be {@code null} but may be empty. */ @Override public Set<String> getDynamicRequirements() { return dynamicRequirements; } /** * Gets the names of other dynamically named capabilities upon a concrete instance of which this * capability will have an optional requirement once the full name is known. * Whether this capability will actually require the other capabilities is not * statically known but rather depends on this capability's own configuration. * * @return the capability names. Will not be {@code null} but may be empty. */ @Override public Set<String> getDynamicOptionalRequirements() { return dynamicOptionalRequirements; } /** * Gets whether this capability is a dynamically named one, whose runtime variants * will have a dynamic element added to the base name provided by {@link #getName()}. * * @return {@code true} if this capability is dynamically named */ @Override public boolean isDynamicallyNamed() { return dynamic; } /** * Gets the full name of a capbility, including a dynamic element * @param dynamicNameElement the dynamic portion of the name. Cannot be {@code null} * @return the full capability name * * @throws IllegalStateException if {@link #isDynamicallyNamed()} returns {@code false} */ @Override public String getDynamicName(String dynamicNameElement) { if (!dynamic) { throw new IllegalStateException(); } return name + "." + dynamicNameElement; } // /** // * Gets an internationalized text description of the capability. // * // * @param locale the locale to use. Cannot be {@code null} // * @return the text description, or {@code null} if there is no text description // * // * @throws java.lang.IllegalArgumentException if {@code locale} is {@code null} // */ // public abstract String getDescription(Locale locale); /** * {@inheritDoc} * * @return {@code true} if {@code o} is the same type as this object and its {@link #getName() name} is equal */ @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AbstractCapability that = (AbstractCapability) o; return name.equals(that.name); } @Override public int hashCode() { return name.hashCode(); } /** * {@inheritDoc} * * @return the value returned by {@link #getName()} */ @Override public String toString() { return name; } }