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

software.amazon.awssdk.enhanced.dynamodb.mapper.ImmutableAttribute Maven / Gradle / Ivy

/*
 * Copyright 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.awssdk.enhanced.dynamodb.mapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import software.amazon.awssdk.annotations.NotThreadSafe;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverterProvider;
import software.amazon.awssdk.enhanced.dynamodb.EnhancedType;
import software.amazon.awssdk.enhanced.dynamodb.internal.mapper.ResolvedImmutableAttribute;
import software.amazon.awssdk.utils.Validate;

/**
 * A class that represents an attribute on an mapped immutable item. A {@link StaticImmutableTableSchema} composes
 * multiple attributes that map to a common immutable item class.
 * 

* The recommended way to use this class is by calling * {@link software.amazon.awssdk.enhanced.dynamodb.TableSchema#builder(Class, Class)}. * Example: * {@code * TableSchema.builder(Customer.class, Customer.Builder.class) * .addAttribute(String.class, * a -> a.name("customer_name").getter(Customer::name).setter(Customer.Builder::name)) * // ... * .build(); * } *

* It's also possible to construct this class on its own using the static builder. Example: * {@code * ImmutableAttribute customerNameAttribute = * ImmutableAttribute.builder(Customer.class, Customer.Builder.class, String.class) * .name("customer_name") * .getter(Customer::name) * .setter(Customer.Builder::name) * .build(); * } * @param the class of the immutable item this attribute maps into. * @param the class of the builder for the immutable item this attribute maps into. * @param the class that the value of this attribute converts to. */ @SdkPublicApi @ThreadSafe public final class ImmutableAttribute { private final String name; private final Function getter; private final BiConsumer setter; private final Collection tags; private final EnhancedType type; private final AttributeConverter attributeConverter; private ImmutableAttribute(Builder builder) { this.name = Validate.paramNotNull(builder.name, "name"); this.getter = Validate.paramNotNull(builder.getter, "getter"); this.setter = Validate.paramNotNull(builder.setter, "setter"); this.tags = builder.tags == null ? Collections.emptyList() : Collections.unmodifiableCollection(builder.tags); this.type = Validate.paramNotNull(builder.type, "type"); this.attributeConverter = builder.attributeConverter; } /** * Constructs a new builder for this class using supplied types. * @param itemClass The class of the immutable item that this attribute composes. * @param builderClass The class of the builder for the immutable item that this attribute composes. * @param attributeType A {@link EnhancedType} that represents the type of the value this attribute stores. * @return A new typed builder for an attribute. */ public static Builder builder(Class itemClass, Class builderClass, EnhancedType attributeType) { return new Builder<>(attributeType); } /** * Constructs a new builder for this class using supplied types. * @param itemClass The class of the item that this attribute composes. * @param builderClass The class of the builder for the immutable item that this attribute composes. * @param attributeClass A class that represents the type of the value this attribute stores. * @return A new typed builder for an attribute. */ public static Builder builder(Class itemClass, Class builderClass, Class attributeClass) { return new Builder<>(EnhancedType.of(attributeClass)); } /** * The name of this attribute */ public String name() { return this.name; } /** * A function that can get the value of this attribute from a modelled immutable item it composes. */ public Function getter() { return this.getter; } /** * A function that can set the value of this attribute on a builder for the immutable modelled item it composes. */ public BiConsumer setter() { return this.setter; } /** * A collection of {@link StaticAttributeTag} associated with this attribute. */ public Collection tags() { return this.tags; } /** * A {@link EnhancedType} that represents the type of the value this attribute stores. */ public EnhancedType type() { return this.type; } /** * A custom {@link AttributeConverter} that will be used to convert this attribute. * If no custom converter was provided, the value will be null. * @see Builder#attributeConverter */ public AttributeConverter attributeConverter() { return this.attributeConverter; } /** * Converts an instance of this class to a {@link Builder} that can be used to modify and reconstruct it. */ public Builder toBuilder() { return new Builder(this.type).name(this.name) .getter(this.getter) .setter(this.setter) .tags(this.tags) .attributeConverter(this.attributeConverter); } ResolvedImmutableAttribute resolve(AttributeConverterProvider attributeConverterProvider) { return ResolvedImmutableAttribute.create(this, converterFrom(attributeConverterProvider)); } private AttributeConverter converterFrom(AttributeConverterProvider attributeConverterProvider) { return (attributeConverter != null) ? attributeConverter : attributeConverterProvider.converterFor(type); } /** * A typed builder for {@link ImmutableAttribute}. * @param the class of the item this attribute maps into. * @param the class that the value of this attribute converts to. */ @NotThreadSafe public static final class Builder { private final EnhancedType type; private String name; private Function getter; private BiConsumer setter; private List tags; private AttributeConverter attributeConverter; private Builder(EnhancedType type) { this.type = type; } /** * The name of this attribute */ public Builder name(String name) { this.name = name; return this; } /** * A function that can get the value of this attribute from a modelled item it composes. */ public Builder getter(Function getter) { this.getter = getter; return this; } /** * A function that can set the value of this attribute on a modelled item it composes. */ public Builder setter(BiConsumer setter) { this.setter = setter; return this; } /** * A collection of {@link StaticAttributeTag} associated with this attribute. Overwrites any existing tags. */ public Builder tags(Collection tags) { this.tags = new ArrayList<>(tags); return this; } /** * A collection of {@link StaticAttributeTag} associated with this attribute. Overwrites any existing tags. */ public Builder tags(StaticAttributeTag... tags) { this.tags = Arrays.asList(tags); return this; } /** * Associates a single {@link StaticAttributeTag} with this attribute. Adds to any existing tags. */ public Builder addTag(StaticAttributeTag tag) { if (this.tags == null) { this.tags = new ArrayList<>(); } this.tags.add(tag); return this; } /** * An {@link AttributeConverter} for the attribute type ({@link EnhancedType}), that can convert this attribute. * It takes precedence over any converter for this type provided by the table schema * {@link AttributeConverterProvider}. */ public Builder attributeConverter(AttributeConverter attributeConverter) { this.attributeConverter = attributeConverter; return this; } /** * Builds a {@link StaticAttributeTag} from the values stored in this builder. */ public ImmutableAttribute build() { return new ImmutableAttribute<>(this); } } }