All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.as.clustering.controller.ResourceDescriptor Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2015, 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.clustering.controller;

import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;

import org.jboss.as.clustering.function.Predicates;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.CapabilityReferenceRecorder;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.ResourceDefinition;
import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
import org.jboss.as.controller.registry.Resource;
import org.jboss.dmr.ModelNode;

/**
 * Describes the properties of resource used by {@link AddStepHandler}.
 * Supports supplying attributes and capabilities via enumerations.
 * Also supports defining extra parameters that are not actually attributes of the target resource.
 * @author Paul Ferraro
 */
public class ResourceDescriptor implements AddStepHandlerDescriptor {

    private static final Comparator PATH_COMPARATOR = new Comparator<>() {
        @Override
        public int compare(PathElement path1, PathElement path2) {
            int result = path1.getKey().compareTo(path2.getKey());
            return (result == 0) ? path1.getValue().compareTo(path2.getValue()) : result;
        }
    };
    private static final Comparator ATTRIBUTE_COMPARATOR = Comparator.comparing(AttributeDefinition::getName);
    private static final Comparator CAPABILITY_COMPARATOR = Comparator.comparing(Capability::getName);
    @SuppressWarnings("deprecation")
    private static final Comparator CAPABILITY_REFERENCE_COMPARATOR = Comparator.comparing(CapabilityReferenceRecorder::getBaseDependentName);

    private final ResourceDescriptionResolver resolver;
    private Map> capabilities = Map.of();
    private List attributes = List.of();
    private Map customAttributes = Map.of();
    private List ignoredAttributes = List.of();
    private List parameters = List.of();
    private Set requiredChildren = Set.of();
    private Set requiredSingletonChildren = Set.of();
    private Map attributeTranslations = Map.of();
    private List runtimeResourceRegistrations = List.of();
    private Set resourceCapabilityReferences = Set.of();
    private UnaryOperator addOperationTransformer = UnaryOperator.identity();
    private UnaryOperator operationTransformer = UnaryOperator.identity();
    private UnaryOperator resourceTransformer = UnaryOperator.identity();

    public ResourceDescriptor(ResourceDescriptionResolver resolver) {
        this.resolver = resolver;
    }

    @Override
    public ResourceDescriptionResolver getDescriptionResolver() {
        return this.resolver;
    }

    @Override
    public Map> getCapabilities() {
        return this.capabilities;
    }

    @Override
    public Collection getAttributes() {
        return this.attributes;
    }

    @Override
    public Collection getIgnoredAttributes() {
        return this.ignoredAttributes;
    }

    @Override
    public Collection getExtraParameters() {
        return this.parameters;
    }

    @Override
    public Set getRequiredChildren() {
        return this.requiredChildren;
    }

    @Override
    public Set getRequiredSingletonChildren() {
        return this.requiredSingletonChildren;
    }

    @Override
    public Map getAttributeTranslations() {
        return this.attributeTranslations;
    }

    @Override
    public Map getCustomAttributes() {
        return this.customAttributes;
    }

    @Override
    public Collection getRuntimeResourceRegistrations() {
        return this.runtimeResourceRegistrations;
    }

    @Override
    public Set getResourceCapabilityReferences() {
        return this.resourceCapabilityReferences;
    }

    @Override
    public UnaryOperator getOperationTransformation() {
        return this.operationTransformer;
    }

    @Override
    public UnaryOperator getResourceTransformation() {
        return this.resourceTransformer;
    }

    @Override
    public UnaryOperator getAddOperationTransformation() {
        return this.addOperationTransformer;
    }

    public ResourceDescriptor addAttribute(Attribute attribute, OperationStepHandler writeAttributeHandler) {
        return this.addAttribute(attribute.getDefinition(), writeAttributeHandler);
    }

    public ResourceDescriptor addAttribute(AttributeDefinition attribute, OperationStepHandler writeAttributeHandler) {
        if (this.customAttributes.isEmpty()) {
            this.customAttributes = Map.of(attribute, writeAttributeHandler);
        } else {
            if (this.customAttributes.size() == 1) {
                Map existing = this.customAttributes;
                this.customAttributes = new TreeMap<>(ATTRIBUTE_COMPARATOR);
                this.customAttributes.putAll(existing);
            }
            this.customAttributes.put(attribute, writeAttributeHandler);
        }
        return this;
    }

