com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAnnotationRegistry Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk-osgi Show documentation
Show all versions of aws-java-sdk-osgi Show documentation
The AWS SDK for Java with support for OSGi. The AWS SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).
/*
* Copyright 2011-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 java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.amazonaws.annotation.SdkInternalApi;
/**
* Map of DynamoDB annotations.
*/
@SdkInternalApi
final class DynamoDBAnnotationRegistry {
/**
* The logging utility.
*/
private static final Log log = LogFactory.getLog(DynamoDBAnnotationRegistry.class);
/**
* Gets all the DynamoDB annotations for a given class.
* @param clazz The class.
* @return The map of annotation type to annotation instance.
*/
final AnnotationMap annotationsOf(final Class> clazz) {
final AnnotationMap annotations = new AnnotationMap();
annotations.putAll(clazz.getAnnotations());
annotations.removeInvalidAnnotations();
return annotations;
}
/**
* Gets all the DynamoDB annotations; method annotations override the field level annotations.
* @param method The method.
* @param field The field.
* @return The map of annotation type to annotation instance.
*/
final AnnotationMap annotationsOf(final Method method, final Field field) {
final AnnotationMap annotations = new AnnotationMap();
if (field != null) {
annotations.putAll(field.getAnnotations());
}
annotations.putAll(method.getAnnotations());
annotations.removeInvalidAnnotations();
return annotations;
}
/**
* Map of annotation type to annotation instance.
*/
static final class AnnotationMap {
/**
* Map of annotation type to annotation instance.
*/
private final Map,Annotation> annotations;
/**
* Constructs an instance of {@code AnnotationMap}.
*/
private AnnotationMap() {
this.annotations = new HashMap,Annotation>();
}
/**
* Gets the annotations.
* @return The annotations.
*/
private final Map,Annotation> getAnnotations() {
return this.annotations;
}
/**
* Put all the DynamoDB annotations.
* @param annotations The array of annotations.
*/
private final void putAll(final Annotation[] annotations) {
if (annotations != null && annotations.length > 0) {
for (final Annotation annotation : annotations) {
if (annotation != null && annotation.annotationType().isAnnotationPresent(DynamoDB.class)) {
getAnnotations().put(annotation.annotationType(), annotation);
}
}
}
}
/**
* Removes any conflicting annotations.
* Note, we may consider throwing exceptions here instead in the future.
*/
private final void removeInvalidAnnotations() {
// Note, the fact this code exists indicates more thought should be placed
// into how we are exposing features as annotations. It may not be clear
// which annotations are compatible to our integrators without extensive
// documentation. The code should stand alone, or try it's best.
if (isAutoGeneratedKey()) {
if (!isHashKey() && !isRangeKey() && !isIndexHashKey() && !isIndexRangeKey()) {
log.warn(annotationOf(DynamoDBAutoGeneratedKey.class) + " is only compatible with keys");
getAnnotations().remove(DynamoDBAutoGeneratedKey.class);
} else {
if (isVersion()) {
log.warn(annotationOf(DynamoDBVersionAttribute.class) + " is not compatible with " + annotationOf(DynamoDBAutoGeneratedKey.class));
getAnnotations().remove(DynamoDBVersionAttribute.class);
}
if (isAutoGeneratedTimestamp()) {
throw new DynamoDBMappingException(annotationOf(DynamoDBAutoGeneratedTimestamp.class) +
" is not compatible with " + annotationOf(DynamoDBAutoGeneratedKey.class));
}
}
} else if (isVersion()) {
if (isAutoGeneratedTimestamp()) {
throw new DynamoDBMappingException(annotationOf(DynamoDBAutoGeneratedTimestamp.class) +
" is not compatible with " + annotationOf(DynamoDBVersionAttribute.class));
}
} else if (isAutoGeneratedTimestamp()) {
if (isHashKey() || isRangeKey()) {
throw new DynamoDBMappingException(annotationOf(DynamoDBAutoGeneratedTimestamp.class) +
" is not compatible with primary keys");
}
}
}
/**
* Gets the annotation of the specified type.
* @param clazz The annotation type.
* @return The annotation or null if not applicable.
*/
private final T annotationOf(final Class clazz) {
return (T)getAnnotations().get(clazz);
}
/**
* Determines if the {@code DynamoDBAttribute} is present.
* @return True if present, false otherwise.
*/
final boolean isAttribute() {
return getAnnotations().containsKey(DynamoDBAttribute.class);
}
/**
* Determines if the {@code DynamoDBAutoGeneratedKey} is present.
* @return True if present, false otherwise.
*/
final boolean isAutoGeneratedKey() {
return getAnnotations().containsKey(DynamoDBAutoGeneratedKey.class);
}
/**
* Determines if the {@code DynamoDBAutoGeneratedTimestamp} is present.
* @return True if present, false otherwise.
*/
final boolean isAutoGeneratedTimestamp() {
return getAnnotations().containsKey(DynamoDBAutoGeneratedTimestamp.class);
}
/**
* Determines if the {@code DynamoDBDocument} is present.
* @return True if present, false otherwise.
*/
final boolean isDocument() {
return getAnnotations().containsKey(DynamoDBDocument.class);
}
/**
* Determines if the {@code DynamoDBHashKey} is present.
* @return True if present, false otherwise.
*/
final boolean isHashKey() {
return getAnnotations().containsKey(DynamoDBHashKey.class);
}
/**
* Determines if the {@code DynamoDBIgnore} is present.
* @return True if present, false otherwise.
*/
final boolean isIgnore() {
return getAnnotations().containsKey(DynamoDBIgnore.class);
}
/**
* Determines if the {@code DynamoDBIndexHashKey} is present.
* @return True if present, false otherwise.
*/
final boolean isIndexHashKey() {
return getAnnotations().containsKey(DynamoDBIndexHashKey.class);
}
/**
* Determines if the {@code DynamoDBIndexRangeKey} is present.
* @return True if present, false otherwise.
*/
final boolean isIndexRangeKey() {
return getAnnotations().containsKey(DynamoDBIndexRangeKey.class);
}
/**
* Determines if the {@code DynamoDBMarshalling} is present.
* @return True if present, false otherwise.
*/
final boolean isMarshalling() {
return getAnnotations().containsKey(DynamoDBMarshalling.class);
}
/**
* Determines if the {@code DynamoDBNativeBoolean} is present.
* @return True if present, false otherwise.
*/
final boolean isNativeBoolean() {
return getAnnotations().containsKey(DynamoDBNativeBoolean.class);
}
/**
* Determines if the {@code DynamoDBRangeKey} is present.
* @return True if present, false otherwise.
*/
final boolean isRangeKey() {
return getAnnotations().containsKey(DynamoDBRangeKey.class);
}
/**
* Determines if the {@code DynamoDBTable} is present.
* @return True if present, false otherwise.
*/
final boolean isTable() {
return getAnnotations().containsKey(DynamoDBTable.class);
}
/**
* Determines if the {@code DynamoDBVersionAttribute} is present.
* @return True if present, false otherwise.
*/
final boolean isVersion() {
return getAnnotations().containsKey(DynamoDBVersionAttribute.class);
}
/**
* Gets the attribute name defaulting if required.
* @return The attribute name.
*/
final String getAttributeName() {
if (isHashKey()) {
final DynamoDBHashKey annotation = annotationOf(DynamoDBHashKey.class);
if (!annotation.attributeName().isEmpty()) {
return annotation.attributeName();
}
}
if (isIndexHashKey()) {
final DynamoDBIndexHashKey annotation = annotationOf(DynamoDBIndexHashKey.class);
if (!annotation.attributeName().isEmpty()) {
return annotation.attributeName();
}
}
if (isRangeKey()) {
final DynamoDBRangeKey annotation = annotationOf(DynamoDBRangeKey.class);
if (!annotation.attributeName().isEmpty()) {
return annotation.attributeName();
}
}
if (isIndexRangeKey()) {
final DynamoDBIndexRangeKey annotation = annotationOf(DynamoDBIndexRangeKey.class);
if (!annotation.attributeName().isEmpty()) {
return annotation.attributeName();
}
}
if (isAttribute()) {
final DynamoDBAttribute annotation = annotationOf(DynamoDBAttribute.class);
if (!annotation.attributeName().isEmpty()) {
return annotation.attributeName();
}
}
if (isVersion()) {
final DynamoDBVersionAttribute annotation = annotationOf(DynamoDBVersionAttribute.class);
if (!annotation.attributeName().isEmpty()) {
return annotation.attributeName();
}
}
return null;
}
/**
* Gets the global secondary index names if applicable.
* @return The names.
*/
final Collection getGlobalSecondaryIndexNamesOfIndexHashKey() {
final DynamoDBIndexHashKey annotation = annotationOf(DynamoDBIndexHashKey.class);
if (annotation == null) {
return Collections.emptySet();
}
return resolveIndexNames(annotation, annotation.globalSecondaryIndexName(), annotation.globalSecondaryIndexNames());
}
/**
* Gets the global secondary index names if applicable.
* @return The names.
*/
final Collection getGlobalSecondaryIndexNamesOfIndexRangeKey() {
final DynamoDBIndexRangeKey annotation = annotationOf(DynamoDBIndexRangeKey.class);
if (annotation == null) {
return Collections.emptySet();
}
return resolveIndexNames(annotation, annotation.globalSecondaryIndexName(), annotation.globalSecondaryIndexNames());
}
/**
* Gets the local secondary index names if applicable.
* @return The names.
*/
final Collection getLocalSecondaryIndexNamesOfIndexRangeKey() {
final DynamoDBIndexRangeKey annotation = annotationOf(DynamoDBIndexRangeKey.class);
if (annotation == null) {
return Collections.emptySet();
}
return resolveIndexNames(annotation, annotation.localSecondaryIndexName(), annotation.localSecondaryIndexNames());
}
/**
* Gets the auto-generate strategy.
* @return The auto-generate strategy, null if not specified.
*/
final DynamoDBAutoGenerateStrategy getAutoGenerateStrategy() {
final DynamoDBAutoGeneratedTimestamp annotation = annotationOf(DynamoDBAutoGeneratedTimestamp.class);
if (annotation == null) {
return null;
}
return annotation.strategy();
}
/**
* Gets the marshaller class.
* @return The marshaller class, null if not specified.
*/
final Class extends DynamoDBMarshaller>> getMarshallerClass() {
final DynamoDBMarshalling annotation = annotationOf(DynamoDBMarshalling.class);
if (annotation == null) {
return null;
}
return annotation.marshallerClass();
}
/**
* Gets the table name.
* @return The table name, null if not specified.
*/
final String getTableName() {
final DynamoDBTable annotation = annotationOf(DynamoDBTable.class);
if (annotation == null) {
return null;
}
return annotation.tableName();
}
/**
* Resolves between which name/names to use.
* @param annotation The annotation.
* @param name The singular name.
* @param names The multiple names.
* @return The names, null if they could not be resolved.
*/
private static final Collection resolveIndexNames(final Annotation annotation, final String name, final String[] names) {
if (name == null || name.isEmpty()) {
if (names == null || names.length == 0) {
return Collections.emptySet();
} else {
return Arrays.asList(names);
}
} else if (names == null || names.length == 0) {
return Collections.singleton(name);
} else {
throw new DynamoDBMappingException(annotation + " contain both index name and names");
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy