
com.amazonaws.services.dynamodbv2.datamodeling.StandardAnnotationMaps Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk-dynamodb Show documentation
Show all versions of aws-java-sdk-dynamodb Show documentation
The AWS Java SDK for Amazon DynamoDB module holds the client classes that are used for communicating with Amazon DynamoDB Service
/*
* Copyright 2016-2016 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.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* 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 com.amazonaws.services.dynamodbv2.datamodeling;
import static com.amazonaws.services.dynamodbv2.model.KeyType.HASH;
import static com.amazonaws.services.dynamodbv2.model.KeyType.RANGE;
import com.amazonaws.annotation.SdkInternalApi;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Map of DynamoDB annotations.
*/
@SdkInternalApi
final class StandardAnnotationMaps {
/**
* Gets all the DynamoDB annotations for a given class.
* @param clazz The object type.
* @return The map of annotation type to annotation instance.
*/
static final TableMap of(final Class clazz) {
final DynamoDBMapperTableModel.Properties.Builder defaults;
defaults = new DynamoDBMapperTableModel.Properties.Builder();
defaults.withTargetType(clazz);
final TableMap map = new TableMap(defaults);
map.putAll(clazz);
return map;
}
/**
* Gets all the DynamoDB annotations; method annotations override field
* level annotations which override class/type level annotations.
* @param getter The getter method.
* @return The map of annotation type to annotation instance.
*/
static final FieldMap of(final Method getter) {
final DynamoDBMapperFieldModel.Properties.Builder defaults;
defaults = new DynamoDBMapperFieldModel.Properties.Builder();
defaults.withAttributeName(StandardBeanProperties.nameOf(getter, null));
defaults.withTargetType((Class)getter.getReturnType());
final FieldMap map = new FieldMap(defaults);
map.putAll(getter.getReturnType());
map.putAll(StandardBeanProperties.declaredFieldOf(getter));
map.putAll(getter);
return map;
}
/**
* Map of annotation type to annotation instance.
*/
static abstract class AnnotationMap {
private final Map,Annotation> map = new HashMap,Annotation>();
/**
* Put all the DynamoDB annotations present on the annotated element.
* @param annotated The annotated element.
* @return This instance for chaining.
*/
final AnnotationMap putAll(final AnnotatedElement annotated) {
if (annotated != null && annotated.getAnnotations().length > 0) {
final Map,Annotation> tmp = new HashMap,Annotation>();
for (final Annotation a1 : annotated.getAnnotations()) {
if (a1.annotationType().isAnnotationPresent(DynamoDB.class)) {
if (tmp.containsKey(a1.annotationType())) {
throw new DynamoDBMappingException("conflicting annotations " + a1 + " and " +
tmp.get(a1.annotationType()) + "; allowed only one of @" + a1.annotationType().getSimpleName());
}
tmp.put(a1.annotationType(), a1);
}
for (final Annotation a2 : a1.annotationType().getAnnotations()) {
if (a2.annotationType().isAnnotationPresent(DynamoDB.class)) {
if (tmp.containsKey(a2.annotationType())) {
throw new DynamoDBMappingException("conflicting annotations " + a1 + " and " +
tmp.get(a2.annotationType()) + "; allowed only one of @" + a2.annotationType().getSimpleName());
}
tmp.put(a2.annotationType(), a1);
}
}
}
this.map.putAll(tmp);
}
return this;
}
/**
* Indicates if any of the specified types are mapped.
* @param annotationTypes The annotation types.
* @return True if any are mapped, false otherwise.
*/
final boolean has(final Class extends Annotation> ... annotationTypes) {
for (final Class extends Annotation> annotationType : annotationTypes) {
if (get(annotationType, true) != null) {
return true;
}
}
return false;
}
/**
* Gets the annotation of the specified type; if the annotation is
* mapped to another type and the actual flag is specified, then it's
* meta annotation is returned.
* @param annotationType The annotation type.
* @param mappedBy To return the annotation mapped by the type.
* @return The annotation or null if not applicable.
*/
final A get(final Class annotationType, final boolean mappedBy) {
final Annotation annotation = this.map.get(annotationType);
if (mappedBy == false && annotation != null && annotation.annotationType() != annotationType) {
return (A)annotation.annotationType().getAnnotation(annotationType);
}
return (A)annotation;
}
/**
* Gets the actual annotation of the specified type; if the annotation
* is mapped to another type, then it's meta annotatoin is returned.
* @param annotationType The annotation type.
* @return The annotation or null if not applicable.
*/
final A get(final Class annotationType) {
return get(annotationType, false);
}
}
/**
* {@link DynamoDBMapperTableModel} annotations.
*/
static final class TableMap extends AnnotationMap implements DynamoDBMapperTableModel.Properties {
private final DynamoDBMapperTableModel.Properties defaults;
/**
* Constructs a new annotation map.
* @param defaults The default properties.
*/
private TableMap(final DynamoDBMapperTableModel.Properties defaults) {
this.defaults = defaults;
}
/**
* Gets the annotation {@code DynamoDBDocument} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBDocument document() {
return get(DynamoDBDocument.class);
}
/**
* Gets the annotation {@code DynamoDBTable} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBTable table() {
return get(DynamoDBTable.class);
}
/**
* Indicates if the map has typed annotations.
* @return True if any typed annotations, false otherwise.
*/
final boolean typed() {
return table() != null || document() != null;
}
/**
* {@inheritDoc}
*/
@Override
public Class targetType() {
return defaults.targetType();
}
/**
* {@inheritDoc}
*/
@Override
public final String tableName() {
return table() != null ? table().tableName() : defaults.tableName();
}
}
/**
* {@link DynamoDBMapperFieldModel} annotations.
*/
static final class FieldMap extends AnnotationMap implements DynamoDBMapperFieldModel.Properties {
private final DynamoDBMapperFieldModel.Properties defaults;
/**
* Constructs a new annotation map.
* @param defaults The default properties.
*/
private FieldMap(final DynamoDBMapperFieldModel.Properties defaults) {
this.defaults = defaults;
}
/**
* Gets the annotation {@code DynamoDBAutoGenerated} if present.
* @return The annotation if present, null otherwise.
*/
final Annotation autoGenerated() {
return get(DynamoDBAutoGenerated.class, true);
}
/**
* Gets the annotation {@code DynamoDBAutoGenerated} if present.
* @return The annotation if present, null otherwise.
*/
final Annotation typeConverted() {
return get(DynamoDBTypeConverted.class, true);
}
/**
* Gets the annotation {@code DynamoDBAttribute} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBAttribute attribute() {
return get(DynamoDBAttribute.class);
}
/**
* Gets the annotation {@code DynamoDBFlattened} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBFlattened flattened() {
return get(DynamoDBFlattened.class);
}
/**
* Gets the annotation {@code DynamoDBHashKey} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBHashKey hashKey() {
return get(DynamoDBHashKey.class);
}
/**
* Gets the annotation {@code DynamoDBIgnore} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBIgnore ignore() {
return get(DynamoDBIgnore.class);
}
/**
* Gets the annotation {@code DynamoDBIndexHashKey} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBIndexHashKey indexHashKey() {
return get(DynamoDBIndexHashKey.class);
}
/**
* Gets the annotation {@code DynamoDBIndexRangeKey} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBIndexRangeKey indexRangeKey() {
return get(DynamoDBIndexRangeKey.class);
}
/**
* Gets the annotation {@code DynamoDBMarshalling} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBMarshalling marshalling() {
return get(DynamoDBMarshalling.class);
}
/**
* Gets the annotation {@code DynamoDBNativeBoolean} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBNativeBoolean nativeBoolean() {
return get(DynamoDBNativeBoolean.class);
}
/**
* Gets the annotation {@code DynamoDBRangeKey} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBRangeKey rangeKey() {
return get(DynamoDBRangeKey.class);
}
/**
* Gets the annotation {@code DynamoDBVersionAttribute} if present.
* @return The annotation if present, null otherwise.
*/
final DynamoDBVersionAttribute version() {
return get(DynamoDBVersionAttribute.class);
}
/**
* Indicates if an ignored attribute.
* @return True if ignored, false otherwise.
*/
final boolean ignored() {
return ignore() != null;
}
/**
* Gets the flattened attribute names map.
* @return The attribute names map.
*/
final Map attributes() {
if (flattened() != null) {
if (flattened().attributes().length == 0) {
throw new DynamoDBMappingException("must specify one or more attributes");
}
final Map attributes = new HashMap();
for (final DynamoDBAttribute a : flattened().attributes()) {
if (a.mappedBy().isEmpty() || a.attributeName().isEmpty()) {
throw new DynamoDBMappingException("must specify mappedBy and attributeName");
} else if (attributes.put(a.mappedBy(), a.attributeName()) != null) {
throw new DynamoDBMappingException("must not duplicate mappedBy=" + a.mappedBy());
}
}
return attributes;
}
return Collections.emptyMap();
}
/**
* {@inheritDoc}
*/
@Override
public Class targetType() {
return defaults.targetType();
}
/**
* {@inheritDoc}
*/
@Override
public final String attributeName() {
if (hashKey() != null && !hashKey().attributeName().isEmpty()) {
return hashKey().attributeName();
} else if (indexHashKey() != null && !indexHashKey().attributeName().isEmpty()) {
return indexHashKey().attributeName();
} else if (rangeKey() != null && !rangeKey().attributeName().isEmpty()) {
return rangeKey().attributeName();
} else if (indexRangeKey() != null && !indexRangeKey().attributeName().isEmpty()) {
return indexRangeKey().attributeName();
} else if (attribute() != null && !attribute().attributeName().isEmpty()) {
return attribute().attributeName();
} else if (version() != null && !version().attributeName().isEmpty()) {
return version().attributeName();
} else {
return defaults.attributeName();
}
}
/**
* {@inheritDoc}
*/
@Override
public final KeyType keyType() {
return hashKey() != null ? HASH : rangeKey() != null ? RANGE : defaults.keyType();
}
/**
* {@inheritDoc}
*/
@Override
public final List globalSecondaryIndexNames(final KeyType keyType) {
if (keyType == HASH && indexHashKey() != null) {
if (!indexHashKey().globalSecondaryIndexName().isEmpty()) {
if (indexHashKey().globalSecondaryIndexNames().length > 0) {
throw new DynamoDBMappingException("must not specify both HASH GSI name/names");
}
return Collections.singletonList(indexHashKey().globalSecondaryIndexName());
} else if (indexHashKey().globalSecondaryIndexNames().length > 0) {
return Collections.unmodifiableList(Arrays.asList(indexHashKey().globalSecondaryIndexNames()));
} else {
throw new DynamoDBMappingException("must specify one of HASH GSI name/names");
}
} else if (keyType == RANGE && indexRangeKey() != null) {
if (!indexRangeKey().globalSecondaryIndexName().isEmpty()) {
if (indexRangeKey().globalSecondaryIndexNames().length > 0) {
throw new DynamoDBMappingException("must not specify both RANGE GSI name/names");
}
return Collections.singletonList(indexRangeKey().globalSecondaryIndexName());
} else if (indexRangeKey().globalSecondaryIndexNames().length > 0) {
return Collections.unmodifiableList(Arrays.asList(indexRangeKey().globalSecondaryIndexNames()));
} else if (localSecondaryIndexNames().isEmpty()) {
throw new DynamoDBMappingException("must specify RANGE GSI and/or LSI name/names");
}
}
return defaults.globalSecondaryIndexNames(keyType);
}
/**
* {@inheritDoc}
*/
@Override
public final List localSecondaryIndexNames() {
if (indexRangeKey() != null) {
if (!indexRangeKey().localSecondaryIndexName().isEmpty()) {
if (indexRangeKey().localSecondaryIndexNames().length > 0) {
throw new DynamoDBMappingException("must not specify both LSI name/names");
}
return Collections.singletonList(indexRangeKey().localSecondaryIndexName());
} else if (indexRangeKey().localSecondaryIndexNames().length > 0) {
return Collections.unmodifiableList(Arrays.asList(indexRangeKey().localSecondaryIndexNames()));
}
}
return defaults.localSecondaryIndexNames();
}
/**
* {@inheritDoc}
*/
@Override
public final DynamoDBAutoGenerator autoGenerator() {
if (autoGenerated() != null) {
return DynamoDBAutoGenerated.Generators.of(targetType(), autoGenerated());
}
return defaults.autoGenerator();
}
/**
* Gets the custom type-converter.
* @return The custom type-converter.
*/
final DynamoDBTypeConverter typeConverter() {
if (typeConverted() != null) {
return DynamoDBTypeConverted.Converters.of(targetType(), typeConverted());
}
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy