package com.stratio.deep.cassandra.entity; import static com.stratio.deep.cassandra.util.AnnotationUtils.MAP_ABSTRACT_TYPE_CLASSNAME_TO_JAVA_TYPE; import static com.stratio.deep.commons.utils.AnnotationUtils.deepFieldName; import static com.stratio.deep.commons.utils.AnnotationUtils.getBeanFieldValue; import java.io.Serializable; import java.lang.reflect.Field; import java.nio.ByteBuffer; import org.apache.cassandra.db.marshal.AbstractType; import com.datastax.driver.core.DataType; import com.datastax.driver.core.ProtocolVersion; import com.stratio.deep.commons.annotations.DeepField; import com.stratio.deep.commons.entity.Cell; import com.stratio.deep.commons.entity.IDeepType; import com.stratio.deep.commons.exception.DeepGenericException; import com.stratio.deep.commons.exception.DeepInstantiationException; /** * Created by rcrespo on 23/06/14. */ @Deprecated public class CassandraCell extends Cell { private transient CellValidator cellValidator; private transient DataType dataType; /** * Factory method, creates a new CassandraCell from a basic Cell. The keys in the cell will be partitionsKey<br/> * * @param basicCell the cell object carrying the metadata and the value * @return an instance of a Cell object for the provided parameters. */ public static Cell create(Cell basicCell) { //TODO if basicCell instanceof CassandraCell => return basicCell; return new CassandraCell(basicCell); } /** * Factory method, creates a new CassandraCell from its value and metadata information<br/> * * @param metadata the cell object carrying the metadata for this new CassandraCell * @param cellValue the cell value, provided as a ByteBuffer. * @return an instance of a Cell object for the provided parameters. */ public static Cell create(Cell metadata, Object cellValue) { return new CassandraCell(metadata, cellValue); } /** * Factory method, creates a new CassandraCell from its value and metadata information<br/> * * @param metadata the cell object carrying the metadata for this new CassandraCell * @param cellValue the cell value, provided as a ByteBuffer. * @return an instance of a Cell object for the provided parameters. */ public static Cell create(Cell metadata, ByteBuffer cellValue) { return new CassandraCell(metadata, cellValue); } /** * Factory method, builds a new CassandraCell (isPartitionKey = false and isClusterKey = false). * The validator will be automatically calculated using the value object type. * * @param cellName the cell name * @param cellValue the cell value, provided as a ByteBuffer. * @return an instance of a Cell object for the provided parameters. */ public static Cell create(String cellName, Object cellValue) { return create(cellName, cellValue, Boolean.FALSE, Boolean.FALSE); } /** * Factory method, builds a new CassandraCell (isPartitionKey = false and isClusterKey = false) with value = null. * The validator will be automatically calculated using the value object type. * * @param cellName the cell name * @return an instance of a Cell object for the provided parameters. */ public static Cell create(String cellName) { return create(cellName, (Object) null, Boolean.FALSE, Boolean.FALSE); } /** * Factory method, creates a new CassandraCell.<br/> * * @param cellName the cell name * @param cellValue the cell value, provided as a ByteBuffer. * @param isPartitionKey true if this cell is part of the cassandra's partition key. * @param isClusterKey true if this cell is part of the cassandra's clustering key. * @return an instance of a Cell object for the provided parameters. */ public static Cell create(String cellName, Object cellValue, Boolean isPartitionKey, Boolean isClusterKey) { return new CassandraCell(cellName, cellValue, isPartitionKey, isClusterKey); } /** * Factory method, creates a new metadata Cell, i.e. a Cell without value. * * @param cellName the cell name * @param cellType the cell value type. * @param isPartitionKey true if this cell is part of the cassandra's partition key. * @param isClusterKey true if this cell is part of the cassandra's clustering key. * @return an instance of a Cell object for the provided parameters. */ public static Cell create(String cellName, DataType cellType, Boolean isPartitionKey, Boolean isClusterKey) { return new CassandraCell(cellName, cellType, isPartitionKey, isClusterKey); } /** * Constructs a Cell from a {@link com.stratio.deep.commons.annotations.DeepField} property. * * @param e instance of the testentity whose field is going to generate a Cell. * @param field field that will generate the Cell. * @param <E> a subclass of IDeepType. * @return an instance of a Cell object for the provided parameters. */ public static <E extends IDeepType> Cell create(E e, Field field) { return new CassandraCell(e, field); } /** * Calculates the Cassandra validator type given the value class type.<br/> * There's a shortcoming in the case of an UUID. At this level we are not able * to distinguish between an UUID or a TimeUUID because twe don't have the UUID value. * * @param obj the value class type. * @return the CellValidator object associated to this cell. */ public static CellValidator getValueType(DataType obj) { return CellValidator.cellValidator(obj); } /** * Calculates the Cassandra marshaller given the cell value. * * @param obj the cell value. * @return the CellValidator object associated to this cell. */ public static CellValidator getValueType(Object obj) { return CellValidator.cellValidator(obj); } /** * Private constructor. */ private CassandraCell(String cellName, Object cellValue, Boolean isPartitionKey, Boolean isClusterKey) { if (cellValue != null && !(cellValue instanceof Serializable)) { throw new DeepInstantiationException("provided cell value " + cellValue + " is not serializable"); } this.cellName = cellName; this.cellValue = cellValue; this.isKey = isPartitionKey; this.isClusterKey = isClusterKey; this.cellValidator = getValueType(cellValue); } /** * Private constructor. */ private CassandraCell(String cellName, DataType cellType, Boolean isPartitionKey, Boolean isClusterKey) { this.cellName = cellName; this.isClusterKey = isClusterKey; this.dataType = cellType; this.isKey = isPartitionKey; } public DataType getDataType() { return dataType; } /** * Private constructor. */ private CassandraCell(Cell metadata, ByteBuffer cellValue) { this.cellName = metadata.getCellName(); this.isClusterKey = ((CassandraCell) metadata).isClusterKey; this.isKey = ((CassandraCell) metadata).isPartitionKey(); this.cellValidator = ((CassandraCell) metadata).cellValidator; if (cellValue != null) { if (((CassandraCell) metadata).getDataType() != null) { this.cellValue = ((CassandraCell) metadata).getDataType().deserialize(cellValue, ProtocolVersion.V2); } else { this.cellValue = ((CassandraCell) metadata).marshaller().compose(cellValue); } } } /** * Private constructor. */ private CassandraCell(Cell metadata, Object cellValue) { if (!(cellValue instanceof Serializable)) { throw new DeepInstantiationException("provided cell value " + cellValue + " is not serializable"); } this.cellName = metadata.getCellName(); this.isClusterKey = ((CassandraCell) metadata).isClusterKey; this.isKey = ((CassandraCell) metadata).isPartitionKey(); this.cellValidator = ((CassandraCell) metadata).cellValidator; this.cellValue = cellValue; } /** * Private constructor.Cassandra cell from a basic cell. */ private CassandraCell(Cell cell) { this.cellName = cell.getCellName(); this.cellValue = cell.getCellValue(); this.isKey = cell.isKey(); this.cellValidator = getValueType(cellValue); } /** * Private constructor. */ private CassandraCell(IDeepType e, Field field) { DeepField annotation = field.getAnnotation(DeepField.class); this.cellName = deepFieldName(field); this.cellValue = getBeanFieldValue(e, field); this.isClusterKey = annotation.isPartOfClusterKey(); this.isKey = annotation.isPartOfPartitionKey(); this.cellValidator = CellValidator.cellValidator(field); } public CellValidator getCellValidator() { return cellValidator; } public Class getValueType() { Class valueType = MAP_ABSTRACT_TYPE_CLASSNAME_TO_JAVA_TYPE.get(cellValidator.getValidatorClassName()); if (valueType == null) { throw new DeepGenericException("Cannot find value type for marshaller " + cellValidator .getValidatorClassName()); } return valueType; } @SuppressWarnings("unchecked") public ByteBuffer getDecomposedCellValue() { if (this.cellValue != null) { return marshaller().decompose(this.cellValue); } else { /* if null we propagate an empty array, see CASSANDRA-5885 and CASSANDRA-6180 */ return ByteBuffer.wrap(new byte[0]); } } public Boolean isClusterKey() { return isClusterKey; } public Boolean isPartitionKey() { return isKey; } public Boolean isKey() { return isClusterKey || isKey; } public AbstractType marshaller() { if (cellValidator != null) { return cellValidator.getAbstractType(); } else { return null; } } public String marshallerClassName() { if (cellValidator != null) { return cellValidator.getValidatorClassName(); } else { return null; } } @Override public String toString() { final StringBuffer sb = new StringBuffer("CassandraCell{"); sb.append("cellName='").append(cellName).append('\''); sb.append(", cellValue=").append(cellValue); sb.append(", isPartitionKey=").append(isKey); sb.append(", isClusterKey=").append(isClusterKey); sb.append(", cellValidator=").append(cellValidator); sb.append('}'); return sb.toString(); } }