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

info.archinnov.achilles.composite.ThriftCompositeFactory Maven / Gradle / Ivy

package info.archinnov.achilles.composite;

import static info.archinnov.achilles.serializer.ThriftSerializerUtils.*;
import static me.prettyprint.hector.api.beans.AbstractComposite.ComponentEquality.EQUAL;
import info.archinnov.achilles.entity.metadata.MultiKeyProperties;
import info.archinnov.achilles.entity.metadata.PropertyMeta;
import info.archinnov.achilles.helper.ThriftCompositeHelper;
import info.archinnov.achilles.proxy.AchillesMethodInvoker;
import info.archinnov.achilles.type.WideMap;
import info.archinnov.achilles.validation.Validator;

import java.util.ArrayList;
import java.util.List;

import me.prettyprint.cassandra.serializers.SerializerTypeInferer;
import me.prettyprint.hector.api.Serializer;
import me.prettyprint.hector.api.beans.AbstractComposite.ComponentEquality;
import me.prettyprint.hector.api.beans.Composite;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ThriftCompositeFactory
 * 
 * @author DuyHai DOAN
 * 
 */
public class ThriftCompositeFactory
{
	private static final Logger log = LoggerFactory.getLogger(ThriftCompositeFactory.class);

	private ThriftCompositeHelper helper = new ThriftCompositeHelper();
	private AchillesMethodInvoker invoker = new AchillesMethodInvoker();

	public  Composite createBaseComposite(PropertyMeta propertyMeta, T keyValue)
	{
		log.trace("Creating base composite for propertyMeta {}", propertyMeta.getPropertyName());

		Composite composite = new Composite();
		String propertyName = propertyMeta.getPropertyName();

		if (propertyMeta.isSingleKey())
		{
			log.trace("PropertyMeta {} is single key", propertyMeta.getPropertyName());
			Validator.validateNotNull(keyValue, "The values for the for the key of WideMap '"
					+ propertyName + "' should not be null");

			Serializer keySerializer = SerializerTypeInferer.getSerializer(propertyMeta
					.getKeyClass());
			composite.setComponent(0, keyValue, keySerializer, keySerializer
					.getComparatorType()
					.getTypeName());
		}
		else
		{
			log.trace("PropertyMeta {} is multi key", propertyMeta.getPropertyName());
			MultiKeyProperties multiKeyProperties = propertyMeta.getMultiKeyProperties();
			List> componentSerializers = getComponentSerializers(multiKeyProperties);
			List keyValues = invoker.determineMultiKeyValues(keyValue,
					multiKeyProperties.getComponentGetters());
			int srzCount = componentSerializers.size();
			int valueCount = keyValues.size();

			Validator.validateTrue(srzCount == valueCount, "There should be " + srzCount
					+ " values for the key of WideMap '" + propertyName + "'");

			for (Object value : keyValues)
			{
				Validator.validateNotNull(value, "The values for the for the key of WideMap '"
						+ propertyName + "' should not be null");
			}

			for (int i = 0; i < srzCount; i++)
			{
				Serializer srz = componentSerializers.get(i);
				composite.setComponent(i, keyValues.get(i), srz, srz
						.getComparatorType()
						.getTypeName());
			}
		}
		return composite;
	}

	public  Composite createForQuery(PropertyMeta propertyMeta, T keyValue,
			ComponentEquality equality)
	{
		log.trace("Creating query composite for propertyMeta {}", propertyMeta.getPropertyName());

		Composite composite = new Composite();
		String propertyName = propertyMeta.getPropertyName();

		if (propertyMeta.isSingleKey())
		{
			log.trace("PropertyMeta {} is single key", propertyMeta.getPropertyName());

			if (keyValue == null)
			{
				composite = null;
			}
			else
			{
				composite.addComponent(0, keyValue, equality);
			}
		}
		else
		{
			log.trace("PropertyMeta {} is multi key", propertyMeta.getPropertyName());

			MultiKeyProperties multiKeyProperties = propertyMeta.getMultiKeyProperties();
			List> componentSerializers = getComponentSerializers(multiKeyProperties);

			List keyValues = invoker.determineMultiKeyValues(keyValue,
					multiKeyProperties.getComponentGetters());
			int srzCount = componentSerializers.size();
			int valueCount = keyValues.size();

			Validator.validateTrue(srzCount >= valueCount, "There should be at most" + srzCount
					+ " values for the key of WideMap '" + propertyName + "'");

			int lastNotNullIndex = helper
					.findLastNonNullIndexForComponents(propertyName, keyValues);

			for (int i = 0; i <= lastNotNullIndex; i++)
			{
				Serializer srz = componentSerializers.get(i);
				Object value = keyValues.get(i);
				if (i < lastNotNullIndex)
				{
					composite.setComponent(i, value, srz, srz.getComparatorType().getTypeName(),
							EQUAL);
				}
				else
				{
					composite.setComponent(i, value, srz, srz.getComparatorType().getTypeName(),
							equality);
				}
			}
		}
		return composite;
	}

