/*
* Copyright 2016 the original author or authors.
*
* 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 org.springframework.data.cassandra.convert;
import java.util.List;
import org.springframework.cassandra.core.cql.CqlIdentifier;
import com.datastax.driver.core.CodecRegistry;
import com.datastax.driver.core.ColumnDefinitions;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.DataType.Name;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.TypeCodec;
/**
* Helpful class to read a column's value from a row, with possible type conversion.
*
* @author Matthew T. Adams
* @author Antoine Toulme
* @author Mark Paluch
*/
public class ColumnReader {
protected Row row;
protected ColumnDefinitions columns;
private final CodecRegistry codecRegistry;
public ColumnReader(Row row) {
this.row = row;
this.columns = row.getColumnDefinitions();
this.codecRegistry = CodecRegistry.DEFAULT_INSTANCE;
}
/**
* Returns the row's column value.
*/
public Object get(CqlIdentifier name) {
return get(name.toCql());
}
/**
* Returns the row's column value.
*/
public Object get(String name) {
int indexOf = getColumnIndex(name);
return get(indexOf);
}
/**
* Read data from a Column using the {@code index}.
*
* @param index
* @return
*/
public Object get(int index) {
if (row.isNull(index)) {
return null;
}
DataType type = columns.getType(index);
if (type.isCollection()) {
return getCollection(index, type);
}
if (Name.TUPLE.equals(type.getName())) {
return row.getTupleValue(index);
}
if (Name.UDT.equals(type.getName())) {
return row.getUDTValue(index);
}
return row.getObject(index);
}
public Object getCollection(int i, DataType type) {
List<DataType> collectionTypes = type.getTypeArguments();
// List/Set
if (collectionTypes.size() == 1) {
DataType valueType = collectionTypes.get(0);
TypeCodec<Object> typeCodec = codecRegistry.codecFor(valueType);
if (type.equals(DataType.list(valueType))) {
return row.getList(i, typeCodec.getJavaType().getRawType());
}
if (type.equals(DataType.set(valueType))) {
return row.getSet(i, typeCodec.getJavaType().getRawType());
}
}
// Map
if (collectionTypes.size() == 2) {
DataType keyType = collectionTypes.get(0);
TypeCodec<Object> keyTypeCodec = codecRegistry.codecFor(keyType);
DataType valueType = collectionTypes.get(1);
TypeCodec<Object> valueTypeCodec = codecRegistry.codecFor(valueType);
return row.getMap(i, keyTypeCodec.getJavaType().getRawType(), valueTypeCodec.getJavaType().getRawType());
}
throw new IllegalStateException("Unknown Collection type encountered. Valid collections are Set, List and Map.");
}
public Row getRow() {
return row;
}
/**
* Returns the row's column value as an instance of the given type.
*
* @throws ClassCastException if the value cannot be converted to the requested type.
*/
public <T> T get(CqlIdentifier name, Class<T> requestedType) {
return get(getColumnIndex(name.toCql()), requestedType);
}
/**
* Returns the row's column value as an instance of the given type.
*
* @throws ClassCastException if the value cannot be converted to the requested type.
*/
public <T> T get(String name, Class<T> requestedType) {
return get(columns.getIndexOf(name), requestedType);
}
/**
* Returns the row's column value as an instance of the given type.
*
* @throws ClassCastException if the value cannot be converted to the requested type.
*/
@SuppressWarnings("unchecked")
public <T> T get(int i, Class<T> requestedType) {
Object o = get(i);
if (o == null) {
return null;
}
return (T) o;
}
private int getColumnIndex(String name) {
int indexOf = columns.getIndexOf(name);
if (indexOf == -1) {
throw new IllegalArgumentException("Column does not exist in Cassandra table: " + name);
}
return indexOf;
}
}