package org.simpleflatmapper.datastax; import com.datastax.driver.core.GettableByIndexData; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.SettableByIndexData; import com.datastax.driver.core.exceptions.DriverException; import org.simpleflatmapper.reflect.getter.GetterFactory; import org.simpleflatmapper.datastax.impl.DatastaxMapperKeyComparator; import org.simpleflatmapper.datastax.impl.DatastaxMappingContextFactoryBuilder; import org.simpleflatmapper.datastax.impl.RowGetterFactory; import org.simpleflatmapper.datastax.impl.SettableDataSetterFactory; import org.simpleflatmapper.map.MapperConfig; import org.simpleflatmapper.map.SetRowMapper; import org.simpleflatmapper.map.property.FieldMapperColumnDefinition; import org.simpleflatmapper.map.mapper.AbstractMapperFactory; import org.simpleflatmapper.map.mapper.ConstantTargetFieldMapperFactoryImpl; import org.simpleflatmapper.map.mapper.DynamicSetRowMapper; import org.simpleflatmapper.map.mapper.FieldMapperColumnDefinitionProviderImpl; import org.simpleflatmapper.map.mapper.MapperKey; import org.simpleflatmapper.util.TypeReference; import org.simpleflatmapper.reflect.meta.ClassMeta; import org.simpleflatmapper.util.UnaryFactory; import org.simpleflatmapper.util.UnaryFactoryWithException; import java.lang.reflect.Type; public class DatastaxMapperFactory extends AbstractMapperFactory<DatastaxColumnKey, FieldMapperColumnDefinition<DatastaxColumnKey>, DatastaxMapperFactory> { private GetterFactory<GettableByIndexData, DatastaxColumnKey> getterFactory = new RowGetterFactory(this); private DatastaxMapperFactory() { super(new FieldMapperColumnDefinitionProviderImpl<DatastaxColumnKey>(), FieldMapperColumnDefinition.<DatastaxColumnKey>identity()); } private DatastaxMapperFactory(AbstractMapperFactory<DatastaxColumnKey, FieldMapperColumnDefinition<DatastaxColumnKey>, ?> config) { super(config); } public static DatastaxMapperFactory newInstance() { return new DatastaxMapperFactory(); } public static DatastaxMapperFactory newInstance(AbstractMapperFactory<DatastaxColumnKey, FieldMapperColumnDefinition<DatastaxColumnKey>, ?> config) { return new DatastaxMapperFactory(config); } public <T> DatastaxMapperBuilder<T> newBuilder(Class<T> type) { return newBuilder((Type)type); } public <T> DatastaxMapperBuilder<T> newBuilder(TypeReference<T> type) { return newBuilder(type.getType()); } public <T> DatastaxMapperBuilder<T> newBuilder(Type type) { final ClassMeta<T> classMeta = getClassMeta(type); return newBuilder(classMeta); } public <T> DatastaxMapperBuilder<T> newBuilder(ClassMeta<T> classMeta) { return new DatastaxMapperBuilder<T>(classMeta, mapperConfig(), getterFactory, new DatastaxMappingContextFactoryBuilder()); } public <T> SettableDataMapperBuilder<T> newBuilderFrom(TypeReference<T> type) { return newBuilderFrom(type.getType()); } public <T> SettableDataMapperBuilder<T> newBuilderFrom(Class<T> type) { return newBuilderFrom((Type)type); } public <T> SettableDataMapperBuilder<T> newBuilderFrom(Type type) { ClassMeta<T> classMeta = getClassMeta(type); return newBuilderFrom(classMeta); } public <T> SettableDataMapperBuilder<T> newBuilderFrom(ClassMeta<T> classMeta) { MapperConfig<DatastaxColumnKey, FieldMapperColumnDefinition<DatastaxColumnKey>> config = mapperConfig(); return new SettableDataMapperBuilder<T>( classMeta, config, ConstantTargetFieldMapperFactoryImpl .newInstance(new SettableDataSetterFactory(config, classMeta.getReflectionService()), SettableByIndexData.class)); } public <T> DatastaxBinder<T> mapFrom(Class<T> type) { return mapFrom((Type) type); } public <T> DatastaxBinder<T> mapFrom(TypeReference<T> type) { return mapFrom(type.getType()); } public <T> DatastaxBinder<T> mapFrom(Type type) { final ClassMeta<T> classMeta = getClassMeta(type); return new DatastaxBinder<T>(classMeta, mapperConfig()); } public <T> DatastaxMapper<T> mapTo(Class<T> type) { return mapTo((Type) type); } public <T> DatastaxMapper<T> mapTo(TypeReference<T> type) { return mapTo(type.getType()); } public <T> DatastaxMapper<T> mapTo(Type type) { final ClassMeta<T> classMeta = getClassMeta(type); return new DynamicDatastaxSetRowMapper<T>(new MapperFactory<T>(classMeta), new MapperKeyFromRowFactory(), new MapperKeyFromSet()); } public <T, K> DatastaxCrudDSL<T, K> crud(Class<T> targetType, Class<K> keyType) { return crud((Type)targetType, (Type)keyType); } public <T, K> DatastaxCrudDSL<T, K> crud(Type targetType, Type keyType) { return new DatastaxCrudDSL<T, K>(targetType, keyType, this); } private static class MapperKeyFromRowFactory implements UnaryFactoryWithException<Row, MapperKey<DatastaxColumnKey>, DriverException> { @Override public MapperKey<DatastaxColumnKey> newInstance(Row row) throws DriverException { return DatastaxColumnKey.mapperKey(row.getColumnDefinitions()); } } private static class MapperKeyFromSet implements UnaryFactoryWithException<ResultSet, MapperKey<DatastaxColumnKey>, DriverException> { @Override public MapperKey<DatastaxColumnKey> newInstance(ResultSet rows) throws DriverException { return DatastaxColumnKey.mapperKey(rows.getColumnDefinitions()); } } private class MapperFactory<T> implements UnaryFactory<MapperKey<DatastaxColumnKey>, SetRowMapper<Row, ResultSet, T, DriverException>> { private final ClassMeta<T> classMeta; public MapperFactory(ClassMeta<T> classMeta) { this.classMeta = classMeta; } @Override public SetRowMapper<Row, ResultSet, T, DriverException> newInstance(MapperKey<DatastaxColumnKey> datastaxColumnKeyMapperKey) { DatastaxMapperBuilder<T> builder = newBuilder(classMeta); for(DatastaxColumnKey key : datastaxColumnKeyMapperKey.getColumns()) { builder.addMapping(key); } return builder.mapper(); } } private static class DynamicDatastaxSetRowMapper<T> extends DynamicSetRowMapper<Row, ResultSet, T, DriverException, DatastaxColumnKey> implements DatastaxMapper<T> { public DynamicDatastaxSetRowMapper( UnaryFactory<MapperKey<DatastaxColumnKey>, SetRowMapper<Row, ResultSet, T, DriverException>> mapperFactory, UnaryFactoryWithException<Row, MapperKey<DatastaxColumnKey>, DriverException> mapperKeyFromRow, UnaryFactoryWithException<ResultSet, MapperKey<DatastaxColumnKey>, DriverException> mapperKeyFromSet) { super(mapperFactory, mapperKeyFromRow, mapperKeyFromSet, DatastaxMapperKeyComparator.INSTANCE); } } }