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

com.datastax.driver.mapping.AnnotationChecks Maven / Gradle / Ivy

There is a newer version: 3.11.5
Show newest version
/*
 *      Copyright (C) 2012-2015 DataStax Inc.
 *
 *   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://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License 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.datastax.driver.mapping;

import com.datastax.driver.mapping.annotations.*;

import java.lang.annotation.Annotation;
import java.util.*;

/**
 * Various checks on mapping annotations.
 */
class AnnotationChecks {

    // The package containing the mapping annotations
    private static final Package MAPPING_PACKAGE = Table.class.getPackage();

    /**
     * Checks that a class is decorated with the given annotation, and return the annotation instance.
     * Also validates that no other mapping annotation is present.
     */
    static  T getTypeAnnotation(Class annotation, Class annotatedClass) {
        T instance = annotatedClass.getAnnotation(annotation);
        if (instance == null)
            throw new IllegalArgumentException(String.format("@%s annotation was not found on %s",
                    annotation.getSimpleName(), annotatedClass));

        // Check that no other mapping annotations are present
        validateAnnotations(annotatedClass, annotation);

        return instance;
    }

    private static void validateAnnotations(Class clazz, Class allowed) {
        Collection classAnnotations = new HashSet();
        Collections.addAll(classAnnotations, clazz.getAnnotations());
        Class invalid = validateAnnotations(classAnnotations, Collections.singleton(allowed));
        if (invalid != null)
            throw new IllegalArgumentException(String.format("Cannot have both @%s and @%s on %s",
                    allowed.getSimpleName(), invalid.getSimpleName(),
                    clazz));
    }

    /**
     * Checks that a field is only annotated with the given mapping annotations, and that its "frozen" annotations are valid.
     */
    static void validateAnnotations(String propertyName, Map, Annotation> annotations, Collection> allowed) {
        Class invalid = validateAnnotations(annotations.values(), allowed);
        if (invalid != null) {
            throw new IllegalArgumentException(String.format("Annotation @%s is not allowed on property '%s'",
                    invalid.getSimpleName(),
                    propertyName));
        }
        checkValidPrimaryKey(propertyName, annotations);
        checkValidComputed(propertyName, annotations);
    }

    // Returns the offending annotation if there is one
    private static Class validateAnnotations(Collection annotations, Collection> allowed) {
        for (Annotation annotation : annotations) {
            Class actual = annotation.annotationType();
            if (actual.getPackage().equals(MAPPING_PACKAGE) && !allowed.contains(actual))
                return actual;
        }
        return null;
    }

    private static void checkValidPrimaryKey(String propertyName, Map, Annotation> annotations) {
        if (annotations.containsKey(PartitionKey.class) && annotations.containsKey(ClusteringColumn.class))
            throw new IllegalArgumentException(String.format("Property '%s' cannot be annotated with both @PartitionKey and @ClusteringColumn", propertyName));
    }

    private static void checkValidComputed(String propertyName, Map, Annotation> annotations) {
        if (annotations.containsKey(Computed.class)) {
            Computed computed = (Computed) annotations.get(Computed.class);
            if (computed.value().isEmpty()) {
                throw new IllegalArgumentException(String.format("Property '%s': attribute 'value' of annotation @Computed is mandatory for computed properties", propertyName));
            }
            if (annotations.containsKey(Column.class)) {
                throw new IllegalArgumentException(String.format("Property '%s' cannot be annotated with both @Column and @Computed", propertyName));
            }
        }
    }

    static void validateOrder(List> properties, String annotation) {
        for (int i = 0; i < properties.size(); i++) {
            AliasedMappedProperty property = properties.get(i);
            int pos = property.mappedProperty.getPosition();
            if (pos != i)
                throw new IllegalArgumentException(String.format("Invalid ordering value %d for annotation %s of property '%s', was expecting %d",
                        pos, annotation, property.mappedProperty.getPropertyName(), i));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy