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

com.netflix.astyanax.entitystore.CompositeColumnMapper Maven / Gradle / Ivy

package com.netflix.astyanax.entitystore;

import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.netflix.astyanax.ColumnListMutation;

class CompositeColumnMapper extends AbstractColumnMapper {
	private final Class clazz;
	private final Map columnList;
	private final List nonNullableFields;
	
	CompositeColumnMapper(final Field field) {
	    super(field);
		this.clazz = field.getType();
		// clazz should be annotated with @Entity
		Entity entityAnnotation = clazz.getAnnotation(Entity.class);
		if(entityAnnotation == null)
			throw new IllegalArgumentException("class is NOT annotated with @javax.persistence.Entity: " + clazz.getName());

		columnList = Maps.newHashMapWithExpectedSize(clazz.getDeclaredFields().length);
		nonNullableFields = Lists.newArrayList();
		
		Set usedColumnNames = Sets.newHashSet();
		for (Field childField : clazz.getDeclaredFields()) {
			// extract @Column annotated fields
			Column annotation = childField.getAnnotation(Column.class);
			if ((annotation != null)) {
				childField.setAccessible(true);
				ColumnMapper columnMapper = null;
				Entity compositeAnnotation = childField.getType().getAnnotation(Entity.class);
				if(compositeAnnotation == null) {
					columnMapper = new LeafColumnMapper(childField);
				} else {
					columnMapper = new CompositeColumnMapper(childField);
				}
				Preconditions.checkArgument(!usedColumnNames.contains(columnMapper.getColumnName().toLowerCase()), 
						String.format("duplicate case-insensitive column name: %s", columnMapper.getColumnName()));
				columnList.put(columnMapper.getColumnName(), columnMapper);
				usedColumnNames.add(columnMapper.getColumnName().toLowerCase());
				
	            if (!annotation.nullable()) {
	                nonNullableFields.add(columnMapper);
	            }
			}
		}
	}

	@Override
	public String toString() {
		return String.format("CompositeColumnMapper(%s)", clazz);
	}

	@Override
	public String getColumnName() {
		return columnName;
	}

	@Override
	public boolean fillMutationBatch(Object entity, ColumnListMutation clm, String prefix) throws Exception {
		Object childEntity = field.get(entity);
		if(childEntity == null) {
			if(columnAnnotation.nullable()) {
				return false; // skip. cannot write null column
			} else {
				throw new IllegalArgumentException("cannot write non-nullable column with null value: " + columnName);
			}
		}
		
		prefix += getColumnName() + ".";
		boolean hasNonNullChildField = false;
		for (ColumnMapper mapper : columnList.values()) {
			boolean childFilled = mapper.fillMutationBatch(childEntity, clm, prefix);
			if(childFilled)
				hasNonNullChildField = true;
		}
		return hasNonNullChildField;
	}

    @Override
    public boolean setField(Object entity, Iterator name, com.netflix.astyanax.model.Column column) throws Exception {
        Object childEntity = field.get(entity);
        if (childEntity == null) {
            childEntity = clazz.newInstance();
            field.set(entity, childEntity);
        }
        
        ColumnMapper mapper = this.columnList.get(name.next());
        if (mapper == null)
            return false;
        
        return mapper.setField(childEntity, name, column);
    }

    @Override
    public void validate(Object entity) throws Exception {
        Object objForThisField = field.get(entity);
        if (objForThisField == null) {
            if (!columnAnnotation.nullable())
                throw new IllegalArgumentException("cannot find non-nullable column: " + columnName);
        }
        else {
            for (ColumnMapper childField : this.nonNullableFields) {
                childField.validate(objForThisField);
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy