software.amazon.smithy.model.shapes.ResourceShape 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.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import software.amazon.smithy.model.traits.MixinTrait;
import software.amazon.smithy.utils.BuilderRef;
import software.amazon.smithy.utils.ToSmithyBuilder;
/**
* Represents a {@code resource} shape.
*/
public final class ResourceShape extends EntityShape implements ToSmithyBuilder {
private final Map identifiers;
private final Map properties;
private final ShapeId put;
private final ShapeId create;
private final ShapeId read;
private final ShapeId update;
private final ShapeId delete;
private final ShapeId list;
private final Set collectionOperations;
private final Set allOperations = new HashSet<>();
private ResourceShape(Builder builder) {
super(builder);
identifiers = builder.identifiers.copy();
properties = builder.properties.copy();
put = builder.put;
create = builder.create;
read = builder.read;
update = builder.update;
delete = builder.delete;
list = builder.list;
collectionOperations = builder.collectionOperations.copy();
// Compute all operations bound to the resource.
allOperations.addAll(getOperations());
allOperations.addAll(getCollectionOperations());
getPut().ifPresent(allOperations::add);
getCreate().ifPresent(allOperations::add);
getRead().ifPresent(allOperations::add);
getUpdate().ifPresent(allOperations::add);
getDelete().ifPresent(allOperations::add);
getList().ifPresent(allOperations::add);
if (hasTrait(MixinTrait.ID) && (!getIdentifiers().isEmpty()
|| getPut().isPresent()
|| getCreate().isPresent()
|| getRead().isPresent()
|| getUpdate().isPresent()
|| getDelete().isPresent()
|| getList().isPresent()
|| !getProperties().isEmpty()
|| !getOperations().isEmpty()
|| !getResources().isEmpty())) {
throw new IllegalStateException(String.format(
"Resource shapes with the mixin trait may not define any properties. Resource mixin shape `%s` "
+ "defines one or more properties.", getId()));
}
}
public static Builder builder() {
return new Builder();
}
@Override
public Builder toBuilder() {
Builder builder = updateBuilder(builder())
.identifiers(getIdentifiers())
.properties(properties)
.put(put)
.create(create)
.read(read)
.update(update)
.delete(delete)
.list(list);
getOperations().forEach(builder::addOperation);
getCollectionOperations().forEach(builder::addCollectionOperation);
getResources().forEach(builder::addResource);
return builder;
}
@Override
public R accept(ShapeVisitor visitor) {
return visitor.resourceShape(this);
}
@Override
public Optional asResourceShape() {
return Optional.of(this);
}
@Override
public Set getAllOperations() {
return Collections.unmodifiableSet(allOperations);
}
@Override
public ShapeType getType() {
return ShapeType.RESOURCE;
}
/**
* Gets the operations bound through the "collectionOperations" property.
*
* This will not include operations bound to resources using a lifecycle
* operation binding.
*
* @return Get the "collectionOperations" directly bound to this shape.
* @see #getAllOperations()
*/
public Set getCollectionOperations() {
return Collections.unmodifiableSet(collectionOperations);
}
/**
* Gets the identifiers of the resource.
*
* @return Returns the identifiers map of name to shape ID.
*/
public Map getIdentifiers() {
return identifiers;
}
/**
* @return Returns true if this resource defines any identifiers.
*/
public boolean hasIdentifiers() {
return !identifiers.isEmpty();
}
public Map getProperties() {
return properties;
}
public boolean hasProperties() {
return !properties.isEmpty();
}
/**
* Gets the put lifecycle operation of the resource.
*
* @return Returns the optionally found lifecycle.
*/
public Optional getPut() {
return Optional.ofNullable(put);
}
/**
* Gets the create lifecycle operation of the resource.
*
* @return Returns the optionally found lifecycle.
*/
public Optional getCreate() {
return Optional.ofNullable(create);
}
/**
* Gets the read lifecycle operation of the resource.
*
* @return Returns the optionally found lifecycle.
*/
public Optional getRead() {
return Optional.ofNullable(read);
}
/**
* Gets the update lifecycle operation of the resource.
*
* @return Returns the optionally found lifecycle.
*/
public Optional getUpdate() {
return Optional.ofNullable(update);
}
/**
* Gets the delete lifecycle operation of the resource.
*
* @return Returns the optionally found lifecycle.
*/
public Optional getDelete() {
return Optional.ofNullable(delete);
}
/**
* Gets the list lifecycle operation of the resource.
*
* @return Returns the optionally found lifecycle.
*/
public Optional getList() {
return Optional.ofNullable(list);
}
@Override
public boolean equals(Object other) {
if (!super.equals(other)) {
return false;
}
ResourceShape otherShape = (ResourceShape) other;
return identifiers.equals(otherShape.identifiers)
&& Objects.equals(properties, otherShape.properties)
&& Objects.equals(create, otherShape.create)
&& Objects.equals(put, otherShape.put)
&& Objects.equals(read, otherShape.read)
&& Objects.equals(update, otherShape.update)
&& Objects.equals(delete, otherShape.delete)
&& Objects.equals(list, otherShape.list);
}
/**
* Builder used to create a {@link ResourceShape}.
*/
public static final class Builder extends EntityShape.Builder {
private final BuilderRef