	private List> getComponentSerializers(MultiKeyProperties multiKeyProperties)
	{
		List> componentSerializers = new ArrayList>();
		for (Class clazz : multiKeyProperties.getComponentClasses())
		{
			componentSerializers.add(SerializerTypeInferer. getSerializer(clazz));
		}
		return componentSerializers;
	}

	public  Composite[] createForQuery(PropertyMeta propertyMeta, K start, K end,
			WideMap.BoundingMode bounds, WideMap.OrderingMode ordering)
	{
		log
				.trace("Creating query composite for propertyMeta {} with start {}, end {}, bounding mode {} and orderging {}",
						propertyMeta.getPropertyName(), start, end, bounds.name(), ordering.name());

		Composite[] queryComp = new Composite[2];

		ComponentEquality[] equalities = helper.determineEquality(bounds, ordering);

		Composite startComp = createForQuery(propertyMeta, start, equalities[0]);
		Composite endComp = createForQuery(propertyMeta, end, equalities[1]);

		queryComp[0] = startComp;
		queryComp[1] = endComp;

		return queryComp;
	}

	public Composite createKeyForCounter(String fqcn, Object key, PropertyMeta idMeta)
	{
		log.trace("Creating composite counter row key for entity class {} and primary key {}",
				fqcn, key);

		Composite comp = new Composite();
		comp.setComponent(0, fqcn, STRING_SRZ);
		comp.setComponent(1, idMeta.writeValueToString(key), STRING_SRZ);
		return comp;
	}

	public  Composite createBaseForGet(PropertyMeta propertyMeta)
	{
		log
				.trace("Creating base composite for propertyMeta {} get",
						propertyMeta.getPropertyName());

		Composite composite = new Composite();
		composite.addComponent(0, propertyMeta.type().flag(), ComponentEquality.EQUAL);
		composite.addComponent(1, propertyMeta.getPropertyName(), ComponentEquality.EQUAL);
		composite.addComponent(2, 0, ComponentEquality.EQUAL);
		return composite;
	}

	public  Composite createBaseForCounterGet(PropertyMeta propertyMeta)
	{
		log
				.trace("Creating base composite for propertyMeta {} get",
						propertyMeta.getPropertyName());

		Composite composite = new Composite();
		composite.addComponent(0, propertyMeta.getPropertyName(), ComponentEquality.EQUAL);
		return composite;
	}

	public  Composite createBaseForQuery(PropertyMeta propertyMeta,
			ComponentEquality equality)
	{
		log.trace("Creating base composite for propertyMeta {} query and equality {}",
				propertyMeta.getPropertyName(), equality.name());

		Composite composite = new Composite();
		composite.addComponent(0, propertyMeta.type().flag(), ComponentEquality.EQUAL);
		composite.addComponent(1, propertyMeta.getPropertyName(), equality);
		return composite;
	}

	public  Composite createForBatchInsertSingleValue(PropertyMeta propertyMeta)
	{
		log.trace("Creating base composite for propertyMeta {} for single value batch insert",
				propertyMeta.getPropertyName());

		Composite composite = new Composite();
		composite.setComponent(0, propertyMeta.type().flag(), BYTE_SRZ, BYTE_SRZ
				.getComparatorType()
				.getTypeName());
		composite.setComponent(1, propertyMeta.getPropertyName(), STRING_SRZ, STRING_SRZ
				.getComparatorType()
				.getTypeName());
		composite.setComponent(2, 0, INT_SRZ, INT_SRZ.getComparatorType().getTypeName());
		return composite;
	}

	public  Composite createForBatchInsertSingleCounter(PropertyMeta propertyMeta)
	{
		log
				.trace("Creating base composite for propertyMeta {} for single counter value batch insert",
						propertyMeta.getPropertyName());

		Composite composite = new Composite();
		composite.setComponent(0, propertyMeta.getPropertyName(), STRING_SRZ, STRING_SRZ
				.getComparatorType()
				.getTypeName());
		return composite;
	}

	public  Composite createForBatchInsertMultiValue(PropertyMeta propertyMeta,
			int hashOrPosition)
	{
		log
				.trace("Creating base composite for propertyMeta {} for multi value batch insert with hash or position {}",
						propertyMeta.getPropertyName(), hashOrPosition);

		Composite composite = new Composite();
		composite.setComponent(0, propertyMeta.type().flag(), BYTE_SRZ, BYTE_SRZ
				.getComparatorType()
				.getTypeName());
		composite.setComponent(1, propertyMeta.getPropertyName(), STRING_SRZ, STRING_SRZ
				.getComparatorType()
				.getTypeName());
		composite.setComponent(2, hashOrPosition, INT_SRZ, INT_SRZ
				.getComparatorType()
				.getTypeName());
		return composite;
	}

}