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

software.amazon.smithy.model.shapes.EntityShape Maven / Gradle / Ivy

/*
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package software.amazon.smithy.model.shapes;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import software.amazon.smithy.utils.BuilderRef;

/**
 * Abstract class representing service and resource shapes.
 */
public abstract class EntityShape extends Shape {

    private final Set resources;
    private final Set introducedResources;
    private final Set operations;
    private final Set introducedOperations;

    EntityShape(Builder builder) {
        super(builder, false);

        if (getMixins().isEmpty()) {
            resources = builder.resources.copy();
            introducedResources = resources;
            operations = builder.operations.copy();
            introducedOperations = operations;
        } else {
            Set computedResources = new LinkedHashSet<>();
            Set computedOperations = new LinkedHashSet<>();

            for (Shape shape : builder.getMixins().values()) {
                // validateMixins should have already assured that this is an EntityShape.
                EntityShape mixin = (EntityShape) shape;
                computedResources.addAll(mixin.getResources());
                computedOperations.addAll(mixin.getOperations());
            }

            introducedResources = builder.resources.copy();
            introducedOperations = builder.operations.copy();

            computedResources.addAll(introducedResources);
            computedOperations.addAll(introducedOperations);

            resources = Collections.unmodifiableSet(computedResources);
            operations = Collections.unmodifiableSet(computedOperations);
        }
    }

    /**
     * @return Get all the resources directly bound to this shape.
     */
    public final Set getResources() {
        return resources;
    }

    /**
     * Gets all the directly-bound resources introduced by this shape and
     * not inherited from mixins.
     *
     * @return Gets the introduced resources directly-bound to the shape.
     */
    public final Set getIntroducedResources() {
        return introducedResources;
    }

    /**
     * Gets operations bound only through the "operations" property.
     *
     * 

This will not include operations bound to resources using * a lifecycle operation binding. This will also not include * operations bound to this entity through sub-resources. * * @return Get the "operations" directly bound to this shape. * @see #getAllOperations() * @see software.amazon.smithy.model.knowledge.TopDownIndex#getContainedOperations */ public final Set getOperations() { return operations; } /** * Gets operations bound through the "operations" property that * were not inherited from mixins. * *

This will not include operations bound to resources using * a lifecycle operation binding. This will also not include * operations bound to this entity through sub-resources. * * @return Gets the introduced operations. */ public final Set getIntroducedOperations() { return introducedOperations; } /** * Get all operations directly bound to this shape. * *

This will include operations bound directly to resources * using a lifecycle operation binding. This will not include * operations bound to this entity through sub-resources. * * @return Returns all operations bound to the shape. * @see software.amazon.smithy.model.knowledge.TopDownIndex#getContainedOperations */ public Set getAllOperations() { return getOperations(); } @Override public boolean equals(Object other) { if (!super.equals(other)) { return false; } EntityShape o = (EntityShape) other; return getResources().equals(o.getResources()) && getAllOperations().equals(o.getAllOperations()); } /** * Builder used to create a Service or Resource shape. * @param Concrete builder type. * @param Shape type being created. */ public abstract static class Builder, S extends EntityShape> extends AbstractShapeBuilder { private final BuilderRef> resources = BuilderRef.forOrderedSet(); private final BuilderRef> operations = BuilderRef.forOrderedSet(); @SuppressWarnings("unchecked") public B operations(Collection ids) { clearOperations(); operations.get().addAll(ids); return (B) this; } @SuppressWarnings("unchecked") public B addOperation(ToShapeId id) { operations.get().add(id.toShapeId()); return (B) this; } public B addOperation(String id) { return addOperation(ShapeId.from(id)); } @SuppressWarnings("unchecked") public B removeOperation(ToShapeId id) { operations.get().remove(id.toShapeId()); return (B) this; } @SuppressWarnings("unchecked") public B clearOperations() { operations.clear(); return (B) this; } @SuppressWarnings("unchecked") public B resources(Collection ids) { clearResources(); resources.get().addAll(ids); return (B) this; } @SuppressWarnings("unchecked") public B addResource(ToShapeId id) { resources.get().add(id.toShapeId()); return (B) this; } public B addResource(String id) { return addResource(ShapeId.from(id)); } @SuppressWarnings("unchecked") public B removeResource(ToShapeId id) { resources.get().remove(id.toShapeId()); return (B) this; } @SuppressWarnings("unchecked") public B clearResources() { resources.clear(); return (B) this; } @Override @SuppressWarnings("unchecked") public B flattenMixins() { if (getMixins().isEmpty()) { return (B) this; } Set flatResources = new LinkedHashSet<>(); Set flatOperations = new LinkedHashSet<>(); for (Shape shape : getMixins().values()) { EntityShape mixin = (EntityShape) shape; flatResources.addAll(mixin.getResources()); flatOperations.addAll(mixin.getOperations()); } flatResources.addAll(resources.peek()); flatOperations.addAll(operations.peek()); resources(flatResources); operations(flatOperations); return super.flattenMixins(); } } }