    public  & Attribute> ResourceDescriptor addAttributes(Class enumClass) {
        return this.addAttributes(EnumSet.allOf(enumClass));
    }

    public ResourceDescriptor addAttributes(Set attributes) {
        return this.addAttributes(attributes.stream());
    }

    public ResourceDescriptor addAttributes(Attribute... attributes) {
        return this.addAttributes(List.of(attributes).stream());
    }

    private ResourceDescriptor addAttributes(Stream attributes) {
        return this.addAttributes(attributes.map(Attribute::getDefinition)::iterator);
    }

    public ResourceDescriptor addAttributes(AttributeDefinition... attributes) {
        return this.addAttributes(List.of(attributes));
    }

    public ResourceDescriptor addAttributes(Iterable attributes) {
        if (this.attributes.isEmpty()) {
            this.attributes = new LinkedList<>();
        }
        for (AttributeDefinition attribute : attributes) {
            this.attributes.add(attribute);
        }
        return this;
    }

    public  & Attribute> ResourceDescriptor addIgnoredAttributes(Class enumClass) {
        return this.addIgnoredAttributes(EnumSet.allOf(enumClass));
    }

    public ResourceDescriptor addIgnoredAttributes(Set attributes) {
        return this.addIgnoredAttributes(attributes.stream());
    }

    public ResourceDescriptor addIgnoredAttributes(Attribute... attributes) {
        return this.addIgnoredAttributes(List.of(attributes).stream());
    }

    private ResourceDescriptor addIgnoredAttributes(Stream attributes) {
        return this.addIgnoredAttributes(attributes.map(Attribute::getDefinition)::iterator);
    }

    public ResourceDescriptor addIgnoredAttributes(AttributeDefinition... attributes) {
        return this.addIgnoredAttributes(List.of(attributes));
    }

    public ResourceDescriptor addIgnoredAttributes(Iterable attributes) {
        if (this.ignoredAttributes.isEmpty()) {
            this.ignoredAttributes = new LinkedList<>();
        }
        for (AttributeDefinition attribute : attributes) {
            this.ignoredAttributes.add(attribute);
        }
        return this;
    }

    public  & Attribute> ResourceDescriptor addExtraParameters(Class enumClass) {
        return this.addExtraParameters(EnumSet.allOf(enumClass));
    }

    public ResourceDescriptor addExtraParameters(Set parameters) {
        return this.addExtraParameters(parameters.stream());
    }

    public ResourceDescriptor addExtraParameters(Attribute... parameters) {
        return this.addExtraParameters(List.of(parameters).stream());
    }

    private ResourceDescriptor addExtraParameters(Stream parameters) {
        return this.addExtraParameters(parameters.map(Attribute::getDefinition)::iterator);
    }

    public ResourceDescriptor addExtraParameters(AttributeDefinition... parameters) {
        return this.addExtraParameters(List.of(parameters));
    }

    public ResourceDescriptor addExtraParameters(Iterable parameters) {
        if (this.parameters.isEmpty()) {
            this.parameters = new LinkedList<>();
        }
        for (AttributeDefinition parameter : parameters) {
            this.parameters.add(parameter);
        }
        return this;
    }

    public  & Capability> ResourceDescriptor addCapabilities(Class enumClass) {
        return this.addCapabilities(Predicates.always(), enumClass);
    }

    public ResourceDescriptor addCapabilities(Capability... capabilities) {
        return this.addCapabilities(Predicates.always(), capabilities);
    }

    public ResourceDescriptor addCapabilities(Iterable capabilities) {
        return this.addCapabilities(Predicates.always(), capabilities);
    }

    public  & Capability> ResourceDescriptor addCapabilities(Predicate predicate, Class enumClass) {
        return this.addCapabilities(predicate, EnumSet.allOf(enumClass));
    }

    public ResourceDescriptor addCapabilities(Predicate predicate, Capability... capabilities) {
        return this.addCapabilities(predicate, Arrays.asList(capabilities));
    }

    public ResourceDescriptor addCapabilities(Predicate predicate, Iterable capabilities) {
        if (this.capabilities.isEmpty()) {
            this.capabilities = new TreeMap<>(CAPABILITY_COMPARATOR);
        }
        for (Capability capability : capabilities) {
            this.capabilities.put(capability, predicate);
        }
        return this;
    }

