info.archinnov.achilles.helper.EntityIntrospector.java Source code

Java tutorial

Introduction

Here is the source code for info.archinnov.achilles.helper.EntityIntrospector.java

Source

/**
 *
 * Copyright (C) 2012-2013 DuyHai DOAN
 *
 * 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 info.archinnov.achilles.helper;

import static info.archinnov.achilles.helper.LoggerHelper.fieldToStringFn;
import info.archinnov.achilles.annotations.Consistency;
import info.archinnov.achilles.annotations.Entity;
import info.archinnov.achilles.configuration.ConfigurationParameters;
import info.archinnov.achilles.consistency.AchillesConsistencyLevelPolicy;
import info.archinnov.achilles.entity.parsing.PropertyFilter;
import info.archinnov.achilles.exception.AchillesBeanMappingException;
import info.archinnov.achilles.table.TableNameNormalizer;
import info.archinnov.achilles.type.ConsistencyLevel;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.cassandra.utils.Pair;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

public class EntityIntrospector {
    private static final Logger log = LoggerFactory.getLogger(EntityIntrospector.class);

    private PropertyFilter filter = new PropertyFilter();

    protected String[] deriveGetterName(Field field) {
        log.debug("Derive getter name for field {} from class {}", field.getName(),
                field.getDeclaringClass().getCanonicalName());

        String camelCase = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);

        String[] getters;

        if (StringUtils.equals(field.getType().toString(), "boolean")) {
            getters = new String[] { "is" + camelCase, "get" + camelCase };
        } else {
            getters = new String[] { "get" + camelCase };
        }
        if (log.isTraceEnabled()) {
            log.trace("Derived getters : {}", StringUtils.join(getters, ","));
        }
        return getters;
    }

    protected String deriveSetterName(Field field) {
        log.debug("Derive setter name for field {} from class {}", field.getName(),
                field.getDeclaringClass().getCanonicalName());

        String fieldName = field.getName();
        String setter = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        log.trace("Derived setter : {}", setter);
        return setter;
    }

    public Method findGetter(Class<?> beanClass, Field field) {
        log.debug("Find getter for field {} in class {}", field.getName(), beanClass.getCanonicalName());

        Method getterMethod = null;
        String fieldName = field.getName();
        String[] getters = this.deriveGetterName(field);

        for (String getter : getters) {
            try {
                getterMethod = beanClass.getMethod(getter);
                if (getterMethod.getReturnType() != field.getType()) {
                    throw new AchillesBeanMappingException("The getter for field '" + fieldName + "' of type '"
                            + field.getDeclaringClass().getCanonicalName() + "' does not return correct type");
                }
            } catch (NoSuchMethodException e) {
                // Do nothing here
            }
        }
        if (getterMethod == null) {
            throw new AchillesBeanMappingException("The getter for field '" + fieldName + "' of type '"
                    + field.getDeclaringClass().getCanonicalName() + "' does not exist");
        }

        log.trace("Derived getter method : {}", getterMethod.getName());
        return getterMethod;
    }

    public Method findSetter(Class<?> beanClass, Field field) {
        log.debug("Find setter for field {} in class {}", field.getName(), beanClass.getCanonicalName());

        String fieldName = field.getName();

        try {
            String setter = this.deriveSetterName(field);
            Method setterMethod = beanClass.getMethod(setter, field.getType());

            if (!setterMethod.getReturnType().toString().equals("void")) {
                throw new AchillesBeanMappingException("The setter for field '" + fieldName + "' of type '"
                        + field.getDeclaringClass().getCanonicalName()
                        + "' does not return correct type or does not have the correct parameter");
            }

            log.trace("Derived setter method : {}", setterMethod.getName());
            return setterMethod;

        } catch (NoSuchMethodException e) {
            throw new AchillesBeanMappingException("The setter for field '" + fieldName + "' of type '"
                    + field.getDeclaringClass().getCanonicalName() + "' does not exist or is incorrect");
        }
    }

    public Method[] findAccessors(Class<?> beanClass, Field field) {
        log.debug("Find accessors for field {} in class {}", field.getName(), beanClass.getCanonicalName());

        Method[] accessors = new Method[2];

        accessors[0] = findGetter(beanClass, field);
        accessors[1] = findSetter(beanClass, field);

        return accessors;
    }

    public String inferColumnFamilyName(Class<?> entity, String canonicalName) {
        String columnFamilyName = null;
        Entity annotation = entity.getAnnotation(Entity.class);
        if (annotation != null) {
            if (StringUtils.isNotBlank(annotation.table())) {
                columnFamilyName = annotation.table();
            }
        }

        if (!StringUtils.isBlank(columnFamilyName)) {
            columnFamilyName = TableNameNormalizer.normalizerAndValidateColumnFamilyName(columnFamilyName);
        } else {
            columnFamilyName = TableNameNormalizer.normalizerAndValidateColumnFamilyName(canonicalName);
        }

        log.debug("Inferred columnFamilyName for entity {} : {}", canonicalName, columnFamilyName);
        return columnFamilyName;
    }

    public <T> Pair<ConsistencyLevel, ConsistencyLevel> findConsistencyLevels(Class<T> entity,
            AchillesConsistencyLevelPolicy policy) {
        log.debug("Find consistency levels for entity class {}", entity.getCanonicalName());

        ConsistencyLevel defaultGlobalRead = getDefaultGlobalReadConsistency(policy);
        ConsistencyLevel defaultGlobalWrite = getDefaultGlobalWriteConsistency(policy);

        Consistency clevel = entity.getAnnotation(Consistency.class);

        if (clevel != null) {
            defaultGlobalRead = clevel.read();
            defaultGlobalWrite = clevel.write();
        }

        log.trace("Found consistency levels : {}/{}", defaultGlobalRead, defaultGlobalWrite);

        return Pair.create(defaultGlobalRead, defaultGlobalWrite);
    }

    public List<Field> getInheritedPrivateFields(Class<?> type) {
        log.debug("Find inherited private fields from hierarchy for entity class {}", type.getCanonicalName());

        List<Field> fields = new ArrayList<Field>();

        Class<?> i = type;
        while (i != null && i != Object.class) {
            for (Field declaredField : i.getDeclaredFields()) {
                if (filter.matches(declaredField)) {
                    fields.add(declaredField);
                }
            }
            i = i.getSuperclass();
        }
        if (log.isTraceEnabled()) {
            log.trace("Found inherited private fields : {}", Lists.transform(fields, fieldToStringFn));
        }
        return fields;
    }

    public Field getInheritedPrivateFields(Class<?> type, Class<?> annotation) {
        log.debug("Find private field from hierarchy with annotation {} for entity class {}",
                annotation.getCanonicalName(), type.getCanonicalName());

        Class<?> i = type;
        while (i != null && i != Object.class) {
            for (Field declaredField : i.getDeclaredFields()) {
                if (filter.matches(declaredField, annotation)) {
                    log.trace("Found inherited private field : {}", declaredField);
                    return declaredField;
                }
            }
            i = i.getSuperclass();
        }
        return null;
    }

    public Field getInheritedPrivateFields(Class<?> type, Class<?> annotation, String name) {
        log.debug("Find private field with name {} having annotation {} from hierarchy for entity class {}", name,
                annotation.getCanonicalName(), type.getCanonicalName());

        Class<?> i = type;
        while (i != null && i != Object.class) {
            for (Field declaredField : i.getDeclaredFields()) {
                if (filter.matches(declaredField, annotation, name)) {
                    log.trace("Found inherited private field : {}", declaredField);
                    return declaredField;
                }
            }
            i = i.getSuperclass();
        }
        return null;
    }

    public ConsistencyLevel getDefaultGlobalReadConsistency(AchillesConsistencyLevelPolicy policy) {
        return policy.getDefaultGlobalReadConsistencyLevel() != null ? policy.getDefaultGlobalReadConsistencyLevel()
                : ConfigurationParameters.DEFAULT_LEVEL;
    }

    public ConsistencyLevel getDefaultGlobalWriteConsistency(AchillesConsistencyLevelPolicy policy) {
        return policy.getDefaultGlobalWriteConsistencyLevel() != null
                ? policy.getDefaultGlobalWriteConsistencyLevel()
                : ConfigurationParameters.DEFAULT_LEVEL;
    }
}