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

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

Go to download

The code in this module is not explicitly related to clustering, but rather contains resuable code used by clustering modules and any modules that integrate with clustering.

There is a newer version: 34.0.0.Final
Show newest version
/*
 * 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.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(ModelNode::isDefined, enumClass);
    }

    public ResourceDescriptor addCapabilities(Capability... capabilities) {
        return this.addCapabilities(ModelNode::isDefined, capabilities);
    }

    public ResourceDescriptor addCapabilities(Iterable capabilities) {
        return this.addCapabilities(ModelNode::isDefined, 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