    public  & ResourceDefinitionProvider> ResourceDescriptor addRequiredChildren(Class enumClass) {
        return this.addRequiredChildren(EnumSet.allOf(enumClass));
    }

    public ResourceDescriptor addRequiredChildren(Set providers) {
        return this.addRequiredChildren(providers.stream().map(ResourceDefinitionProvider::getPathElement)::iterator);
    }

    public ResourceDescriptor addRequiredChildren(PathElement... paths) {
        return this.addRequiredChildren(List.of(paths));
    }

    public ResourceDescriptor addRequiredChildren(Iterable paths) {
        if (this.requiredChildren.isEmpty()) {
            this.requiredChildren = new TreeSet<>(PATH_COMPARATOR);
        }
        for (PathElement path : paths) {
            this.requiredChildren.add(path);
        }
        return this;
    }

    public  & ResourceDefinition> ResourceDescriptor addRequiredSingletonChildren(Class enumClass) {
        return this.addRequiredSingletonChildren(EnumSet.allOf(enumClass));
    }

    public ResourceDescriptor addRequiredSingletonChildren(Set definitions) {
        return this.addRequiredSingletonChildren(definitions.stream().map(ResourceDefinition::getPathElement)::iterator);
    }

    public ResourceDescriptor addRequiredSingletonChildren(PathElement... paths) {
        return this.addRequiredSingletonChildren(List.of(paths));
    }

    public ResourceDescriptor addRequiredSingletonChildren(Iterable paths) {
        if (this.requiredSingletonChildren.isEmpty()) {
            this.requiredSingletonChildren = new TreeSet<>(PATH_COMPARATOR);
        }
        for (PathElement path : paths) {
            this.requiredSingletonChildren.add(path);
        }
        return this;
    }

    public ResourceDescriptor addAlias(Attribute alias, Attribute target) {
        return this.addAttributeTranslation(alias, () -> target);
    }

    public ResourceDescriptor addAttributeTranslation(Attribute sourceAttribute, AttributeTranslation translation) {
        if (this.attributeTranslations.isEmpty()) {
            this.attributeTranslations = Map.of(sourceAttribute.getDefinition(), translation);
        } else {
            if (this.attributeTranslations.size() == 1) {
                Map existing = this.attributeTranslations;
                this.attributeTranslations = new TreeMap<>(ATTRIBUTE_COMPARATOR);
                this.attributeTranslations.putAll(existing);
            }
            this.attributeTranslations.put(sourceAttribute.getDefinition(), translation);
        }
        return this;
    }

    public ResourceDescriptor addRuntimeResourceRegistration(RuntimeResourceRegistration registration) {
        if (this.runtimeResourceRegistrations.isEmpty()) {
            this.runtimeResourceRegistrations = List.of(registration);
        } else {
            if (this.runtimeResourceRegistrations.size() == 1) {
                List existing = this.runtimeResourceRegistrations;
                this.runtimeResourceRegistrations = new LinkedList<>();
                this.runtimeResourceRegistrations.addAll(existing);
            }
            this.runtimeResourceRegistrations.add(registration);
        }
        return this;
    }

    public ResourceDescriptor addResourceCapabilityReference(CapabilityReferenceRecorder reference) {
        if (this.resourceCapabilityReferences.isEmpty()) {
            this.resourceCapabilityReferences = Set.of(reference);
        } else {
            if (this.resourceCapabilityReferences.size() == 1) {
                Set existing = this.resourceCapabilityReferences;
                this.resourceCapabilityReferences = new TreeSet<>(CAPABILITY_REFERENCE_COMPARATOR);
                this.resourceCapabilityReferences.addAll(existing);
            }
            this.resourceCapabilityReferences.add(reference);
        }
        return this;
    }

    public ResourceDescriptor setAddOperationTransformation(UnaryOperator transformation) {
        this.addOperationTransformer = transformation;
        return this;
    }

    public ResourceDescriptor setOperationTransformation(UnaryOperator transformation) {
        this.operationTransformer = transformation;
        return this;
    }

    public ResourceDescriptor setResourceTransformation(UnaryOperator transformation) {
        this.resourceTransformer = transformation;
        return this;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy