diff --git a/NOTES b/NOTES index 04dd989..bbacfc9 100644 --- a/NOTES +++ b/NOTES @@ -1,3 +1,8 @@ + + + + + --- Cache // `E` is the type of the Entity class or one of: // - ResultSet @@ -315,3 +320,55 @@ begin: } }; } +---------------------------------- + if ("ttl".equals(methodName) && method.getParameterCount() == 1 && method.getReturnType() == int.class) { + Getter getter = (Getter) args[0]; + if (getter == null) { + return false; + } + HelenusProperty prop = MappingUtil.resolveMappingProperty(getter).getProperty(); + String getterName = prop.getPropertyName(); + String ttlKeyForProperty = prop.getColumnName().toCql() + "_ttl"; + if (src.containsKey(ttlKeyForProperty)) { + return src.get(ttlKeyForProperty); + } else { + return 0; + } + } + + if ("written".equals(methodName) && method.getParameterCount() == 1 && method.getReturnType() == int.class) { + Getter getter = (Getter) args[0]; + if (getter == null) { + return false; + } + HelenusProperty prop = MappingUtil.resolveMappingProperty(getter).getProperty(); + String getterName = prop.getPropertyName(); + String ttlKeyForProperty = prop.getColumnName().toCql() + "_ttl"; + if (src.containsKey(ttlKeyForProperty)) { + return src.get(ttlKeyForProperty); + } else { + return 0; + } + } + + + +----------------- + + +/*else { + Cache cache = session.getSessionCache(); + Map rowMap = this.cache.rowMap(); + for (String rowKey : rowMap.keySet()) { + String keys = flattenFacets(facets); + for (String key : keys) { + Object value = cache.getIfPresent(key); + if (value != null) { + result = Optional.of(value); + break; + } + } + } + cache.put + } + */ diff --git a/build.gradle b/build.gradle index 1c1b7de..50b24e8 100644 --- a/build.gradle +++ b/build.gradle @@ -64,7 +64,6 @@ dependencies { compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.10' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.6' compile group: 'org.springframework', name: 'spring-core', version: '4.3.10.RELEASE' - compile group: 'com.google.guava', name: 'guava', version: '20.0' compile group: 'com.diffplug.durian', name: 'durian', version: '3.+' compile group: 'io.zipkin.java', name: 'zipkin', version: '1.29.2' diff --git a/src/main/java/com/datastax/driver/core/DefaultMetadata.java b/src/main/java/com/datastax/driver/core/DefaultMetadata.java index 57566ab..4ca45d0 100644 --- a/src/main/java/com/datastax/driver/core/DefaultMetadata.java +++ b/src/main/java/com/datastax/driver/core/DefaultMetadata.java @@ -5,19 +5,19 @@ import java.util.List; public class DefaultMetadata extends Metadata { - public DefaultMetadata() { - super(null); - } + public DefaultMetadata() { + super(null); + } - private DefaultMetadata(Cluster.Manager cluster) { - super(cluster); - } + private DefaultMetadata(Cluster.Manager cluster) { + super(cluster); + } - public TupleType newTupleType(DataType... types) { - return newTupleType(Arrays.asList(types)); - } + public TupleType newTupleType(DataType... types) { + return newTupleType(Arrays.asList(types)); + } - public TupleType newTupleType(List types) { - return new TupleType(types, ProtocolVersion.NEWEST_SUPPORTED, CodecRegistry.DEFAULT_INSTANCE); - } + public TupleType newTupleType(List types) { + return new TupleType(types, ProtocolVersion.NEWEST_SUPPORTED, CodecRegistry.DEFAULT_INSTANCE); + } } diff --git a/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java b/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java index 9ff2596..991de7c 100644 --- a/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java +++ b/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java @@ -15,34 +15,35 @@ */ package com.datastax.driver.core.querybuilder; -import com.datastax.driver.core.CodecRegistry; import java.util.List; +import com.datastax.driver.core.CodecRegistry; + public class IsNotNullClause extends Clause { - final String name; + final String name; - public IsNotNullClause(String name) { - this.name = name; - } + public IsNotNullClause(String name) { + this.name = name; + } - @Override - String name() { - return name; - } + @Override + String name() { + return name; + } - @Override - Object firstValue() { - return null; - } + @Override + Object firstValue() { + return null; + } - @Override - void appendTo(StringBuilder sb, List variables, CodecRegistry codecRegistry) { - Utils.appendName(name, sb).append(" IS NOT NULL"); - } + @Override + void appendTo(StringBuilder sb, List variables, CodecRegistry codecRegistry) { + Utils.appendName(name, sb).append(" IS NOT NULL"); + } - @Override - boolean containsBindMarker() { - return false; - } + @Override + boolean containsBindMarker() { + return false; + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java index 54e247a..227c622 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java @@ -1,157 +1,148 @@ package com.datastax.driver.core.schemabuilder; -import static com.datastax.driver.core.schemabuilder.SchemaStatement.STATEMENT_START; -import static com.datastax.driver.core.schemabuilder.SchemaStatement.validateNotEmpty; -import static com.datastax.driver.core.schemabuilder.SchemaStatement.validateNotKeyWord; +import static com.datastax.driver.core.schemabuilder.SchemaStatement.*; import com.google.common.base.Optional; public class CreateCustomIndex extends CreateIndex { - private String indexName; - private boolean ifNotExists = false; - private Optional keyspaceName = Optional.absent(); - private String tableName; - private String columnName; - private boolean keys; + private String indexName; + private boolean ifNotExists = false; + private Optional keyspaceName = Optional.absent(); + private String tableName; + private String columnName; + private boolean keys; - CreateCustomIndex(String indexName) { - super(indexName); - validateNotEmpty(indexName, "Index name"); - validateNotKeyWord( - indexName, - String.format( - "The index name '%s' is not allowed because it is a reserved keyword", indexName)); - this.indexName = indexName; - } + CreateCustomIndex(String indexName) { + super(indexName); + validateNotEmpty(indexName, "Index name"); + validateNotKeyWord(indexName, + String.format("The index name '%s' is not allowed because it is a reserved keyword", indexName)); + this.indexName = indexName; + } - /** - * Add the 'IF NOT EXISTS' condition to this CREATE INDEX statement. - * - * @return this CREATE INDEX statement. - */ - public CreateIndex ifNotExists() { - this.ifNotExists = true; - return this; - } + /** + * Add the 'IF NOT EXISTS' condition to this CREATE INDEX statement. + * + * @return this CREATE INDEX statement. + */ + public CreateIndex ifNotExists() { + this.ifNotExists = true; + return this; + } - /** - * Specify the keyspace and table to create the index on. - * - * @param keyspaceName the keyspace name. - * @param tableName the table name. - * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification of the column. - */ - public CreateIndex.CreateIndexOn onTable(String keyspaceName, String tableName) { - validateNotEmpty(keyspaceName, "Keyspace name"); - validateNotEmpty(tableName, "Table name"); - validateNotKeyWord( - keyspaceName, - String.format( - "The keyspace name '%s' is not allowed because it is a reserved keyword", - keyspaceName)); - validateNotKeyWord( - tableName, - String.format( - "The table name '%s' is not allowed because it is a reserved keyword", tableName)); - this.keyspaceName = Optional.fromNullable(keyspaceName); - this.tableName = tableName; - return new CreateCustomIndex.CreateIndexOn(); - } + /** + * Specify the keyspace and table to create the index on. + * + * @param keyspaceName + * the keyspace name. + * @param tableName + * the table name. + * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification + * of the column. + */ + public CreateIndex.CreateIndexOn onTable(String keyspaceName, String tableName) { + validateNotEmpty(keyspaceName, "Keyspace name"); + validateNotEmpty(tableName, "Table name"); + validateNotKeyWord(keyspaceName, + String.format("The keyspace name '%s' is not allowed because it is a reserved keyword", keyspaceName)); + validateNotKeyWord(tableName, + String.format("The table name '%s' is not allowed because it is a reserved keyword", tableName)); + this.keyspaceName = Optional.fromNullable(keyspaceName); + this.tableName = tableName; + return new CreateCustomIndex.CreateIndexOn(); + } - /** - * Specify the table to create the index on. - * - * @param tableName the table name. - * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification of the column. - */ - public CreateIndex.CreateIndexOn onTable(String tableName) { - validateNotEmpty(tableName, "Table name"); - validateNotKeyWord( - tableName, - String.format( - "The table name '%s' is not allowed because it is a reserved keyword", tableName)); - this.tableName = tableName; - return new CreateCustomIndex.CreateIndexOn(); - } + /** + * Specify the table to create the index on. + * + * @param tableName + * the table name. + * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification + * of the column. + */ + public CreateIndex.CreateIndexOn onTable(String tableName) { + validateNotEmpty(tableName, "Table name"); + validateNotKeyWord(tableName, + String.format("The table name '%s' is not allowed because it is a reserved keyword", tableName)); + this.tableName = tableName; + return new CreateCustomIndex.CreateIndexOn(); + } - public class CreateIndexOn extends CreateIndex.CreateIndexOn { - /** - * Specify the column to create the index on. - * - * @param columnName the column name. - * @return the final CREATE INDEX statement. - */ - public SchemaStatement andColumn(String columnName) { - validateNotEmpty(columnName, "Column name"); - validateNotKeyWord( - columnName, - String.format( - "The column name '%s' is not allowed because it is a reserved keyword", columnName)); - CreateCustomIndex.this.columnName = columnName; - return SchemaStatement.fromQueryString(buildInternal()); - } + String getCustomClassName() { + return ""; + } - /** - * Create an index on the keys of the given map column. - * - * @param columnName the column name. - * @return the final CREATE INDEX statement. - */ - public SchemaStatement andKeysOfColumn(String columnName) { - validateNotEmpty(columnName, "Column name"); - validateNotKeyWord( - columnName, - String.format( - "The column name '%s' is not allowed because it is a reserved keyword", columnName)); - CreateCustomIndex.this.columnName = columnName; - CreateCustomIndex.this.keys = true; - return SchemaStatement.fromQueryString(buildInternal()); - } - } + String getOptions() { + return ""; + } - String getCustomClassName() { - return ""; - } + @Override + public String buildInternal() { + StringBuilder createStatement = new StringBuilder(STATEMENT_START).append("CREATE CUSTOM INDEX "); - String getOptions() { - return ""; - } + if (ifNotExists) { + createStatement.append("IF NOT EXISTS "); + } - @Override - public String buildInternal() { - StringBuilder createStatement = - new StringBuilder(STATEMENT_START).append("CREATE CUSTOM INDEX "); + createStatement.append(indexName).append(" ON "); - if (ifNotExists) { - createStatement.append("IF NOT EXISTS "); - } + if (keyspaceName.isPresent()) { + createStatement.append(keyspaceName.get()).append("."); + } + createStatement.append(tableName); - createStatement.append(indexName).append(" ON "); + createStatement.append("("); + if (keys) { + createStatement.append("KEYS("); + } - if (keyspaceName.isPresent()) { - createStatement.append(keyspaceName.get()).append("."); - } - createStatement.append(tableName); + createStatement.append(columnName); - createStatement.append("("); - if (keys) { - createStatement.append("KEYS("); - } + if (keys) { + createStatement.append(")"); + } + createStatement.append(")"); - createStatement.append(columnName); + createStatement.append(" USING '"); + createStatement.append(getCustomClassName()); + createStatement.append("' WITH OPTIONS = {"); + createStatement.append(getOptions()); + createStatement.append(" }"); - if (keys) { - createStatement.append(")"); - } - createStatement.append(")"); + return createStatement.toString(); + } - createStatement.append(" USING '"); - createStatement.append(getCustomClassName()); - createStatement.append("' WITH OPTIONS = {"); - createStatement.append(getOptions()); - createStatement.append(" }"); + public class CreateIndexOn extends CreateIndex.CreateIndexOn { + /** + * Specify the column to create the index on. + * + * @param columnName + * the column name. + * @return the final CREATE INDEX statement. + */ + public SchemaStatement andColumn(String columnName) { + validateNotEmpty(columnName, "Column name"); + validateNotKeyWord(columnName, + String.format("The column name '%s' is not allowed because it is a reserved keyword", columnName)); + CreateCustomIndex.this.columnName = columnName; + return SchemaStatement.fromQueryString(buildInternal()); + } - return createStatement.toString(); - } + /** + * Create an index on the keys of the given map column. + * + * @param columnName + * the column name. + * @return the final CREATE INDEX statement. + */ + public SchemaStatement andKeysOfColumn(String columnName) { + validateNotEmpty(columnName, "Column name"); + validateNotKeyWord(columnName, + String.format("The column name '%s' is not allowed because it is a reserved keyword", columnName)); + CreateCustomIndex.this.columnName = columnName; + CreateCustomIndex.this.keys = true; + return SchemaStatement.fromQueryString(buildInternal()); + } + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java index 919becc..867cbc6 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java @@ -5,49 +5,48 @@ import com.datastax.driver.core.querybuilder.Select; public class CreateMaterializedView extends Create { - private String viewName; - private Select.Where selection; - private String primaryKey; - private String clustering; + private String viewName; + private Select.Where selection; + private String primaryKey; + private String clustering; - public CreateMaterializedView( - String keyspaceName, String viewName, Select.Where selection, String primaryKey, String clustering) { - super(keyspaceName, viewName); - this.viewName = viewName; - this.selection = selection; - this.primaryKey = primaryKey; - this.clustering = clustering; - } + public CreateMaterializedView(String keyspaceName, String viewName, Select.Where selection, String primaryKey, + String clustering) { + super(keyspaceName, viewName); + this.viewName = viewName; + this.selection = selection; + this.primaryKey = primaryKey; + this.clustering = clustering; + } - public String getQueryString(CodecRegistry codecRegistry) { - return buildInternal(); - } + public String getQueryString(CodecRegistry codecRegistry) { + return buildInternal(); + } - public String buildInternal() { - StringBuilder createStatement = - new StringBuilder(STATEMENT_START).append("CREATE MATERIALIZED VIEW"); - if (ifNotExists) { - createStatement.append(" IF NOT EXISTS"); - } - createStatement.append(" "); - if (keyspaceName.isPresent()) { - createStatement.append(keyspaceName.get()).append("."); - } - createStatement.append(viewName); - createStatement.append(" AS "); - createStatement.append(selection.getQueryString()); - createStatement.setLength(createStatement.length() - 1); - createStatement.append(" "); - createStatement.append(primaryKey); - if (clustering != null) { - createStatement.append(" ").append(clustering); - } - createStatement.append(";"); + public String buildInternal() { + StringBuilder createStatement = new StringBuilder(STATEMENT_START).append("CREATE MATERIALIZED VIEW"); + if (ifNotExists) { + createStatement.append(" IF NOT EXISTS"); + } + createStatement.append(" "); + if (keyspaceName.isPresent()) { + createStatement.append(keyspaceName.get()).append("."); + } + createStatement.append(viewName); + createStatement.append(" AS "); + createStatement.append(selection.getQueryString()); + createStatement.setLength(createStatement.length() - 1); + createStatement.append(" "); + createStatement.append(primaryKey); + if (clustering != null) { + createStatement.append(" ").append(clustering); + } + createStatement.append(";"); - return createStatement.toString(); - } + return createStatement.toString(); + } - public String toString() { - return buildInternal(); - } + public String toString() { + return buildInternal(); + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java index 7a82590..6487b32 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java @@ -2,17 +2,16 @@ package com.datastax.driver.core.schemabuilder; public class CreateSasiIndex extends CreateCustomIndex { - public CreateSasiIndex(String indexName) { - super(indexName); - } + public CreateSasiIndex(String indexName) { + super(indexName); + } - String getCustomClassName() { - return "org.apache.cassandra.index.sasi.SASIIndex"; - } + String getCustomClassName() { + return "org.apache.cassandra.index.sasi.SASIIndex"; + } - String getOptions() { - return "'analyzer_class': " - + "'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', " - + "'case_sensitive': 'false'"; - } + String getOptions() { + return "'analyzer_class': " + "'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', " + + "'case_sensitive': 'false'"; + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java index 7efce6f..cab8549 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java @@ -20,19 +20,19 @@ import com.datastax.driver.core.CodecRegistry; /** A built CREATE TABLE statement. */ public class CreateTable extends Create { - public CreateTable(String keyspaceName, String tableName) { - super(keyspaceName, tableName); - } + public CreateTable(String keyspaceName, String tableName) { + super(keyspaceName, tableName); + } - public CreateTable(String tableName) { - super(tableName); - } + public CreateTable(String tableName) { + super(tableName); + } - public String getQueryString(CodecRegistry codecRegistry) { - return buildInternal(); - } + public String getQueryString(CodecRegistry codecRegistry) { + return buildInternal(); + } - public String toString() { - return buildInternal(); - } + public String toString() { + return buildInternal(); + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java b/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java index 7eca05d..a7279f2 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java @@ -4,50 +4,46 @@ import com.google.common.base.Optional; public class DropMaterializedView extends Drop { - enum DroppedItem { - TABLE, - TYPE, - INDEX, - MATERIALIZED_VIEW - } + private final String itemType = "MATERIALIZED VIEW"; + private Optional keyspaceName = Optional.absent(); + private String itemName; + private boolean ifExists = true; + public DropMaterializedView(String keyspaceName, String viewName) { + this(keyspaceName, viewName, DroppedItem.MATERIALIZED_VIEW); + } - private Optional keyspaceName = Optional.absent(); - private String itemName; - private boolean ifExists = true; - private final String itemType = "MATERIALIZED VIEW"; + private DropMaterializedView(String keyspaceName, String viewName, DroppedItem itemType) { + super(keyspaceName, viewName, Drop.DroppedItem.TABLE); + validateNotEmpty(keyspaceName, "Keyspace name"); + this.keyspaceName = Optional.fromNullable(keyspaceName); + this.itemName = viewName; + } - public DropMaterializedView(String keyspaceName, String viewName) { - this(keyspaceName, viewName, DroppedItem.MATERIALIZED_VIEW); - } + /** + * Add the 'IF EXISTS' condition to this DROP statement. + * + * @return this statement. + */ + public Drop ifExists() { + this.ifExists = true; + return this; + } - private DropMaterializedView(String keyspaceName, String viewName, DroppedItem itemType) { - super(keyspaceName, viewName, Drop.DroppedItem.TABLE); - validateNotEmpty(keyspaceName, "Keyspace name"); - this.keyspaceName = Optional.fromNullable(keyspaceName); - this.itemName = viewName; - } + @Override + public String buildInternal() { + StringBuilder dropStatement = new StringBuilder("DROP " + itemType + " "); + if (ifExists) { + dropStatement.append("IF EXISTS "); + } + if (keyspaceName.isPresent()) { + dropStatement.append(keyspaceName.get()).append("."); + } - /** - * Add the 'IF EXISTS' condition to this DROP statement. - * - * @return this statement. - */ - public Drop ifExists() { - this.ifExists = true; - return this; - } + dropStatement.append(itemName); + return dropStatement.toString(); + } - @Override - public String buildInternal() { - StringBuilder dropStatement = new StringBuilder("DROP " + itemType + " "); - if (ifExists) { - dropStatement.append("IF EXISTS "); - } - if (keyspaceName.isPresent()) { - dropStatement.append(keyspaceName.get()).append("."); - } - - dropStatement.append(itemName); - return dropStatement.toString(); - } + enum DroppedItem { + TABLE, TYPE, INDEX, MATERIALIZED_VIEW + } } diff --git a/src/main/java/net/helenus/config/DefaultHelenusSettings.java b/src/main/java/net/helenus/config/DefaultHelenusSettings.java index 500fed5..a8daa1c 100644 --- a/src/main/java/net/helenus/config/DefaultHelenusSettings.java +++ b/src/main/java/net/helenus/config/DefaultHelenusSettings.java @@ -17,6 +17,7 @@ package net.helenus.config; import java.lang.reflect.Method; import java.util.function.Function; + import net.helenus.core.DslInstantiator; import net.helenus.core.MapperInstantiator; import net.helenus.core.reflect.ReflectionDslInstantiator; @@ -25,23 +26,23 @@ import net.helenus.mapping.convert.CamelCaseToUnderscoreConverter; public class DefaultHelenusSettings implements HelenusSettings { - @Override - public Function getPropertyToColumnConverter() { - return CamelCaseToUnderscoreConverter.INSTANCE; - } + @Override + public Function getPropertyToColumnConverter() { + return CamelCaseToUnderscoreConverter.INSTANCE; + } - @Override - public Function getGetterMethodDetector() { - return GetterMethodDetector.INSTANCE; - } + @Override + public Function getGetterMethodDetector() { + return GetterMethodDetector.INSTANCE; + } - @Override - public DslInstantiator getDslInstantiator() { - return ReflectionDslInstantiator.INSTANCE; - } + @Override + public DslInstantiator getDslInstantiator() { + return ReflectionDslInstantiator.INSTANCE; + } - @Override - public MapperInstantiator getMapperInstantiator() { - return ReflectionMapperInstantiator.INSTANCE; - } + @Override + public MapperInstantiator getMapperInstantiator() { + return ReflectionMapperInstantiator.INSTANCE; + } } diff --git a/src/main/java/net/helenus/config/GetterMethodDetector.java b/src/main/java/net/helenus/config/GetterMethodDetector.java index 60a9ec0..a4535f5 100644 --- a/src/main/java/net/helenus/config/GetterMethodDetector.java +++ b/src/main/java/net/helenus/config/GetterMethodDetector.java @@ -18,31 +18,32 @@ package net.helenus.config; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.function.Function; + import net.helenus.mapping.annotation.Transient; public enum GetterMethodDetector implements Function { - INSTANCE; + INSTANCE; - @Override - public Boolean apply(Method method) { + @Override + public Boolean apply(Method method) { - if (method == null) { - throw new IllegalArgumentException("empty parameter"); - } + if (method == null) { + throw new IllegalArgumentException("empty parameter"); + } - if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { - return false; - } + if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { + return false; + } - if (Modifier.isStatic(method.getModifiers())) { - return false; - } + if (Modifier.isStatic(method.getModifiers())) { + return false; + } - // Methods marked "Transient" are not mapped, skip them. - if (method.getDeclaredAnnotation(Transient.class) != null) { - return false; - } + // Methods marked "Transient" are not mapped, skip them. + if (method.getDeclaredAnnotation(Transient.class) != null) { + return false; + } - return true; - } + return true; + } } diff --git a/src/main/java/net/helenus/config/HelenusSettings.java b/src/main/java/net/helenus/config/HelenusSettings.java index c8ffee2..27d1431 100644 --- a/src/main/java/net/helenus/config/HelenusSettings.java +++ b/src/main/java/net/helenus/config/HelenusSettings.java @@ -17,16 +17,17 @@ package net.helenus.config; import java.lang.reflect.Method; import java.util.function.Function; + import net.helenus.core.DslInstantiator; import net.helenus.core.MapperInstantiator; public interface HelenusSettings { - Function getPropertyToColumnConverter(); + Function getPropertyToColumnConverter(); - Function getGetterMethodDetector(); + Function getGetterMethodDetector(); - DslInstantiator getDslInstantiator(); + DslInstantiator getDslInstantiator(); - MapperInstantiator getMapperInstantiator(); + MapperInstantiator getMapperInstantiator(); } diff --git a/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java b/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java index a9a09e2..f2b16ff 100644 --- a/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java @@ -3,36 +3,37 @@ package net.helenus.core; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Date; + import net.helenus.core.reflect.MapExportable; public abstract class AbstractAuditedEntityDraft extends AbstractEntityDraft { - public AbstractAuditedEntityDraft(MapExportable entity) { - super(entity); + public AbstractAuditedEntityDraft(MapExportable entity) { + super(entity); - Date in = new Date(); - LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); - Date now = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); + Date in = new Date(); + LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); + Date now = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); - String who = getCurrentAuditor(); + String who = getCurrentAuditor(); - if (entity == null) { - if (who != null) { - set("createdBy", who); - } - set("createdAt", now); - } - if (who != null) { - set("modifiedBy", who); - } - set("modifiedAt", now); - } + if (entity == null) { + if (who != null) { + set("createdBy", who); + } + set("createdAt", now); + } + if (who != null) { + set("modifiedBy", who); + } + set("modifiedAt", now); + } - protected String getCurrentAuditor() { - return null; - } + protected String getCurrentAuditor() { + return null; + } - public Date createdAt() { - return (Date) get("createdAt", Date.class); - } + public Date createdAt() { + return (Date) get("createdAt", Date.class); + } } diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index fbccb3b..6c9bf9f 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -1,7 +1,12 @@ package net.helenus.core; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + import com.google.common.primitives.Primitives; -import java.util.*; + import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.MapExportable; @@ -9,151 +14,151 @@ import net.helenus.mapping.MappingUtil; public abstract class AbstractEntityDraft implements Drafted { - private final Map backingMap = new HashMap(); - private final MapExportable entity; - private final Map entityMap; + private final Map backingMap = new HashMap(); + private final MapExportable entity; + private final Map entityMap; - public AbstractEntityDraft(MapExportable entity) { - this.entity = entity; - this.entityMap = entity != null ? entity.toMap() : new HashMap(); - } + public AbstractEntityDraft(MapExportable entity) { + this.entity = entity; + this.entityMap = entity != null ? entity.toMap() : new HashMap(); + } - public abstract Class getEntityClass(); + public abstract Class getEntityClass(); - public E build() { - return Helenus.map(getEntityClass(), toMap()); - } + public E build() { + return Helenus.map(getEntityClass(), toMap()); + } - @SuppressWarnings("unchecked") - protected T get(Getter getter, Class returnType) { - return (T) get(this.methodNameFor(getter), returnType); - } + @SuppressWarnings("unchecked") + protected T get(Getter getter, Class returnType) { + return (T) get(this.methodNameFor(getter), returnType); + } - @SuppressWarnings("unchecked") - protected T get(String key, Class returnType) { - T value = (T) backingMap.get(key); + @SuppressWarnings("unchecked") + protected T get(String key, Class returnType) { + T value = (T) backingMap.get(key); - if (value == null) { - value = (T) entityMap.get(key); - if (value == null) { + if (value == null) { + value = (T) entityMap.get(key); + if (value == null) { - if (Primitives.allPrimitiveTypes().contains(returnType)) { + if (Primitives.allPrimitiveTypes().contains(returnType)) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); - if (type == null) { - throw new RuntimeException("unknown primitive type " + returnType); - } + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); + if (type == null) { + throw new RuntimeException("unknown primitive type " + returnType); + } - return (T) type.getDefaultValue(); - } - } - } + return (T) type.getDefaultValue(); + } + } + } - return value; - } + return value; + } - protected Object set(Getter getter, Object value) { - return set(this.methodNameFor(getter), value); - } + protected Object set(Getter getter, Object value) { + return set(this.methodNameFor(getter), value); + } - protected Object set(String key, Object value) { - if (key == null || value == null) { - return null; - } + protected Object set(String key, Object value) { + if (key == null || value == null) { + return null; + } - backingMap.put(key, value); - return value; - } + backingMap.put(key, value); + return value; + } - @SuppressWarnings("unchecked") - protected T mutate(Getter getter, T value) { - return (T) mutate(this.methodNameFor(getter), value); - } + @SuppressWarnings("unchecked") + protected T mutate(Getter getter, T value) { + return (T) mutate(this.methodNameFor(getter), value); + } - protected Object mutate(String key, Object value) { - Objects.requireNonNull(key); + protected Object mutate(String key, Object value) { + Objects.requireNonNull(key); - if (value == null) { - return null; - } + if (value == null) { + return null; + } - if (entity != null) { - Map map = entity.toMap(); + if (entity != null) { + Map map = entity.toMap(); - if (map.containsKey(key) && !value.equals(map.get(key))) { - backingMap.put(key, value); - return value; - } + if (map.containsKey(key) && !value.equals(map.get(key))) { + backingMap.put(key, value); + return value; + } - return map.get(key); - } else { - backingMap.put(key, value); + return map.get(key); + } else { + backingMap.put(key, value); - return null; - } - } + return null; + } + } - private String methodNameFor(Getter getter) { - return MappingUtil.resolveMappingProperty(getter).getProperty().getPropertyName(); - } + private String methodNameFor(Getter getter) { + return MappingUtil.resolveMappingProperty(getter).getProperty().getPropertyName(); + } - public Object unset(Getter getter) { - return unset(methodNameFor(getter)); - } + public Object unset(Getter getter) { + return unset(methodNameFor(getter)); + } - public Object unset(String key) { - if (key != null) { - Object value = backingMap.get(key); - backingMap.put(key, null); - return value; - } - return null; - } + public Object unset(String key) { + if (key != null) { + Object value = backingMap.get(key); + backingMap.put(key, null); + return value; + } + return null; + } - public boolean reset(Getter getter, T desiredValue) { - return this.reset(this.methodNameFor(getter), desiredValue); - } + public boolean reset(Getter getter, T desiredValue) { + return this.reset(this.methodNameFor(getter), desiredValue); + } - public boolean reset(String key, T desiredValue) { - if (key != null && desiredValue != null) { - @SuppressWarnings("unchecked") - T currentValue = (T) backingMap.get(key); - if (currentValue == null || !currentValue.equals(desiredValue)) { - set(key, desiredValue); - return true; - } - } - return false; - } + public boolean reset(String key, T desiredValue) { + if (key != null && desiredValue != null) { + @SuppressWarnings("unchecked") + T currentValue = (T) backingMap.get(key); + if (currentValue == null || !currentValue.equals(desiredValue)) { + set(key, desiredValue); + return true; + } + } + return false; + } - @Override - public Map toMap() { - return toMap(entityMap); - } + @Override + public Map toMap() { + return toMap(entityMap); + } - public Map toMap(Map entityMap) { - Map combined; - if (entityMap != null && entityMap.size() > 0) { - combined = new HashMap(entityMap.size()); - for (String key : entityMap.keySet()) { - combined.put(key, entityMap.get(key)); - } - } else { - combined = new HashMap(backingMap.size()); - } - for (String key : mutated()) { - combined.put(key, backingMap.get(key)); - } - return combined; - } + public Map toMap(Map entityMap) { + Map combined; + if (entityMap != null && entityMap.size() > 0) { + combined = new HashMap(entityMap.size()); + for (String key : entityMap.keySet()) { + combined.put(key, entityMap.get(key)); + } + } else { + combined = new HashMap(backingMap.size()); + } + for (String key : mutated()) { + combined.put(key, backingMap.get(key)); + } + return combined; + } - @Override - public Set mutated() { - return backingMap.keySet(); - } + @Override + public Set mutated() { + return backingMap.keySet(); + } - @Override - public String toString() { - return backingMap.toString(); - } + @Override + public String toString() { + return backingMap.toString(); + } } diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 5721051..15abfae 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -15,112 +15,128 @@ */ package net.helenus.core; -import brave.Tracer; -import com.codahale.metrics.MetricRegistry; -import com.datastax.driver.core.*; -import com.datastax.driver.core.querybuilder.BuiltStatement; -import com.google.common.util.concurrent.ListenableFuture; import java.io.PrintStream; +import java.util.List; import java.util.concurrent.Executor; -import net.helenus.mapping.value.ColumnValuePreparer; -import net.helenus.mapping.value.ColumnValueProvider; -import net.helenus.support.HelenusException; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.codahale.metrics.MetricRegistry; +import com.datastax.driver.core.*; +import com.datastax.driver.core.querybuilder.BuiltStatement; +import com.google.common.collect.Table; +import com.google.common.util.concurrent.ListenableFuture; + +import brave.Tracer; +import net.helenus.core.cache.Facet; +import net.helenus.mapping.value.ColumnValuePreparer; +import net.helenus.mapping.value.ColumnValueProvider; +import net.helenus.support.HelenusException; + public abstract class AbstractSessionOperations { - final Logger logger = LoggerFactory.getLogger(getClass()); + private static final Logger LOG = LoggerFactory.getLogger(AbstractSessionOperations.class); - public abstract Session currentSession(); + public abstract Session currentSession(); - public abstract String usingKeyspace(); + public abstract String usingKeyspace(); - public abstract boolean isShowCql(); + public abstract boolean isShowCql(); - public abstract PrintStream getPrintStream(); + public abstract PrintStream getPrintStream(); - public abstract Executor getExecutor(); + public abstract Executor getExecutor(); - public abstract SessionRepository getSessionRepository(); + public abstract SessionRepository getSessionRepository(); - public abstract ColumnValueProvider getValueProvider(); + public abstract ColumnValueProvider getValueProvider(); - public abstract ColumnValuePreparer getValuePreparer(); + public abstract ColumnValuePreparer getValuePreparer(); - public abstract ConsistencyLevel getDefaultConsistencyLevel(); + public abstract ConsistencyLevel getDefaultConsistencyLevel(); - public abstract boolean getDefaultQueryIdempotency(); + public abstract boolean getDefaultQueryIdempotency(); - public PreparedStatement prepare(RegularStatement statement) { - try { - log(statement, false); - return currentSession().prepare(statement); - } catch (RuntimeException e) { - throw translateException(e); - } - } + public PreparedStatement prepare(RegularStatement statement) { + try { + log(statement, false); + return currentSession().prepare(statement); + } catch (RuntimeException e) { + throw translateException(e); + } + } - public ListenableFuture prepareAsync(RegularStatement statement) { - try { - log(statement, false); - return currentSession().prepareAsync(statement); - } catch (RuntimeException e) { - throw translateException(e); - } - } + public ListenableFuture prepareAsync(RegularStatement statement) { + try { + log(statement, false); + return currentSession().prepareAsync(statement); + } catch (RuntimeException e) { + throw translateException(e); + } + } - public ResultSet execute(Statement statement, boolean showValues) { - return executeAsync(statement, showValues).getUninterruptibly(); - } + public ResultSet execute(Statement statement, boolean showValues) { + return executeAsync(statement, showValues).getUninterruptibly(); + } - public ResultSetFuture executeAsync(Statement statement, boolean showValues) { - try { - log(statement, showValues); - return currentSession().executeAsync(statement); - } catch (RuntimeException e) { - throw translateException(e); - } - } + public ResultSetFuture executeAsync(Statement statement, boolean showValues) { + try { + log(statement, showValues); + return currentSession().executeAsync(statement); + } catch (RuntimeException e) { + throw translateException(e); + } + } - void log(Statement statement, boolean showValues) { - if (logger.isInfoEnabled()) { - logger.info("Execute statement " + statement); - } - if (isShowCql()) { - if (statement instanceof BuiltStatement) { - BuiltStatement builtStatement = (BuiltStatement) statement; - if (showValues) { - RegularStatement regularStatement = builtStatement.setForceNoValues(true); - printCql(regularStatement.getQueryString()); - } else { - printCql(builtStatement.getQueryString()); - } - } else if (statement instanceof RegularStatement) { - RegularStatement regularStatement = (RegularStatement) statement; - printCql(regularStatement.getQueryString()); - } else { - printCql(statement.toString()); - } - } - } + void log(Statement statement, boolean showValues) { + if (LOG.isInfoEnabled()) { + LOG.info("Execute statement " + statement); + } + if (isShowCql()) { + if (statement instanceof BuiltStatement) { + BuiltStatement builtStatement = (BuiltStatement) statement; + if (showValues) { + RegularStatement regularStatement = builtStatement.setForceNoValues(true); + printCql(regularStatement.getQueryString()); + } else { + printCql(builtStatement.getQueryString()); + } + } else if (statement instanceof RegularStatement) { + RegularStatement regularStatement = (RegularStatement) statement; + printCql(regularStatement.getQueryString()); + } else { + printCql(statement.toString()); + } + } + } - public Tracer getZipkinTracer() { - return null; - } + public Tracer getZipkinTracer() { + return null; + } - public MetricRegistry getMetricRegistry() { - return null; - } + public MetricRegistry getMetricRegistry() { + return null; + } - RuntimeException translateException(RuntimeException e) { - if (e instanceof HelenusException) { - return e; - } - throw new HelenusException(e); - } + public void mergeCache(Table cache) { + } - void printCql(String cql) { - getPrintStream().println(cql); - } + RuntimeException translateException(RuntimeException e) { + if (e instanceof HelenusException) { + return e; + } + throw new HelenusException(e); + } + + public Object checkCache(String tableName, List facets) { + return null; + } + + public void updateCache(Object pojo, List facets) { + } + + void printCql(String cql) { + getPrintStream().println(cql); + } } diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index c621770..fe3ccdf 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -15,163 +15,239 @@ */ package net.helenus.core; -import com.diffplug.common.base.Errors; -import com.google.common.collect.TreeTraverser; import java.util.*; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.diffplug.common.base.Errors; +import com.google.common.base.Stopwatch; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import com.google.common.collect.TreeTraverser; + +import net.helenus.core.cache.CacheUtil; +import net.helenus.core.cache.Facet; /** Encapsulates the concept of a "transaction" as a unit-of-work. */ -public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { - private final List> nested = new ArrayList<>(); - private final HelenusSession session; - private final AbstractUnitOfWork parent; - private List postCommit = new ArrayList(); - private final Map> cache = new HashMap>(); - private boolean aborted = false; - private boolean committed = false; +public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { - protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { - Objects.requireNonNull(session, "containing session cannot be null"); + private static final Logger LOG = LoggerFactory.getLogger(AbstractUnitOfWork.class); - this.session = session; - this.parent = parent; - } + private final List> nested = new ArrayList<>(); + private final HelenusSession session; + private final AbstractUnitOfWork parent; + // Cache: + private final Table cache = HashBasedTable.create(); + private List postCommit = new ArrayList(); + private boolean aborted = false; + private boolean committed = false; + private String purpose_; + private Stopwatch elapsedTime_; + private Stopwatch databaseTime_ = Stopwatch.createUnstarted(); + private Stopwatch cacheLookupTime_ = Stopwatch.createUnstarted(); - public UnitOfWork addNestedUnitOfWork(UnitOfWork uow) { - synchronized (nested) { - nested.add((AbstractUnitOfWork) uow); - } - return this; - } + protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { + Objects.requireNonNull(session, "containing session cannot be null"); - public UnitOfWork begin() { - // log.record(txn::start) - return this; - } + this.session = session; + this.parent = parent; + } - private void applyPostCommitFunctions() { - if (!postCommit.isEmpty()) { - for (CommitThunk f : postCommit) { - f.apply(); - } - } - } + @Override + public Stopwatch getExecutionTimer() { + return databaseTime_; + } - public Set cacheLookup(String key) { - Set r = getCache().get(key); - if (r != null) { - return r; - } else { - if (parent != null) { - return parent.cacheLookup(key); - } - } - return null; - } + @Override + public Stopwatch getCacheLookupTimer() { + return cacheLookupTime_; + } - public Map> getCache() { - return cache; - } + @Override + public void addNestedUnitOfWork(UnitOfWork uow) { + synchronized (nested) { + nested.add((AbstractUnitOfWork) uow); + } + } - private Iterator> getChildNodes() { - return nested.iterator(); - } + @Override + public UnitOfWork begin() { + elapsedTime_ = Stopwatch.createStarted(); + // log.record(txn::start) + return this; + } - /** - * Checks to see if the work performed between calling begin and now can be committed or not. - * - * @return a function from which to chain work that only happens when commit is successful - * @throws E when the work overlaps with other concurrent writers. - */ - public PostCommitFunction commit() throws E { - // All nested UnitOfWork should be committed (not aborted) before calls to commit, check. - boolean canCommit = true; - TreeTraverser> traverser = - TreeTraverser.using(node -> node::getChildNodes); - for (AbstractUnitOfWork uow : traverser.postOrderTraversal(this)) { - if (this != uow) { - canCommit &= (!uow.aborted && uow.committed); - } - } + @Override + public UnitOfWork setPurpose(String purpose) { + purpose_ = purpose; + return this; + } - // log.record(txn::provisionalCommit) - // examine log for conflicts in read-set and write-set between begin and provisional commit - // if (conflict) { throw new ConflictingUnitOfWorkException(this) } - // else return function so as to enable commit.andThen(() -> { do something iff commit was successful; }) + public void logTimers(String what) { + double e = (double) elapsedTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; + double d = (double) databaseTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; + double c = (double) cacheLookupTime_.elapsed(TimeUnit.MICROSECONDS) / 1000.0; + double fd = (d / (e - c)) * 100.0; + double fc = (c / (e - d)) * 100.0; + LOG.info(String.format("UOW(%s)%s %s (total: %.3fms cache: %.3fms %2.2f%% db: %.3fms %2.2f%%)", hashCode(), + (purpose_ == null ? "" : " " + purpose_), what, e, c, fc, d, fd)); + } - if (canCommit) { - committed = true; - aborted = false; + private void applyPostCommitFunctions() { + if (!postCommit.isEmpty()) { + for (CommitThunk f : postCommit) { + f.apply(); + } + } + logTimers("committed"); + } - // TODO(gburd): union this cache with parent's (if there is a parent) or with the session cache for all cacheable entities we currently hold + @Override + public Optional cacheLookup(List facets) { + String tableName = CacheUtil.schemaName(facets); + Optional result = Optional.empty(); + for (Facet facet : facets) { + if (!facet.fixed()) { + String columnName = facet.name() + "==" + facet.value(); + Object value = cache.get(tableName, columnName); + if (value != null) { + if (result.isPresent() && result.get() != value) { + // One facet matched, but another did not. + result = Optional.empty(); + break; + } else { + result = Optional.of(value); + } + } + } + } + if (!result.isPresent()) { + // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. + if (parent != null) { + return parent.cacheLookup(facets); + } + } + return result; + } - nested.forEach((uow) -> Errors.rethrow().wrap(uow::commit)); + @Override + public void cacheUpdate(Object value, List facets) { + Facet table = facets.remove(0); + String tableName = table.value().toString(); + for (Facet facet : facets) { + String columnName = facet.name() + "==" + facet.value(); + cache.put(tableName, columnName, value); + } + } - // Merge UOW cache into parent's cache. - if (parent != null) { - Map> parentCache = parent.getCache(); - for (String key : cache.keySet()) { - if (parentCache.containsKey(key)) { - // merge the sets - Set ps = parentCache.get(key); - ps.addAll( - cache.get(key)); //TODO(gburd): review this, likely not correct in all cases as-is. - } else { - // add the missing set - parentCache.put(key, cache.get(key)); - } - } - } + private Iterator> getChildNodes() { + return nested.iterator(); + } - // Apply all post-commit functions for - if (parent == null) { - traverser - .postOrderTraversal(this) - .forEach( - uow -> { - uow.applyPostCommitFunctions(); - }); - return new PostCommitFunction(this, null); - } - } - // else { - // Constructor ctor = clazz.getConstructor(conflictExceptionClass); - // T object = ctor.newInstance(new Object[] { String message }); - // } - return new PostCommitFunction(this, postCommit); - } + /** + * Checks to see if the work performed between calling begin and now can be + * committed or not. + * + * @return a function from which to chain work that only happens when commit is + * successful + * @throws E + * when the work overlaps with other concurrent writers. + */ + public PostCommitFunction commit() throws E { + // All nested UnitOfWork should be committed (not aborted) before calls to + // commit, check. + boolean canCommit = true; + TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); + for (AbstractUnitOfWork uow : traverser.postOrderTraversal(this)) { + if (this != uow) { + canCommit &= (!uow.aborted && uow.committed); + } + } - /* Explicitly discard the work and mark it as as such in the log. */ - public void abort() { - TreeTraverser> traverser = - TreeTraverser.using(node -> node::getChildNodes); - traverser - .postOrderTraversal(this) - .forEach( - uow -> { - uow.committed = false; - uow.aborted = true; - }); - // log.record(txn::abort) - // cache.invalidateSince(txn::start time) - } + // log.record(txn::provisionalCommit) + // examine log for conflicts in read-set and write-set between begin and + // provisional commit + // if (conflict) { throw new ConflictingUnitOfWorkException(this) } + // else return function so as to enable commit.andThen(() -> { do something iff + // commit was successful; }) - public String describeConflicts() { - return "it's complex..."; - } + if (canCommit) { + committed = true; + aborted = false; - @Override - public void close() throws E { - // Closing a AbstractUnitOfWork will abort iff we've not already aborted or committed this unit of work. - if (aborted == false && committed == false) { - abort(); - } - } + nested.forEach((uow) -> Errors.rethrow().wrap(uow::commit)); - public boolean hasAborted() { - return aborted; - } + // Merge UOW cache into parent's cache. + if (parent != null) { + parent.mergeCache(cache); + } else { + session.mergeCache(cache); + } + elapsedTime_.stop(); - public boolean hasCommitted() { - return committed; - } + // Apply all post-commit functions for + if (parent == null) { + traverser.postOrderTraversal(this).forEach(uow -> { + uow.applyPostCommitFunctions(); + }); + return new PostCommitFunction(this, null); + } + } + // else { + // Constructor ctor = clazz.getConstructor(conflictExceptionClass); + // T object = ctor.newInstance(new Object[] { String message }); + // } + return new PostCommitFunction(this, postCommit); + } + + /* Explicitly discard the work and mark it as as such in the log. */ + public void abort() { + TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); + traverser.postOrderTraversal(this).forEach(uow -> { + uow.committed = false; + uow.aborted = true; + }); + // log.record(txn::abort) + // cache.invalidateSince(txn::start time) + if (!hasAborted()) { + elapsedTime_.stop(); + logTimers("aborted"); + } + } + + private void mergeCache(Table from) { + Table to = this.cache; + from.rowMap().forEach((rowKey, columnMap) -> { + columnMap.forEach((columnKey, value) -> { + if (to.contains(rowKey, columnKey)) { + to.put(rowKey, columnKey, CacheUtil.merge(to.get(rowKey, columnKey), from.get(rowKey, columnKey))); + } else { + to.put(rowKey, columnKey, from.get(rowKey, columnKey)); + } + }); + }); + } + + public String describeConflicts() { + return "it's complex..."; + } + + @Override + public void close() throws E { + // Closing a AbstractUnitOfWork will abort iff we've not already aborted or + // committed this unit of work. + if (aborted == false && committed == false) { + abort(); + } + } + + public boolean hasAborted() { + return aborted; + } + + public boolean hasCommitted() { + return committed; + } } diff --git a/src/main/java/net/helenus/core/AutoDdl.java b/src/main/java/net/helenus/core/AutoDdl.java index c1e2626..d578cfd 100644 --- a/src/main/java/net/helenus/core/AutoDdl.java +++ b/src/main/java/net/helenus/core/AutoDdl.java @@ -16,8 +16,5 @@ package net.helenus.core; public enum AutoDdl { - VALIDATE, - UPDATE, - CREATE, - CREATE_DROP; + VALIDATE, UPDATE, CREATE, CREATE_DROP; } diff --git a/src/main/java/net/helenus/core/CommitThunk.java b/src/main/java/net/helenus/core/CommitThunk.java index ff50f4a..11b1e30 100644 --- a/src/main/java/net/helenus/core/CommitThunk.java +++ b/src/main/java/net/helenus/core/CommitThunk.java @@ -1,7 +1,6 @@ package net.helenus.core; - @FunctionalInterface public interface CommitThunk { - void apply(); + void apply(); } diff --git a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java index f91e75f..a20aad4 100644 --- a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java +++ b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java @@ -2,9 +2,9 @@ package net.helenus.core; public class ConflictingUnitOfWorkException extends Exception { - final UnitOfWork uow; + final UnitOfWork uow; - ConflictingUnitOfWorkException(UnitOfWork uow) { - this.uow = uow; - } + ConflictingUnitOfWorkException(UnitOfWork uow) { + this.uow = uow; + } } diff --git a/src/main/java/net/helenus/core/DslInstantiator.java b/src/main/java/net/helenus/core/DslInstantiator.java index d05914c..29b96de 100644 --- a/src/main/java/net/helenus/core/DslInstantiator.java +++ b/src/main/java/net/helenus/core/DslInstantiator.java @@ -15,15 +15,13 @@ */ package net.helenus.core; -import com.datastax.driver.core.Metadata; import java.util.Optional; + +import com.datastax.driver.core.Metadata; + import net.helenus.core.reflect.HelenusPropertyNode; public interface DslInstantiator { - E instantiate( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata); + E instantiate(Class iface, ClassLoader classLoader, Optional parent, Metadata metadata); } diff --git a/src/main/java/net/helenus/core/Filter.java b/src/main/java/net/helenus/core/Filter.java index 0958c93..9eeb803 100644 --- a/src/main/java/net/helenus/core/Filter.java +++ b/src/main/java/net/helenus/core/Filter.java @@ -15,97 +15,102 @@ */ package net.helenus.core; -import com.datastax.driver.core.querybuilder.Clause; import java.util.Objects; + +import com.datastax.driver.core.querybuilder.Clause; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.value.ColumnValuePreparer; public final class Filter { - private final HelenusPropertyNode node; - private final Postulate postulate; + private final HelenusPropertyNode node; + private final Postulate postulate; - private Filter(HelenusPropertyNode node, Postulate postulate) { - this.node = node; - this.postulate = postulate; - } + private Filter(HelenusPropertyNode node, Postulate postulate) { + this.node = node; + this.postulate = postulate; + } - public HelenusPropertyNode getNode() { - return node; - } + public static Filter equal(Getter getter, V val) { + return create(getter, Operator.EQ, val); + } - public Clause getClause(ColumnValuePreparer valuePreparer) { - return postulate.getClause(node, valuePreparer); - } + public static Filter in(Getter getter, V... vals) { + Objects.requireNonNull(getter, "empty getter"); + Objects.requireNonNull(vals, "empty values"); - public static Filter equal(Getter getter, V val) { - return create(getter, Operator.EQ, val); - } + if (vals.length == 0) { + throw new IllegalArgumentException("values array is empty"); + } - public static Filter in(Getter getter, V... vals) { - Objects.requireNonNull(getter, "empty getter"); - Objects.requireNonNull(vals, "empty values"); + for (int i = 0; i != vals.length; ++i) { + Objects.requireNonNull(vals[i], "value[" + i + "] is empty"); + } - if (vals.length == 0) { - throw new IllegalArgumentException("values array is empty"); - } + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - for (int i = 0; i != vals.length; ++i) { - Objects.requireNonNull(vals[i], "value[" + i + "] is empty"); - } + Postulate postulate = Postulate.of(Operator.IN, vals); - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + return new Filter(node, postulate); + } - Postulate postulate = Postulate.of(Operator.IN, vals); + public static Filter greaterThan(Getter getter, V val) { + return create(getter, Operator.GT, val); + } - return new Filter(node, postulate); - } + public static Filter lessThan(Getter getter, V val) { + return create(getter, Operator.LT, val); + } - public static Filter greaterThan(Getter getter, V val) { - return create(getter, Operator.GT, val); - } + public static Filter greaterThanOrEqual(Getter getter, V val) { + return create(getter, Operator.GTE, val); + } - public static Filter lessThan(Getter getter, V val) { - return create(getter, Operator.LT, val); - } + public static Filter lessThanOrEqual(Getter getter, V val) { + return create(getter, Operator.LTE, val); + } - public static Filter greaterThanOrEqual(Getter getter, V val) { - return create(getter, Operator.GTE, val); - } + public static Filter create(Getter getter, Postulate postulate) { + Objects.requireNonNull(getter, "empty getter"); + Objects.requireNonNull(postulate, "empty operator"); - public static Filter lessThanOrEqual(Getter getter, V val) { - return create(getter, Operator.LTE, val); - } + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - public static Filter create(Getter getter, Postulate postulate) { - Objects.requireNonNull(getter, "empty getter"); - Objects.requireNonNull(postulate, "empty operator"); + return new Filter(node, postulate); + } - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + public static Filter create(Getter getter, Operator op, V val) { + Objects.requireNonNull(getter, "empty getter"); + Objects.requireNonNull(op, "empty op"); + Objects.requireNonNull(val, "empty value"); - return new Filter(node, postulate); - } + if (op == Operator.IN) { + throw new IllegalArgumentException("invalid usage of the 'in' operator, use Filter.in() static method"); + } - public static Filter create(Getter getter, Operator op, V val) { - Objects.requireNonNull(getter, "empty getter"); - Objects.requireNonNull(op, "empty op"); - Objects.requireNonNull(val, "empty value"); + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - if (op == Operator.IN) { - throw new IllegalArgumentException( - "invalid usage of the 'in' operator, use Filter.in() static method"); - } + Postulate postulate = Postulate.of(op, val); - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + return new Filter(node, postulate); + } - Postulate postulate = Postulate.of(op, val); + public HelenusPropertyNode getNode() { + return node; + } - return new Filter(node, postulate); - } + public Clause getClause(ColumnValuePreparer valuePreparer) { + return postulate.getClause(node, valuePreparer); + } - @Override - public String toString() { - return node.getColumnName() + postulate.toString(); - } + public V[] postulateValues() { + return postulate.values(); + } + + @Override + public String toString() { + return node.getColumnName() + postulate.toString(); + } } diff --git a/src/main/java/net/helenus/core/Getter.java b/src/main/java/net/helenus/core/Getter.java index 7b7d5dd..2cf9c39 100644 --- a/src/main/java/net/helenus/core/Getter.java +++ b/src/main/java/net/helenus/core/Getter.java @@ -17,5 +17,5 @@ package net.helenus.core; public interface Getter { - V get(); + V get(); } diff --git a/src/main/java/net/helenus/core/Helenus.java b/src/main/java/net/helenus/core/Helenus.java index c0d9bc6..eb6b493 100644 --- a/src/main/java/net/helenus/core/Helenus.java +++ b/src/main/java/net/helenus/core/Helenus.java @@ -15,12 +15,17 @@ */ package net.helenus.core; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Metadata; import com.datastax.driver.core.Session; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; + import net.helenus.config.DefaultHelenusSettings; import net.helenus.config.HelenusSettings; import net.helenus.core.reflect.DslExportable; @@ -30,164 +35,161 @@ import net.helenus.support.HelenusMappingException; public final class Helenus { - private static volatile HelenusSettings settings = new DefaultHelenusSettings(); - private static final ConcurrentMap, Object> dslCache = - new ConcurrentHashMap, Object>(); - private static final ConcurrentMap, Metadata> metadataForEntity = - new ConcurrentHashMap, Metadata>(); - private static final Set sessions = new HashSet(); - private static volatile HelenusSession singleton; + private static final ConcurrentMap, Object> dslCache = new ConcurrentHashMap, Object>(); + private static final ConcurrentMap, Metadata> metadataForEntity = new ConcurrentHashMap, Metadata>(); + private static final Set sessions = new HashSet(); + private static volatile HelenusSettings settings = new DefaultHelenusSettings(); + private static volatile HelenusSession singleton; - private Helenus() {} + private Helenus() { + } - protected static void setSession(HelenusSession session) { - sessions.add(session); - singleton = session; - } + protected static void setSession(HelenusSession session) { + sessions.add(session); + singleton = session; + } - public static HelenusSession session() { - return singleton; - } + public static HelenusSession session() { + return singleton; + } - public static void shutdown() { - sessions.forEach( - (session) -> { - session.close(); - sessions.remove(session); - }); - dslCache.clear(); - } + public static void shutdown() { + sessions.forEach((session) -> { + session.close(); + sessions.remove(session); + }); + dslCache.clear(); + } - public static HelenusSettings settings() { - return settings; - } + public static HelenusSettings settings() { + return settings; + } - public static HelenusSettings settings(HelenusSettings overrideSettings) { - HelenusSettings old = settings; - settings = overrideSettings; - return old; - } + public static HelenusSettings settings(HelenusSettings overrideSettings) { + HelenusSettings old = settings; + settings = overrideSettings; + return old; + } - public static SessionInitializer connect(Cluster cluster) { - Session session = cluster.connect(); - return new SessionInitializer(session); - } + public static SessionInitializer connect(Cluster cluster) { + Session session = cluster.connect(); + return new SessionInitializer(session); + } - public static SessionInitializer connect(Cluster cluster, String keyspace) { - Session session = cluster.connect(keyspace); - return new SessionInitializer(session); - } + public static SessionInitializer connect(Cluster cluster, String keyspace) { + Session session = cluster.connect(keyspace); + return new SessionInitializer(session); + } - public static SessionInitializer init(Session session) { + public static SessionInitializer init(Session session) { - if (session == null) { - throw new IllegalArgumentException("empty session"); - } + if (session == null) { + throw new IllegalArgumentException("empty session"); + } - return new SessionInitializer(session); - } + return new SessionInitializer(session); + } - public static void clearDslCache() { - dslCache.clear(); - } + public static void clearDslCache() { + dslCache.clear(); + } - public static E dsl(Class iface) { - return dsl(iface, null); - } + public static E dsl(Class iface) { + return dsl(iface, null); + } - public static E dsl(Class iface, Metadata metadata) { - return dsl(iface, iface.getClassLoader(), Optional.empty(), metadata); - } + public static E dsl(Class iface, Metadata metadata) { + return dsl(iface, iface.getClassLoader(), Optional.empty(), metadata); + } - public static E dsl(Class iface, ClassLoader classLoader, Metadata metadata) { - return dsl(iface, classLoader, Optional.empty(), metadata); - } + public static E dsl(Class iface, ClassLoader classLoader, Metadata metadata) { + return dsl(iface, classLoader, Optional.empty(), metadata); + } - public static E dsl( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata) { + public static E dsl(Class iface, ClassLoader classLoader, Optional parent, + Metadata metadata) { - Object instance = null; + Object instance = null; - if (!parent.isPresent()) { - instance = dslCache.get(iface); - } + if (!parent.isPresent()) { + instance = dslCache.get(iface); + } - if (instance == null) { + if (instance == null) { - instance = settings.getDslInstantiator().instantiate(iface, classLoader, parent, metadata); + instance = settings.getDslInstantiator().instantiate(iface, classLoader, parent, metadata); - if (!parent.isPresent()) { + if (!parent.isPresent()) { - Object c = dslCache.putIfAbsent(iface, instance); - if (c != null) { - instance = c; - } - } - } + Object c = dslCache.putIfAbsent(iface, instance); + if (c != null) { + instance = c; + } + } + } - return (E) instance; - } + return (E) instance; + } - public static E map(Class iface, Map src) { - return map(iface, src, iface.getClassLoader()); - } + public static E map(Class iface, Map src) { + return map(iface, src, iface.getClassLoader()); + } - public static E map(Class iface, Map src, ClassLoader classLoader) { - return settings.getMapperInstantiator().instantiate(iface, src, classLoader); - } + public static E map(Class iface, Map src, ClassLoader classLoader) { + return settings.getMapperInstantiator().instantiate(iface, src, classLoader); + } - public static HelenusEntity entity(Class iface) { - Metadata metadata = metadataForEntity.get(iface); - if (metadata == null) { - HelenusSession session = session(); - if (session != null) { - metadata = session.getMetadata(); - } - } - return entity(iface, metadata); - } + public static HelenusEntity entity(Class iface) { + Metadata metadata = metadataForEntity.get(iface); + if (metadata == null) { + HelenusSession session = session(); + if (session != null) { + metadata = session.getMetadata(); + } + } + return entity(iface, metadata); + } - public static HelenusEntity entity(Class iface, Metadata metadata) { + public static HelenusEntity entity(Class iface, Metadata metadata) { - Object dsl = dsl(iface, metadata); + Object dsl = dsl(iface, metadata); - DslExportable e = (DslExportable) dsl; + DslExportable e = (DslExportable) dsl; - return e.getHelenusMappingEntity(); - } + return e.getHelenusMappingEntity(); + } - public static HelenusEntity resolve(Object ifaceOrDsl) { - return resolve(ifaceOrDsl, metadataForEntity.get(ifaceOrDsl)); - } + public static HelenusEntity resolve(Object ifaceOrDsl) { + return resolve(ifaceOrDsl, metadataForEntity.get(ifaceOrDsl)); + } - public static HelenusEntity resolve(Object ifaceOrDsl, Metadata metadata) { + public static HelenusEntity resolve(Object ifaceOrDsl, Metadata metadata) { - if (ifaceOrDsl == null) { - throw new HelenusMappingException("ifaceOrDsl is null"); - } + if (ifaceOrDsl == null) { + throw new HelenusMappingException("ifaceOrDsl is null"); + } - if (ifaceOrDsl instanceof DslExportable) { + if (ifaceOrDsl instanceof DslExportable) { - DslExportable e = (DslExportable) ifaceOrDsl; + DslExportable e = (DslExportable) ifaceOrDsl; - return e.getHelenusMappingEntity(); - } + return e.getHelenusMappingEntity(); + } - if (ifaceOrDsl instanceof Class) { + if (ifaceOrDsl instanceof Class) { - Class iface = (Class) ifaceOrDsl; + Class iface = (Class) ifaceOrDsl; - if (!iface.isInterface()) { - throw new HelenusMappingException("class is not an interface " + iface); - } + if (!iface.isInterface()) { + throw new HelenusMappingException("class is not an interface " + iface); + } - metadataForEntity.putIfAbsent(iface, metadata); - return entity(iface, metadata); - } + if (metadata != null) { + metadataForEntity.putIfAbsent(iface, metadata); + } + return entity(iface, metadata); + } - throw new HelenusMappingException("unknown dsl object or mapping interface " + ifaceOrDsl); - } + throw new HelenusMappingException("unknown dsl object or mapping interface " + ifaceOrDsl); + } } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 601a773..b0b0fb1 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -17,22 +17,30 @@ package net.helenus.core; import static net.helenus.core.Query.eq; -import brave.Tracer; -import com.codahale.metrics.MetricRegistry; -import com.datastax.driver.core.*; import java.io.Closeable; import java.io.PrintStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.stream.Collectors; + +import com.codahale.metrics.MetricRegistry; +import com.datastax.driver.core.*; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.collect.Table; + +import brave.Tracer; +import net.helenus.core.cache.CacheUtil; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.UnboundFacet; import net.helenus.core.operation.*; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; +import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.value.*; @@ -46,577 +54,610 @@ import net.helenus.support.HelenusMappingException; public final class HelenusSession extends AbstractSessionOperations implements Closeable { - private final int MAX_CACHE_SIZE = 10000; - private final int MAX_CACHE_EXPIRE_SECONDS = 600; - - private final Session session; - private final CodecRegistry registry; - private volatile String usingKeyspace; - private volatile boolean showCql; - private final ConsistencyLevel defaultConsistencyLevel; - private final boolean defaultQueryIdempotency; - private final MetricRegistry metricRegistry; - private final Tracer zipkinTracer; - private final PrintStream printStream; - private final Class unitOfWorkClass; - private final SessionRepository sessionRepository; - private final Executor executor; - private final boolean dropSchemaOnClose; - - private final RowColumnValueProvider valueProvider; - private final StatementColumnValuePreparer valuePreparer; - private final Metadata metadata; - - HelenusSession( - Session session, - String usingKeyspace, - CodecRegistry registry, - boolean showCql, - PrintStream printStream, - SessionRepositoryBuilder sessionRepositoryBuilder, - Executor executor, - boolean dropSchemaOnClose, - ConsistencyLevel consistencyLevel, - boolean defaultQueryIdempotency, - Class unitOfWorkClass, - MetricRegistry metricRegistry, - Tracer tracer) { - this.session = session; - this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; - this.usingKeyspace = - Objects.requireNonNull( - usingKeyspace, "keyspace needs to be selected before creating session"); - this.showCql = showCql; - this.printStream = printStream; - this.sessionRepository = sessionRepositoryBuilder.build(); - this.executor = executor; - this.dropSchemaOnClose = dropSchemaOnClose; - this.defaultConsistencyLevel = consistencyLevel; - this.defaultQueryIdempotency = defaultQueryIdempotency; - this.unitOfWorkClass = unitOfWorkClass; - this.metricRegistry = metricRegistry; - this.zipkinTracer = tracer; - - this.valueProvider = new RowColumnValueProvider(this.sessionRepository); - this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); - this.metadata = session.getCluster().getMetadata(); - } - - @Override - public Session currentSession() { - return session; - } - - @Override - public String usingKeyspace() { - return usingKeyspace; - } - - public HelenusSession useKeyspace(String keyspace) { - session.execute(SchemaUtil.use(keyspace, false)); - this.usingKeyspace = keyspace; - return this; - } - - @Override - public boolean isShowCql() { - return showCql; - } - - @Override - public PrintStream getPrintStream() { - return printStream; - } - - public HelenusSession showCql() { - this.showCql = true; - return this; - } - - public HelenusSession showCql(boolean showCql) { - this.showCql = showCql; - return this; - } - - @Override - public Executor getExecutor() { - return executor; - } - - @Override - public SessionRepository getSessionRepository() { - return sessionRepository; - } - - @Override - public ColumnValueProvider getValueProvider() { - return valueProvider; - } - - @Override - public ColumnValuePreparer getValuePreparer() { - return valuePreparer; - } - - @Override - public Tracer getZipkinTracer() { - return zipkinTracer; - } - - @Override - public MetricRegistry getMetricRegistry() { - return metricRegistry; - } - - @Override - public ConsistencyLevel getDefaultConsistencyLevel() { - return defaultConsistencyLevel; - } - - @Override - public boolean getDefaultQueryIdempotency() { - return defaultQueryIdempotency; - } - - public Metadata getMetadata() { - return metadata; - } - - public synchronized UnitOfWork begin() { - return begin(null); - } - - public synchronized UnitOfWork begin(UnitOfWork parent) { - try { - Class clazz = unitOfWorkClass; - Constructor ctor = - clazz.getConstructor(HelenusSession.class, UnitOfWork.class); - UnitOfWork uow = ctor.newInstance(this, parent); - if (parent != null) { - parent.addNestedUnitOfWork(uow); - } - return uow.begin(); - } catch (NoSuchMethodException - | InvocationTargetException - | InstantiationException - | IllegalAccessException e) { - throw new HelenusException( - String.format( - "Unable to instantiate {} as a UnitOfWork.", unitOfWorkClass.getSimpleName()), - e); - } - } - - public SelectOperation select(E pojo) { - Objects.requireNonNull( - pojo, "supplied object must be a dsl for a registered entity but cannot be null"); - ColumnValueProvider valueProvider = getValueProvider(); - HelenusEntity entity = Helenus.resolve(pojo); - Class entityClass = entity.getMappingInterface(); - - return new SelectOperation( - this, - entity, - (r) -> { - Map map = new ValueProviderMap(r, valueProvider, entity); - return (E) Helenus.map(entityClass, map); - }); - } - - public SelectOperation select(Class entityClass) { - Objects.requireNonNull(entityClass, "entityClass is empty"); - ColumnValueProvider valueProvider = getValueProvider(); - HelenusEntity entity = Helenus.entity(entityClass); - - return new SelectOperation( - this, - entity, - (r) -> { - Map map = new ValueProviderMap(r, valueProvider, entity); - return (E) Helenus.map(entityClass, map); - }); - } - - public SelectOperation select() { - return new SelectOperation(this); - } - - public SelectOperation selectAll(Class entityClass) { - Objects.requireNonNull(entityClass, "entityClass is empty"); - return new SelectOperation(this, Helenus.entity(entityClass)); - } - - public SelectOperation selectAll(E pojo) { - Objects.requireNonNull( - pojo, "supplied object must be a dsl for a registered entity but cannot be null"); - HelenusEntity entity = Helenus.resolve(pojo); - return new SelectOperation(this, entity); - } - - public SelectOperation selectAll(Class entityClass, Function rowMapper) { - Objects.requireNonNull(entityClass, "entityClass is empty"); - Objects.requireNonNull(rowMapper, "rowMapper is empty"); - return new SelectOperation(this, Helenus.entity(entityClass), rowMapper); - } - - public SelectOperation> select(Getter getter1) { - Objects.requireNonNull(getter1, "field 1 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - return new SelectOperation>( - this, new Mappers.Mapper1(getValueProvider(), p1), p1); - } - - public SelectOperation> select(Getter getter1, Getter getter2) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - return new SelectOperation>( - this, new Mappers.Mapper2(getValueProvider(), p1, p2), p1, p2); - } - - public SelectOperation> select( - Getter getter1, Getter getter2, Getter getter3) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - return new SelectOperation>( - this, new Mappers.Mapper3(getValueProvider(), p1, p2, p3), p1, p2, p3); - } - - public SelectOperation> select( - Getter getter1, Getter getter2, Getter getter3, Getter getter4) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - return new SelectOperation>( - this, - new Mappers.Mapper4(getValueProvider(), p1, p2, p3, p4), - p1, - p2, - p3, - p4); - } - - public SelectOperation> select( - Getter getter1, - Getter getter2, - Getter getter3, - Getter getter4, - Getter getter5) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - Objects.requireNonNull(getter5, "field 5 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); - return new SelectOperation>( - this, - new Mappers.Mapper5(getValueProvider(), p1, p2, p3, p4, p5), - p1, - p2, - p3, - p4, - p5); - } - - public SelectOperation> select( - Getter getter1, - Getter getter2, - Getter getter3, - Getter getter4, - Getter getter5, - Getter getter6) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - Objects.requireNonNull(getter5, "field 5 is empty"); - Objects.requireNonNull(getter6, "field 6 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); - HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); - return new SelectOperation>( - this, - new Mappers.Mapper6(getValueProvider(), p1, p2, p3, p4, p5, p6), - p1, - p2, - p3, - p4, - p5, - p6); - } - - public - SelectOperation> select( - Getter getter1, - Getter getter2, - Getter getter3, - Getter getter4, - Getter getter5, - Getter getter6, - Getter getter7) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - Objects.requireNonNull(getter5, "field 5 is empty"); - Objects.requireNonNull(getter6, "field 6 is empty"); - Objects.requireNonNull(getter7, "field 7 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); - HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); - HelenusPropertyNode p7 = MappingUtil.resolveMappingProperty(getter7); - return new SelectOperation>( - this, - new Mappers.Mapper7( - getValueProvider(), p1, p2, p3, p4, p5, p6, p7), - p1, - p2, - p3, - p4, - p5, - p6, - p7); - } - - public CountOperation count() { - return new CountOperation(this); - } - - public CountOperation count(Object dsl) { - Objects.requireNonNull(dsl, "dsl is empty"); - return new CountOperation(this, Helenus.resolve(dsl)); - } - - public UpdateOperation update() { - return new UpdateOperation(this); - } - - public UpdateOperation update(Drafted drafted) { - if (drafted instanceof AbstractEntityDraft == false) { - throw new HelenusMappingException( - "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); - } - AbstractEntityDraft draft = (AbstractEntityDraft) drafted; - UpdateOperation update = new UpdateOperation(this, draft); - Map map = draft.toMap(); - Set mutatedProperties = draft.mutated(); - HelenusEntity entity = Helenus.entity(draft.getEntityClass()); - - // Add all the mutated values contained in the draft. - entity - .getOrderedProperties() - .forEach( - property -> { - switch (property.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - break; - default: - String propertyName = property.getPropertyName(); - if (mutatedProperties.contains(propertyName)) { - Object value = map.get(propertyName); - Getter getter = - new Getter() { - @Override - public Object get() { - throw new DslPropertyException( - new HelenusPropertyNode(property, Optional.empty())); - } - }; - update.set(getter, value); - } - } - }); - - // Add the partition and clustering keys if they were in the draft (normally the case). - entity - .getOrderedProperties() - .forEach( - property -> { - switch (property.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - String propertyName = property.getPropertyName(); - Object value = map.get(propertyName); - Getter getter = - new Getter() { - @Override - public Object get() { - throw new DslPropertyException( - new HelenusPropertyNode(property, Optional.empty())); - } - }; - update.where(getter, eq(value)); - } - }); - - return update; - } - - public UpdateOperation update(Getter getter, V v) { - Objects.requireNonNull(getter, "field is empty"); - Objects.requireNonNull(v, "value is empty"); - - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); - - return new UpdateOperation(this, p, v); - } - - public InsertOperation insert() { - return new InsertOperation(this, true); - } - - public InsertOperation insert(Class resultType) { - return new InsertOperation(this, resultType, true); - } - - public InsertOperation insert(T pojo) { - Objects.requireNonNull( - pojo, - "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); - HelenusEntity entity = null; - try { - entity = Helenus.resolve(pojo); - } catch (HelenusMappingException e) { - } - if (entity != null) { - return new InsertOperation(this, entity.getMappingInterface(), true); - } else { - return this.insert(pojo, null); - } - } - - public InsertOperation insert(Drafted draft) { - return insert(draft.build(), draft.mutated()); - } - - private InsertOperation insert(T pojo, Set mutations) { - Objects.requireNonNull(pojo, "pojo is empty"); - - Class iface = MappingUtil.getMappingInterface(pojo); - HelenusEntity entity = Helenus.entity(iface); - - return new InsertOperation(this, entity, pojo, mutations, true); - } - - public InsertOperation upsert() { - return new InsertOperation(this, false); - } - - public InsertOperation upsert(Class resultType) { - return new InsertOperation(this, resultType, false); - } - - public InsertOperation upsert(Drafted draft) { - return this.upsert((T) draft.build(), draft.mutated()); - } - - public InsertOperation upsert(T pojo) { - Objects.requireNonNull( - pojo, - "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); - HelenusEntity entity = null; - try { - entity = Helenus.resolve(pojo); - } catch (HelenusMappingException e) { - } - if (entity != null) { - return new InsertOperation(this, entity.getMappingInterface(), false); - } else { - return this.upsert(pojo, null); - } - } - - private InsertOperation upsert(T pojo, Set mutations) { - Objects.requireNonNull(pojo, "pojo is empty"); - - Class iface = MappingUtil.getMappingInterface(pojo); - HelenusEntity entity = Helenus.entity(iface); - - return new InsertOperation(this, entity, pojo, mutations, false); - } - - public DeleteOperation delete() { - return new DeleteOperation(this); - } - - public DeleteOperation delete(Object dsl) { - Objects.requireNonNull(dsl, "dsl is empty"); - return new DeleteOperation(this, Helenus.resolve(dsl)); - } - - public Session getSession() { - return session; - } - - public E dsl(Class iface) { - return Helenus.dsl(iface, getMetadata()); - } - - public void close() { - - if (session.isClosed()) { - return; - } - - if (dropSchemaOnClose) { - dropSchema(); - } - - session.close(); - } - - public CloseFuture closeAsync() { - - if (!session.isClosed() && dropSchemaOnClose) { - dropSchema(); - } - - return session.closeAsync(); - } - - private void dropSchema() { - - sessionRepository.entities().forEach(e -> dropEntity(e)); - } - - private void dropEntity(HelenusEntity entity) { + private final int MAX_CACHE_SIZE = 10000; + private final int MAX_CACHE_EXPIRE_SECONDS = 600; + + private final Session session; + private final CodecRegistry registry; + private final ConsistencyLevel defaultConsistencyLevel; + private final boolean defaultQueryIdempotency; + private final MetricRegistry metricRegistry; + private final Tracer zipkinTracer; + private final PrintStream printStream; + private final Class unitOfWorkClass; + private final SessionRepository sessionRepository; + private final Executor executor; + private final boolean dropSchemaOnClose; + private final Cache sessionCache; + private final RowColumnValueProvider valueProvider; + private final StatementColumnValuePreparer valuePreparer; + private final Metadata metadata; + private volatile String usingKeyspace; + private volatile boolean showCql; + + HelenusSession(Session session, String usingKeyspace, CodecRegistry registry, boolean showCql, + PrintStream printStream, SessionRepositoryBuilder sessionRepositoryBuilder, Executor executor, + boolean dropSchemaOnClose, ConsistencyLevel consistencyLevel, boolean defaultQueryIdempotency, + Class unitOfWorkClass, MetricRegistry metricRegistry, Tracer tracer) { + this.session = session; + this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; + this.usingKeyspace = Objects.requireNonNull(usingKeyspace, + "keyspace needs to be selected before creating session"); + this.showCql = showCql; + this.printStream = printStream; + this.sessionRepository = sessionRepositoryBuilder.build(); + this.executor = executor; + this.dropSchemaOnClose = dropSchemaOnClose; + this.defaultConsistencyLevel = consistencyLevel; + this.defaultQueryIdempotency = defaultQueryIdempotency; + this.unitOfWorkClass = unitOfWorkClass; + this.metricRegistry = metricRegistry; + this.zipkinTracer = tracer; + + this.sessionCache = CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) + .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build(); + + this.valueProvider = new RowColumnValueProvider(this.sessionRepository); + this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); + this.metadata = session.getCluster().getMetadata(); + } + + @Override + public Session currentSession() { + return session; + } + + @Override + public String usingKeyspace() { + return usingKeyspace; + } + + public HelenusSession useKeyspace(String keyspace) { + session.execute(SchemaUtil.use(keyspace, false)); + this.usingKeyspace = keyspace; + return this; + } + + @Override + public boolean isShowCql() { + return showCql; + } + + @Override + public PrintStream getPrintStream() { + return printStream; + } + + public HelenusSession showCql() { + this.showCql = true; + return this; + } + + public HelenusSession showCql(boolean showCql) { + this.showCql = showCql; + return this; + } + + @Override + public Executor getExecutor() { + return executor; + } + + @Override + public SessionRepository getSessionRepository() { + return sessionRepository; + } + + @Override + public ColumnValueProvider getValueProvider() { + return valueProvider; + } + + @Override + public ColumnValuePreparer getValuePreparer() { + return valuePreparer; + } + + @Override + public Tracer getZipkinTracer() { + return zipkinTracer; + } + + @Override + public MetricRegistry getMetricRegistry() { + return metricRegistry; + } + + @Override + public ConsistencyLevel getDefaultConsistencyLevel() { + return defaultConsistencyLevel; + } + + @Override + public boolean getDefaultQueryIdempotency() { + return defaultQueryIdempotency; + } + + @Override + public Object checkCache(String tableName, List facets) { + List facetCombinations = CacheUtil.flattenFacets(facets); + Object result = null; + for (String[] combination : facetCombinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + result = sessionCache.getIfPresent(cacheKey); + if (result != null) { + return result; + } + } + return null; + } + + @Override + public void updateCache(Object pojo, List facets) { + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + List boundFacets = new ArrayList<>(); + for (Facet facet : facets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + String tableName = CacheUtil.schemaName(facets); + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + Object value = sessionCache.getIfPresent(pojo); + Object mergedValue = null; + for (String[] combination : facetCombinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + if (value == null) { + sessionCache.put(cacheKey, pojo); + } else { + if (mergedValue == null) { + mergedValue = pojo; + } else { + mergedValue = CacheUtil.merge(value, pojo); + } + sessionCache.put(mergedValue, pojo); + } + } + + } + + @Override + public void mergeCache(Table uowCache) { + List pojos = uowCache.values().stream().distinct().collect(Collectors.toList()); + for (Object pojo : pojos) { + HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + if (entity.isCacheable()) { + List boundFacets = new ArrayList<>(); + for (Facet facet : entity.getFacets()) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + String tableName = entity.getName().toCql(); + // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + Object value = sessionCache.getIfPresent(pojo); + Object mergedValue = null; + for (String[] combination : facetCombinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + if (value == null) { + sessionCache.put(cacheKey, pojo); + } else { + if (mergedValue == null) { + mergedValue = pojo; + } else { + mergedValue = CacheUtil.merge(value, pojo); + } + sessionCache.put(mergedValue, pojo); + } + } + } + } + } + + public Metadata getMetadata() { + return metadata; + } + + public synchronized UnitOfWork begin() { + return begin(null); + } + + public synchronized UnitOfWork begin(UnitOfWork parent) { + try { + Class clazz = unitOfWorkClass; + Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); + UnitOfWork uow = ctor.newInstance(this, parent); + if (parent != null) { + parent.addNestedUnitOfWork(uow); + } + return uow.begin(); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException + | IllegalAccessException e) { + throw new HelenusException( + String.format("Unable to instantiate {} as a UnitOfWork.", unitOfWorkClass.getSimpleName()), e); + } + } + + public SelectOperation select(E pojo) { + Objects.requireNonNull(pojo, "supplied object must be a dsl for a registered entity but cannot be null"); + ColumnValueProvider valueProvider = getValueProvider(); + HelenusEntity entity = Helenus.resolve(pojo); + Class entityClass = entity.getMappingInterface(); + + return new SelectOperation(this, entity, (r) -> { + Map map = new ValueProviderMap(r, valueProvider, entity); + return (E) Helenus.map(entityClass, map); + }); + } + + public SelectOperation select(Class entityClass) { + Objects.requireNonNull(entityClass, "entityClass is empty"); + ColumnValueProvider valueProvider = getValueProvider(); + HelenusEntity entity = Helenus.entity(entityClass); + + return new SelectOperation(this, entity, (r) -> { + Map map = new ValueProviderMap(r, valueProvider, entity); + return (E) Helenus.map(entityClass, map); + }); + } + + public SelectOperation select() { + return new SelectOperation(this); + } + + public SelectOperation selectAll(Class entityClass) { + Objects.requireNonNull(entityClass, "entityClass is empty"); + return new SelectOperation(this, Helenus.entity(entityClass)); + } + + public SelectOperation selectAll(E pojo) { + Objects.requireNonNull(pojo, "supplied object must be a dsl for a registered entity but cannot be null"); + HelenusEntity entity = Helenus.resolve(pojo); + return new SelectOperation(this, entity); + } + + public SelectOperation selectAll(Class entityClass, Function rowMapper) { + Objects.requireNonNull(entityClass, "entityClass is empty"); + Objects.requireNonNull(rowMapper, "rowMapper is empty"); + return new SelectOperation(this, Helenus.entity(entityClass), rowMapper); + } + + public SelectOperation> select(Getter getter1) { + Objects.requireNonNull(getter1, "field 1 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + return new SelectOperation>(this, new Mappers.Mapper1(getValueProvider(), p1), p1); + } + + public SelectOperation> select(Getter getter1, Getter getter2) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + return new SelectOperation>(this, new Mappers.Mapper2(getValueProvider(), p1, p2), + p1, p2); + } + + public SelectOperation> select(Getter getter1, Getter getter2, + Getter getter3) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + return new SelectOperation>(this, + new Mappers.Mapper3(getValueProvider(), p1, p2, p3), p1, p2, p3); + } + + public SelectOperation> select(Getter getter1, Getter getter2, + Getter getter3, Getter getter4) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + return new SelectOperation>(this, + new Mappers.Mapper4(getValueProvider(), p1, p2, p3, p4), p1, p2, p3, p4); + } + + public SelectOperation> select(Getter getter1, + Getter getter2, Getter getter3, Getter getter4, Getter getter5) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + Objects.requireNonNull(getter5, "field 5 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); + return new SelectOperation>(this, + new Mappers.Mapper5(getValueProvider(), p1, p2, p3, p4, p5), p1, p2, p3, p4, p5); + } + + public SelectOperation> select(Getter getter1, + Getter getter2, Getter getter3, Getter getter4, Getter getter5, Getter getter6) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + Objects.requireNonNull(getter5, "field 5 is empty"); + Objects.requireNonNull(getter6, "field 6 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); + HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); + return new SelectOperation>(this, + new Mappers.Mapper6(getValueProvider(), p1, p2, p3, p4, p5, p6), p1, p2, p3, p4, + p5, p6); + } + + public SelectOperation> select( + Getter getter1, Getter getter2, Getter getter3, Getter getter4, Getter getter5, + Getter getter6, Getter getter7) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + Objects.requireNonNull(getter5, "field 5 is empty"); + Objects.requireNonNull(getter6, "field 6 is empty"); + Objects.requireNonNull(getter7, "field 7 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); + HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); + HelenusPropertyNode p7 = MappingUtil.resolveMappingProperty(getter7); + return new SelectOperation>(this, + new Mappers.Mapper7(getValueProvider(), p1, p2, p3, p4, p5, p6, p7), p1, p2, + p3, p4, p5, p6, p7); + } + + public CountOperation count() { + return new CountOperation(this); + } + + public CountOperation count(Object dsl) { + Objects.requireNonNull(dsl, "dsl is empty"); + return new CountOperation(this, Helenus.resolve(dsl)); + } + + public UpdateOperation update() { + return new UpdateOperation(this); + } + + public UpdateOperation update(Drafted drafted) { + if (drafted instanceof AbstractEntityDraft == false) { + throw new HelenusMappingException( + "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); + } + AbstractEntityDraft draft = (AbstractEntityDraft) drafted; + UpdateOperation update = new UpdateOperation(this, draft); + Map map = draft.toMap(); + Set mutatedProperties = draft.mutated(); + HelenusEntity entity = Helenus.entity(draft.getEntityClass()); + + // Add all the mutated values contained in the draft. + entity.getOrderedProperties().forEach(property -> { + switch (property.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + break; + default : + String propertyName = property.getPropertyName(); + if (mutatedProperties.contains(propertyName)) { + Object value = map.get(propertyName); + Getter getter = new Getter() { + @Override + public Object get() { + throw new DslPropertyException(new HelenusPropertyNode(property, Optional.empty())); + } + }; + update.set(getter, value); + } + } + }); + + // Add the partition and clustering keys if they were in the draft (normally the + // case). + entity.getOrderedProperties().forEach(property -> { + switch (property.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + String propertyName = property.getPropertyName(); + Object value = map.get(propertyName); + Getter getter = new Getter() { + @Override + public Object get() { + throw new DslPropertyException(new HelenusPropertyNode(property, Optional.empty())); + } + }; + update.where(getter, eq(value)); + } + }); + + return update; + } + + public UpdateOperation update(Getter getter, V v) { + Objects.requireNonNull(getter, "field is empty"); + Objects.requireNonNull(v, "value is empty"); + + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); + + return new UpdateOperation(this, p, v); + } + + public InsertOperation insert() { + return new InsertOperation(this, true); + } + + public InsertOperation insert(Class resultType) { + return new InsertOperation(this, resultType, true); + } + + public InsertOperation insert(T pojo) { + Objects.requireNonNull(pojo, + "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); + HelenusEntity entity = null; + try { + entity = Helenus.resolve(pojo); + } catch (HelenusMappingException e) { + } + if (entity != null) { + return new InsertOperation(this, entity.getMappingInterface(), true); + } else { + return this.insert(pojo, null); + } + } + + public InsertOperation insert(Drafted draft) { + return insert(draft.build(), draft.mutated()); + } + + private InsertOperation insert(T pojo, Set mutations) { + Objects.requireNonNull(pojo, "pojo is empty"); + + Class iface = MappingUtil.getMappingInterface(pojo); + HelenusEntity entity = Helenus.entity(iface); + + return new InsertOperation(this, entity, pojo, mutations, true); + } + + public InsertOperation upsert() { + return new InsertOperation(this, false); + } + + public InsertOperation upsert(Class resultType) { + return new InsertOperation(this, resultType, false); + } + + public InsertOperation upsert(Drafted draft) { + return this.upsert((T) draft.build(), draft.mutated()); + } + + public InsertOperation upsert(T pojo) { + Objects.requireNonNull(pojo, + "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); + HelenusEntity entity = null; + try { + entity = Helenus.resolve(pojo); + } catch (HelenusMappingException e) { + } + if (entity != null) { + return new InsertOperation(this, entity.getMappingInterface(), false); + } else { + return this.upsert(pojo, null); + } + } + + private InsertOperation upsert(T pojo, Set mutations) { + Objects.requireNonNull(pojo, "pojo is empty"); + + Class iface = MappingUtil.getMappingInterface(pojo); + HelenusEntity entity = Helenus.entity(iface); + + return new InsertOperation(this, entity, pojo, mutations, false); + } + + public DeleteOperation delete() { + return new DeleteOperation(this); + } + + public DeleteOperation delete(Object dsl) { + Objects.requireNonNull(dsl, "dsl is empty"); + return new DeleteOperation(this, Helenus.resolve(dsl)); + } + + public Session getSession() { + return session; + } + + public E dsl(Class iface) { + return Helenus.dsl(iface, getMetadata()); + } + + public void close() { + + if (session.isClosed()) { + return; + } + + if (dropSchemaOnClose) { + dropSchema(); + } + + session.close(); + } + + public CloseFuture closeAsync() { + + if (!session.isClosed() && dropSchemaOnClose) { + dropSchema(); + } + + return session.closeAsync(); + } + + private void dropSchema() { + + sessionRepository.entities().forEach(e -> dropEntity(e)); + } + + private void dropEntity(HelenusEntity entity) { - switch (entity.getType()) { - case TABLE: - execute(SchemaUtil.dropTable(entity), true); - break; + switch (entity.getType()) { + case TABLE : + execute(SchemaUtil.dropTable(entity), true); + break; - case UDT: - execute(SchemaUtil.dropUserType(entity), true); - break; - } - } + case UDT : + execute(SchemaUtil.dropUserType(entity), true); + break; + } + } } diff --git a/src/main/java/net/helenus/core/HelenusValidator.java b/src/main/java/net/helenus/core/HelenusValidator.java index b0087f4..1e75544 100644 --- a/src/main/java/net/helenus/core/HelenusValidator.java +++ b/src/main/java/net/helenus/core/HelenusValidator.java @@ -16,32 +16,33 @@ package net.helenus.core; import java.lang.annotation.Annotation; + import javax.validation.ConstraintValidator; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; public enum HelenusValidator implements PropertyValueValidator { - INSTANCE; + INSTANCE; - public void validate(HelenusProperty prop, Object value) { + public void validate(HelenusProperty prop, Object value) { - for (ConstraintValidator validator : prop.getValidators()) { + for (ConstraintValidator validator : prop.getValidators()) { - ConstraintValidator typeless = (ConstraintValidator) validator; + ConstraintValidator typeless = (ConstraintValidator) validator; - boolean valid = false; + boolean valid = false; - try { - valid = typeless.isValid(value, null); - } catch (ClassCastException e) { - throw new HelenusMappingException( - "validator was used for wrong type '" + value + "' in " + prop, e); - } + try { + valid = typeless.isValid(value, null); + } catch (ClassCastException e) { + throw new HelenusMappingException("validator was used for wrong type '" + value + "' in " + prop, e); + } - if (!valid) { - throw new HelenusException("wrong value '" + value + "' for " + prop); - } - } - } + if (!valid) { + throw new HelenusException("wrong value '" + value + "' for " + prop); + } + } + } } diff --git a/src/main/java/net/helenus/core/MapperInstantiator.java b/src/main/java/net/helenus/core/MapperInstantiator.java index 70d4082..c16b4a1 100644 --- a/src/main/java/net/helenus/core/MapperInstantiator.java +++ b/src/main/java/net/helenus/core/MapperInstantiator.java @@ -19,5 +19,5 @@ import java.util.Map; public interface MapperInstantiator { - E instantiate(Class iface, Map src, ClassLoader classLoader); + E instantiate(Class iface, Map src, ClassLoader classLoader); } diff --git a/src/main/java/net/helenus/core/Mappers.java b/src/main/java/net/helenus/core/Mappers.java index 4dc26b1..d774d7f 100644 --- a/src/main/java/net/helenus/core/Mappers.java +++ b/src/main/java/net/helenus/core/Mappers.java @@ -15,8 +15,10 @@ */ package net.helenus.core; -import com.datastax.driver.core.Row; import java.util.function.Function; + +import com.datastax.driver.core.Row; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.value.ColumnValueProvider; @@ -24,203 +26,161 @@ import net.helenus.support.Fun; public final class Mappers { - private Mappers() {} + private Mappers() { + } - public static final class Mapper1 implements Function> { + public static final class Mapper1 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; + private final ColumnValueProvider provider; + private final HelenusProperty p1; - public Mapper1(ColumnValueProvider provider, HelenusPropertyNode p1) { - this.provider = provider; - this.p1 = p1.getProperty(); - } + public Mapper1(ColumnValueProvider provider, HelenusPropertyNode p1) { + this.provider = provider; + this.p1 = p1.getProperty(); + } - @Override - public Fun.Tuple1 apply(Row row) { - return new Fun.Tuple1(provider.getColumnValue(row, 0, p1)); - } - } + @Override + public Fun.Tuple1 apply(Row row) { + return new Fun.Tuple1(provider.getColumnValue(row, 0, p1)); + } + } - public static final class Mapper2 implements Function> { + public static final class Mapper2 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; - private final HelenusProperty p2; + private final ColumnValueProvider provider; + private final HelenusProperty p1; + private final HelenusProperty p2; - public Mapper2(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - } + public Mapper2(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + } - @Override - public Fun.Tuple2 apply(Row row) { - return new Fun.Tuple2( - provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2)); - } - } + @Override + public Fun.Tuple2 apply(Row row) { + return new Fun.Tuple2(provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2)); + } + } - public static final class Mapper3 implements Function> { + public static final class Mapper3 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; - private final HelenusProperty p2; - private final HelenusProperty p3; + private final ColumnValueProvider provider; + private final HelenusProperty p1; + private final HelenusProperty p2; + private final HelenusProperty p3; - public Mapper3( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - } + public Mapper3(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + } - @Override - public Fun.Tuple3 apply(Row row) { - return new Fun.Tuple3( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3)); - } - } + @Override + public Fun.Tuple3 apply(Row row) { + return new Fun.Tuple3(provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2), + provider.getColumnValue(row, 2, p3)); + } + } - public static final class Mapper4 implements Function> { + public static final class Mapper4 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; - private final HelenusProperty p2; - private final HelenusProperty p3; - private final HelenusProperty p4; + private final ColumnValueProvider provider; + private final HelenusProperty p1; + private final HelenusProperty p2; + private final HelenusProperty p3; + private final HelenusProperty p4; - public Mapper4( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - } + public Mapper4(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + } - @Override - public Fun.Tuple4 apply(Row row) { - return new Fun.Tuple4( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4)); - } - } + @Override + public Fun.Tuple4 apply(Row row) { + return new Fun.Tuple4(provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2), + provider.getColumnValue(row, 2, p3), provider.getColumnValue(row, 3, p4)); + } + } - public static final class Mapper5 - implements Function> { + public static final class Mapper5 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1, p2, p3, p4, p5; + private final ColumnValueProvider provider; + private final HelenusProperty p1, p2, p3, p4, p5; - public Mapper5( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4, - HelenusPropertyNode p5) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - this.p5 = p5.getProperty(); - } + public Mapper5(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4, HelenusPropertyNode p5) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + this.p5 = p5.getProperty(); + } - @Override - public Fun.Tuple5 apply(Row row) { - return new Fun.Tuple5( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4), - provider.getColumnValue(row, 4, p5)); - } - } + @Override + public Fun.Tuple5 apply(Row row) { + return new Fun.Tuple5(provider.getColumnValue(row, 0, p1), + provider.getColumnValue(row, 1, p2), provider.getColumnValue(row, 2, p3), + provider.getColumnValue(row, 3, p4), provider.getColumnValue(row, 4, p5)); + } + } - public static final class Mapper6 - implements Function> { + public static final class Mapper6 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1, p2, p3, p4, p5, p6; + private final ColumnValueProvider provider; + private final HelenusProperty p1, p2, p3, p4, p5, p6; - public Mapper6( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4, - HelenusPropertyNode p5, - HelenusPropertyNode p6) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - this.p5 = p5.getProperty(); - this.p6 = p6.getProperty(); - } + public Mapper6(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4, HelenusPropertyNode p5, HelenusPropertyNode p6) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + this.p5 = p5.getProperty(); + this.p6 = p6.getProperty(); + } - @Override - public Fun.Tuple6 apply(Row row) { - return new Fun.Tuple6( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4), - provider.getColumnValue(row, 4, p5), - provider.getColumnValue(row, 5, p6)); - } - } + @Override + public Fun.Tuple6 apply(Row row) { + return new Fun.Tuple6(provider.getColumnValue(row, 0, p1), + provider.getColumnValue(row, 1, p2), provider.getColumnValue(row, 2, p3), + provider.getColumnValue(row, 3, p4), provider.getColumnValue(row, 4, p5), + provider.getColumnValue(row, 5, p6)); + } + } - public static final class Mapper7 - implements Function> { + public static final class Mapper7 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1, p2, p3, p4, p5, p6, p7; + private final ColumnValueProvider provider; + private final HelenusProperty p1, p2, p3, p4, p5, p6, p7; - public Mapper7( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4, - HelenusPropertyNode p5, - HelenusPropertyNode p6, - HelenusPropertyNode p7) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - this.p5 = p5.getProperty(); - this.p6 = p6.getProperty(); - this.p7 = p7.getProperty(); - } + public Mapper7(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4, HelenusPropertyNode p5, HelenusPropertyNode p6, + HelenusPropertyNode p7) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + this.p5 = p5.getProperty(); + this.p6 = p6.getProperty(); + this.p7 = p7.getProperty(); + } - @Override - public Fun.Tuple7 apply(Row row) { - return new Fun.Tuple7( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4), - provider.getColumnValue(row, 4, p5), - provider.getColumnValue(row, 5, p6), - provider.getColumnValue(row, 6, p7)); - } - } + @Override + public Fun.Tuple7 apply(Row row) { + return new Fun.Tuple7(provider.getColumnValue(row, 0, p1), + provider.getColumnValue(row, 1, p2), provider.getColumnValue(row, 2, p3), + provider.getColumnValue(row, 3, p4), provider.getColumnValue(row, 4, p5), + provider.getColumnValue(row, 5, p6), provider.getColumnValue(row, 6, p7)); + } + } } diff --git a/src/main/java/net/helenus/core/Operator.java b/src/main/java/net/helenus/core/Operator.java index bdff51c..3d249ad 100644 --- a/src/main/java/net/helenus/core/Operator.java +++ b/src/main/java/net/helenus/core/Operator.java @@ -19,37 +19,37 @@ import java.util.HashMap; import java.util.Map; public enum Operator { - EQ("=="), + EQ("=="), - IN("in"), + IN("in"), - GT(">"), + GT(">"), - LT("<"), + LT("<"), - GTE(">="), + GTE(">="), - LTE("<="); + LTE("<="); - private final String name; + private static final Map indexByName = new HashMap(); - private static final Map indexByName = new HashMap(); + static { + for (Operator fo : Operator.values()) { + indexByName.put(fo.getName(), fo); + } + } - static { - for (Operator fo : Operator.values()) { - indexByName.put(fo.getName(), fo); - } - } + private final String name; - private Operator(String name) { - this.name = name; - } + private Operator(String name) { + this.name = name; + } - public String getName() { - return name; - } + public static Operator findByOperator(String name) { + return indexByName.get(name); + } - public static Operator findByOperator(String name) { - return indexByName.get(name); - } + public String getName() { + return name; + } } diff --git a/src/main/java/net/helenus/core/Ordered.java b/src/main/java/net/helenus/core/Ordered.java index ac426aa..e86b293 100644 --- a/src/main/java/net/helenus/core/Ordered.java +++ b/src/main/java/net/helenus/core/Ordered.java @@ -1,8 +1,10 @@ package net.helenus.core; +import java.util.Objects; + import com.datastax.driver.core.querybuilder.Ordering; import com.datastax.driver.core.querybuilder.QueryBuilder; -import java.util.Objects; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.ColumnType; import net.helenus.mapping.MappingUtil; @@ -11,34 +13,34 @@ import net.helenus.support.HelenusMappingException; public final class Ordered { - private final Getter getter; - private final OrderingDirection direction; + private final Getter getter; + private final OrderingDirection direction; - public Ordered(Getter getter, OrderingDirection direction) { - this.getter = getter; - this.direction = direction; - } + public Ordered(Getter getter, OrderingDirection direction) { + this.getter = getter; + this.direction = direction; + } - public Ordering getOrdering() { + public Ordering getOrdering() { - Objects.requireNonNull(getter, "property is null"); - Objects.requireNonNull(direction, "direction is null"); + Objects.requireNonNull(getter, "property is null"); + Objects.requireNonNull(direction, "direction is null"); - HelenusPropertyNode propNode = MappingUtil.resolveMappingProperty(getter); + HelenusPropertyNode propNode = MappingUtil.resolveMappingProperty(getter); - if (propNode.getProperty().getColumnType() != ColumnType.CLUSTERING_COLUMN) { - throw new HelenusMappingException( - "property must be a clustering column " + propNode.getProperty().getPropertyName()); - } + if (propNode.getProperty().getColumnType() != ColumnType.CLUSTERING_COLUMN) { + throw new HelenusMappingException( + "property must be a clustering column " + propNode.getProperty().getPropertyName()); + } - switch (direction) { - case ASC: - return QueryBuilder.asc(propNode.getColumnName()); + switch (direction) { + case ASC : + return QueryBuilder.asc(propNode.getColumnName()); - case DESC: - return QueryBuilder.desc(propNode.getColumnName()); - } + case DESC : + return QueryBuilder.desc(propNode.getColumnName()); + } - throw new HelenusMappingException("invalid direction " + direction); - } + throw new HelenusMappingException("invalid direction " + direction); + } } diff --git a/src/main/java/net/helenus/core/PostCommitFunction.java b/src/main/java/net/helenus/core/PostCommitFunction.java index 3ba2b8b..a859608 100644 --- a/src/main/java/net/helenus/core/PostCommitFunction.java +++ b/src/main/java/net/helenus/core/PostCommitFunction.java @@ -1,29 +1,29 @@ package net.helenus.core; -import java.util.*; +import java.util.List; import java.util.Objects; public class PostCommitFunction implements java.util.function.Function { - private final UnitOfWork uow; - private final List postCommit; + private final UnitOfWork uow; + private final List postCommit; - PostCommitFunction(UnitOfWork uow, List postCommit) { - this.uow = uow; - this.postCommit = postCommit; - } + PostCommitFunction(UnitOfWork uow, List postCommit) { + this.uow = uow; + this.postCommit = postCommit; + } - public void andThen(CommitThunk after) { - Objects.requireNonNull(after); - if (postCommit == null) { - after.apply(); - } else { - postCommit.add(after); - } - } + public void andThen(CommitThunk after) { + Objects.requireNonNull(after); + if (postCommit == null) { + after.apply(); + } else { + postCommit.add(after); + } + } - @Override - public R apply(T t) { - return null; - } + @Override + public R apply(T t) { + return null; + } } diff --git a/src/main/java/net/helenus/core/Postulate.java b/src/main/java/net/helenus/core/Postulate.java index e0c8cf6..05e9f57 100644 --- a/src/main/java/net/helenus/core/Postulate.java +++ b/src/main/java/net/helenus/core/Postulate.java @@ -17,80 +17,85 @@ package net.helenus.core; import com.datastax.driver.core.querybuilder.Clause; import com.datastax.driver.core.querybuilder.QueryBuilder; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.value.ColumnValuePreparer; import net.helenus.support.HelenusMappingException; public final class Postulate { - private final Operator operator; - private final V[] values; + private final Operator operator; + private final V[] values; - protected Postulate(Operator op, V[] values) { - this.operator = op; - this.values = values; - } + protected Postulate(Operator op, V[] values) { + this.operator = op; + this.values = values; + } - public static Postulate of(Operator op, V... values) { - return new Postulate(op, values); - } + public static Postulate of(Operator op, V... values) { + return new Postulate(op, values); + } - public Clause getClause(HelenusPropertyNode node, ColumnValuePreparer valuePreparer) { + public Clause getClause(HelenusPropertyNode node, ColumnValuePreparer valuePreparer) { - switch (operator) { - case EQ: - return QueryBuilder.eq( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + switch (operator) { + case EQ : + return QueryBuilder.eq(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case IN: - Object[] preparedValues = new Object[values.length]; - for (int i = 0; i != values.length; ++i) { - preparedValues[i] = valuePreparer.prepareColumnValue(values[i], node.getProperty()); - } - return QueryBuilder.in(node.getColumnName(), preparedValues); + case IN : + Object[] preparedValues = new Object[values.length]; + for (int i = 0; i != values.length; ++i) { + preparedValues[i] = valuePreparer.prepareColumnValue(values[i], node.getProperty()); + } + return QueryBuilder.in(node.getColumnName(), preparedValues); - case LT: - return QueryBuilder.lt( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case LT : + return QueryBuilder.lt(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case LTE: - return QueryBuilder.lte( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case LTE : + return QueryBuilder.lte(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case GT: - return QueryBuilder.gt( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case GT : + return QueryBuilder.gt(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case GTE: - return QueryBuilder.gte( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case GTE : + return QueryBuilder.gte(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - default: - throw new HelenusMappingException("unknown filter operation " + operator); - } - } + default : + throw new HelenusMappingException("unknown filter operation " + operator); + } + } - @Override - public String toString() { + public V[] values() { + return values; + } - if (operator == Operator.IN) { + @Override + public String toString() { - if (values == null) { - return "in()"; - } + if (operator == Operator.IN) { - int len = values.length; - StringBuilder b = new StringBuilder(); - b.append("in("); - for (int i = 0; i != len; i++) { - if (b.length() > 3) { - b.append(", "); - } - b.append(String.valueOf(values[i])); - } - return b.append(')').toString(); - } + if (values == null) { + return "in()"; + } - return operator.getName() + values[0]; - } + int len = values.length; + StringBuilder b = new StringBuilder(); + b.append("in("); + for (int i = 0; i != len; i++) { + if (b.length() > 3) { + b.append(", "); + } + b.append(String.valueOf(values[i])); + } + return b.append(')').toString(); + } + + return operator.getName() + values[0]; + } } diff --git a/src/main/java/net/helenus/core/PropertyValueValidator.java b/src/main/java/net/helenus/core/PropertyValueValidator.java index 276418b..ca4aafb 100644 --- a/src/main/java/net/helenus/core/PropertyValueValidator.java +++ b/src/main/java/net/helenus/core/PropertyValueValidator.java @@ -19,5 +19,5 @@ import net.helenus.mapping.HelenusProperty; public interface PropertyValueValidator { - void validate(HelenusProperty prop, Object value); + void validate(HelenusProperty prop, Object value); } diff --git a/src/main/java/net/helenus/core/Query.java b/src/main/java/net/helenus/core/Query.java index b18fccb..7418876 100644 --- a/src/main/java/net/helenus/core/Query.java +++ b/src/main/java/net/helenus/core/Query.java @@ -15,80 +15,83 @@ */ package net.helenus.core; -import com.datastax.driver.core.querybuilder.BindMarker; -import com.datastax.driver.core.querybuilder.QueryBuilder; import java.util.List; import java.util.Map; import java.util.Objects; + +import com.datastax.driver.core.querybuilder.BindMarker; +import com.datastax.driver.core.querybuilder.QueryBuilder; + import net.helenus.mapping.OrderingDirection; /** Sugar methods for the queries */ public final class Query { - private Query() {} + private Query() { + } - public static BindMarker marker() { - return QueryBuilder.bindMarker(); - } + public static BindMarker marker() { + return QueryBuilder.bindMarker(); + } - public static BindMarker marker(String name) { - return QueryBuilder.bindMarker(name); - } + public static BindMarker marker(String name) { + return QueryBuilder.bindMarker(name); + } - public static Ordered asc(Getter getter) { - return new Ordered(getter, OrderingDirection.ASC); - } + public static Ordered asc(Getter getter) { + return new Ordered(getter, OrderingDirection.ASC); + } - public static Ordered desc(Getter getter) { - return new Ordered(getter, OrderingDirection.DESC); - } + public static Ordered desc(Getter getter) { + return new Ordered(getter, OrderingDirection.DESC); + } - public static Postulate eq(V val) { - return Postulate.of(Operator.EQ, val); - } + public static Postulate eq(V val) { + return Postulate.of(Operator.EQ, val); + } - public static Postulate lt(V val) { - return Postulate.of(Operator.LT, val); - } + public static Postulate lt(V val) { + return Postulate.of(Operator.LT, val); + } - public static Postulate lte(V val) { - return Postulate.of(Operator.LTE, val); - } + public static Postulate lte(V val) { + return Postulate.of(Operator.LTE, val); + } - public static Postulate gt(V val) { - return Postulate.of(Operator.GT, val); - } + public static Postulate gt(V val) { + return Postulate.of(Operator.GT, val); + } - public static Postulate gte(V val) { - return Postulate.of(Operator.GTE, val); - } + public static Postulate gte(V val) { + return Postulate.of(Operator.GTE, val); + } - public static Postulate in(V[] vals) { - return new Postulate(Operator.IN, vals); - } + public static Postulate in(V[] vals) { + return new Postulate(Operator.IN, vals); + } - public static Getter getIdx(Getter> listGetter, int index) { - Objects.requireNonNull(listGetter, "listGetter is null"); + public static Getter getIdx(Getter> listGetter, int index) { + Objects.requireNonNull(listGetter, "listGetter is null"); - return new Getter() { + return new Getter() { - @Override - public V get() { - return listGetter.get().get(index); - } - }; - } + @Override + public V get() { + return listGetter.get().get(index); + } + }; + } - public static Getter get(Getter> mapGetter, K k) { - Objects.requireNonNull(mapGetter, "mapGetter is null"); - Objects.requireNonNull(k, "key is null"); + public static Getter get(Getter> mapGetter, K k) { + Objects.requireNonNull(mapGetter, "mapGetter is null"); + Objects.requireNonNull(k, "key is null"); - return new Getter() { + return new Getter() { - @Override - public V get() { - return mapGetter.get().get(k); - } - }; - } + @Override + public V get() { + return mapGetter.get().get(k); + } + }; + } } diff --git a/src/main/java/net/helenus/core/SchemaUtil.java b/src/main/java/net/helenus/core/SchemaUtil.java index 6a228e9..44ccae8 100644 --- a/src/main/java/net/helenus/core/SchemaUtil.java +++ b/src/main/java/net/helenus/core/SchemaUtil.java @@ -15,15 +15,16 @@ */ package net.helenus.core; +import java.util.*; +import java.util.stream.Collectors; + import com.datastax.driver.core.*; -import com.datastax.driver.core.IndexMetadata; import com.datastax.driver.core.querybuilder.IsNotNullClause; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.schemabuilder.*; import com.datastax.driver.core.schemabuilder.Create.Options; -import java.util.*; -import java.util.stream.Collectors; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.*; import net.helenus.mapping.ColumnType; @@ -32,417 +33,394 @@ import net.helenus.mapping.type.OptionalColumnMetadata; import net.helenus.support.CqlUtil; import net.helenus.support.HelenusMappingException; - public final class SchemaUtil { - private SchemaUtil() {} + private SchemaUtil() { + } - public static RegularStatement use(String keyspace, boolean forceQuote) { - if (forceQuote) { - return new SimpleStatement("USE" + CqlUtil.forceQuote(keyspace)); - } else { - return new SimpleStatement("USE " + keyspace); - } - } + public static RegularStatement use(String keyspace, boolean forceQuote) { + if (forceQuote) { + return new SimpleStatement("USE" + CqlUtil.forceQuote(keyspace)); + } else { + return new SimpleStatement("USE " + keyspace); + } + } - public static SchemaStatement createUserType(HelenusEntity entity) { + public static SchemaStatement createUserType(HelenusEntity entity) { - if (entity.getType() != HelenusEntityType.UDT) { - throw new HelenusMappingException("expected UDT entity " + entity); - } + if (entity.getType() != HelenusEntityType.UDT) { + throw new HelenusMappingException("expected UDT entity " + entity); + } - CreateType create = SchemaBuilder.createType(entity.getName().toCql()); + CreateType create = SchemaBuilder.createType(entity.getName().toCql()); - for (HelenusProperty prop : entity.getOrderedProperties()) { + for (HelenusProperty prop : entity.getOrderedProperties()) { - ColumnType columnType = prop.getColumnType(); + ColumnType columnType = prop.getColumnType(); - if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { - throw new HelenusMappingException( - "primary key columns are not supported in UserDefinedType for " - + prop.getPropertyName() - + " in entity " - + entity); - } + if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { + throw new HelenusMappingException("primary key columns are not supported in UserDefinedType for " + + prop.getPropertyName() + " in entity " + entity); + } - try { - prop.getDataType().addColumn(create, prop.getColumnName()); - } catch (IllegalArgumentException e) { - throw new HelenusMappingException( - "invalid column name '" - + prop.getColumnName() - + "' in entity '" - + entity.getName().getName() - + "'", - e); - } - } - - return create; - } - - public static List alterUserType( - UserType userType, HelenusEntity entity, boolean dropUnusedColumns) { - - if (entity.getType() != HelenusEntityType.UDT) { - throw new HelenusMappingException("expected UDT entity " + entity); - } - - List result = new ArrayList(); - - /** - * TODO: In future replace SchemaBuilder.alterTable by SchemaBuilder.alterType when it will - * exist - */ - Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); - - final Set visitedColumns = - dropUnusedColumns ? new HashSet() : Collections.emptySet(); - - for (HelenusProperty prop : entity.getOrderedProperties()) { - - String columnName = prop.getColumnName().getName(); - - if (dropUnusedColumns) { - visitedColumns.add(columnName); - } - - ColumnType columnType = prop.getColumnType(); - - if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { - continue; - } - - DataType dataType = userType.getFieldType(columnName); - SchemaStatement stmt = - prop.getDataType() - .alterColumn(alter, prop.getColumnName(), optional(columnName, dataType)); - - if (stmt != null) { - result.add(stmt); - } - } - - if (dropUnusedColumns) { - for (String field : userType.getFieldNames()) { - if (!visitedColumns.contains(field)) { - - result.add(alter.dropColumn(field)); - } - } - } - - return result; - } - - public static SchemaStatement dropUserType(HelenusEntity entity) { - - if (entity.getType() != HelenusEntityType.UDT) { - throw new HelenusMappingException("expected UDT entity " + entity); - } - - return SchemaBuilder.dropType(entity.getName().toCql()).ifExists(); - } - - public static SchemaStatement dropUserType(UserType type) { - - return SchemaBuilder.dropType(type.getTypeName()).ifExists(); - } - - public static SchemaStatement createMaterializedView( - String keyspace, String viewName, HelenusEntity entity) { - if (entity.getType() != HelenusEntityType.VIEW) { - throw new HelenusMappingException("expected view entity " + entity); - } - - if (entity == null) { - throw new HelenusMappingException("no entity or table to select data"); - } - - List props = new ArrayList(); - entity - .getOrderedProperties() - .stream() - .map(p -> new HelenusPropertyNode(p, Optional.empty())) - .forEach(p -> props.add(p)); - - Select.Selection selection = QueryBuilder.select(); - - for (HelenusPropertyNode prop : props) { - String columnName = prop.getColumnName(); - selection = selection.column(columnName); - } - Class iface = entity.getMappingInterface(); - String tableName = Helenus.entity(iface.getInterfaces()[0]).getName().toCql(); - Select.Where where = selection.from(tableName).where(); - List p = new ArrayList(props.size()); - List c = new ArrayList(props.size()); - List o = new ArrayList(props.size()); + try { + prop.getDataType().addColumn(create, prop.getColumnName()); + } catch (IllegalArgumentException e) { + throw new HelenusMappingException("invalid column name '" + prop.getColumnName() + "' in entity '" + + entity.getName().getName() + "'", e); + } + } - for (HelenusPropertyNode prop : props) { - String columnName = prop.getColumnName(); - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - p.add(columnName); - where = where.and(new IsNotNullClause(columnName)); - break; + return create; + } - case CLUSTERING_COLUMN: - c.add(columnName); - where = where.and(new IsNotNullClause(columnName)); + public static List alterUserType(UserType userType, HelenusEntity entity, + boolean dropUnusedColumns) { - ClusteringColumn clusteringColumn = prop.getProperty().getGetterMethod().getAnnotation(ClusteringColumn.class); - if (clusteringColumn != null && clusteringColumn.ordering() != null) { - o.add(columnName + " " + clusteringColumn.ordering().cql()); - } - break; - default: - break; - } - } + if (entity.getType() != HelenusEntityType.UDT) { + throw new HelenusMappingException("expected UDT entity " + entity); + } - String primaryKey = - "PRIMARY KEY (" - + ((p.size() > 1) ? "(" + String.join(", ", p) + ")" : p.get(0)) - + ((c.size() > 0) - ? ", " + ((c.size() > 1) ? "(" + String.join(", ", c) + ")" : c.get(0)) - : "") - + ")"; + List result = new ArrayList(); - String clustering = ""; - if (o.size() > 0) { - clustering = "WITH CLUSTERING ORDER BY (" + String.join(", ", o) + ")"; - } - return new CreateMaterializedView(keyspace, viewName, where, primaryKey, clustering); - } + /** + * TODO: In future replace SchemaBuilder.alterTable by SchemaBuilder.alterType + * when it will exist + */ + Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); - public static SchemaStatement dropMaterializedView( - String keyspace, String viewName, HelenusEntity entity) { - return new DropMaterializedView(keyspace, viewName); - } - - public static SchemaStatement createTable(HelenusEntity entity) { - - if (entity.getType() != HelenusEntityType.TABLE) { - throw new HelenusMappingException("expected table entity " + entity); - } - - // NOTE: There is a bug in the normal path of createTable where the - // "cache" is set too early and never unset preventing more than - // one column on a table. - // SchemaBuilder.createTable(entity.getName().toCql()); - CreateTable create = new CreateTable(entity.getName().toCql()); - - create.ifNotExists(); - - List clusteringColumns = new ArrayList(); - - for (HelenusProperty prop : entity.getOrderedProperties()) { - - ColumnType columnType = prop.getColumnType(); - - if (columnType == ColumnType.CLUSTERING_COLUMN) { - clusteringColumns.add(prop); - } - - prop.getDataType().addColumn(create, prop.getColumnName()); - } - - if (!clusteringColumns.isEmpty()) { - Options options = create.withOptions(); - clusteringColumns.forEach( - p -> options.clusteringOrder(p.getColumnName().toCql(), mapDirection(p.getOrdering()))); - } - - return create; - } - - public static List alterTable( - TableMetadata tmd, HelenusEntity entity, boolean dropUnusedColumns) { - - if (entity.getType() != HelenusEntityType.TABLE) { - throw new HelenusMappingException("expected table entity " + entity); - } - - List result = new ArrayList(); - - Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); - - final Set visitedColumns = - dropUnusedColumns ? new HashSet() : Collections.emptySet(); - - for (HelenusProperty prop : entity.getOrderedProperties()) { - - String columnName = prop.getColumnName().getName(); - - if (dropUnusedColumns) { - visitedColumns.add(columnName); - } - - ColumnType columnType = prop.getColumnType(); - - if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { - continue; - } - - ColumnMetadata columnMetadata = tmd.getColumn(columnName); - SchemaStatement stmt = - prop.getDataType().alterColumn(alter, prop.getColumnName(), optional(columnMetadata)); - - if (stmt != null) { - result.add(stmt); - } - } - - if (dropUnusedColumns) { - for (ColumnMetadata cm : tmd.getColumns()) { - if (!visitedColumns.contains(cm.getName())) { - - result.add(alter.dropColumn(cm.getName())); - } - } - } - - return result; - } - - public static SchemaStatement dropTable(HelenusEntity entity) { - - if (entity.getType() != HelenusEntityType.TABLE) { - throw new HelenusMappingException("expected table entity " + entity); - } - - return SchemaBuilder.dropTable(entity.getName().toCql()).ifExists(); - } - - public static SchemaStatement createIndex(HelenusProperty prop) { - if (prop.caseSensitiveIndex()) { - return SchemaBuilder.createIndex(prop.getIndexName().get().toCql()) - .ifNotExists() - .onTable(prop.getEntity().getName().toCql()) - .andColumn(prop.getColumnName().toCql()); - } else { - return new CreateSasiIndex(prop.getIndexName().get().toCql()) - .ifNotExists() - .onTable(prop.getEntity().getName().toCql()) - .andColumn(prop.getColumnName().toCql()); - } - } - - public static List createIndexes(HelenusEntity entity) { - - return entity - .getOrderedProperties() - .stream() - .filter(p -> p.getIndexName().isPresent()) - .map(p -> SchemaUtil.createIndex(p)) - .collect(Collectors.toList()); - } - - public static List alterIndexes( - TableMetadata tmd, HelenusEntity entity, boolean dropUnusedIndexes) { - - List list = new ArrayList(); - - final Set visitedColumns = - dropUnusedIndexes ? new HashSet() : Collections.emptySet(); - - entity - .getOrderedProperties() - .stream() - .filter(p -> p.getIndexName().isPresent()) - .forEach( - p -> { - String columnName = p.getColumnName().getName(); - - if (dropUnusedIndexes) { - visitedColumns.add(columnName); - } - - ColumnMetadata cm = tmd.getColumn(columnName); - - if (cm != null) { - IndexMetadata im = tmd.getIndex(columnName); - if (im == null) { - list.add(createIndex(p)); - } - } else { - list.add(createIndex(p)); - } - }); - - if (dropUnusedIndexes) { - - tmd.getColumns() - .stream() - .filter(c -> tmd.getIndex(c.getName()) != null && !visitedColumns.contains(c.getName())) - .forEach( - c -> { - list.add(SchemaBuilder.dropIndex(tmd.getIndex(c.getName()).getName()).ifExists()); - }); - } - - return list; - } - - public static SchemaStatement dropIndex(HelenusProperty prop) { - return SchemaBuilder.dropIndex(prop.getIndexName().get().toCql()).ifExists(); - } - - private static SchemaBuilder.Direction mapDirection(OrderingDirection o) { - switch (o) { - case ASC: - return SchemaBuilder.Direction.ASC; - case DESC: - return SchemaBuilder.Direction.DESC; - } - throw new HelenusMappingException("unknown ordering " + o); - } - - public static void throwNoMapping(HelenusProperty prop) { - - throw new HelenusMappingException( - "only primitive types and Set,List,Map collections and UserDefinedTypes are allowed, unknown type for property '" - + prop.getPropertyName() - + "' type is '" - + prop.getJavaType() - + "' in the entity " - + prop.getEntity()); - } - - private static OptionalColumnMetadata optional(final ColumnMetadata columnMetadata) { - if (columnMetadata != null) { - return new OptionalColumnMetadata() { - - @Override - public String getName() { - return columnMetadata.getName(); - } - - @Override - public DataType getType() { - return columnMetadata.getType(); - } - }; - } - return null; - } - - private static OptionalColumnMetadata optional(final String name, final DataType dataType) { - if (dataType != null) { - return new OptionalColumnMetadata() { - - @Override - public String getName() { - return name; - } - - @Override - public DataType getType() { - return dataType; - } - }; - } - return null; - } + final Set visitedColumns = dropUnusedColumns ? new HashSet() : Collections.emptySet(); + + for (HelenusProperty prop : entity.getOrderedProperties()) { + + String columnName = prop.getColumnName().getName(); + + if (dropUnusedColumns) { + visitedColumns.add(columnName); + } + + ColumnType columnType = prop.getColumnType(); + + if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { + continue; + } + + DataType dataType = userType.getFieldType(columnName); + SchemaStatement stmt = prop.getDataType().alterColumn(alter, prop.getColumnName(), + optional(columnName, dataType)); + + if (stmt != null) { + result.add(stmt); + } + } + + if (dropUnusedColumns) { + for (String field : userType.getFieldNames()) { + if (!visitedColumns.contains(field)) { + + result.add(alter.dropColumn(field)); + } + } + } + + return result; + } + + public static SchemaStatement dropUserType(HelenusEntity entity) { + + if (entity.getType() != HelenusEntityType.UDT) { + throw new HelenusMappingException("expected UDT entity " + entity); + } + + return SchemaBuilder.dropType(entity.getName().toCql()).ifExists(); + } + + public static SchemaStatement dropUserType(UserType type) { + + return SchemaBuilder.dropType(type.getTypeName()).ifExists(); + } + + public static String createPrimaryKeyPhrase(Collection properties) { + List p = new ArrayList(properties.size()); + List c = new ArrayList(properties.size()); + + for (HelenusProperty prop : properties) { + String columnName = prop.getColumnName().toCql(); + switch (prop.getColumnType()) { + case PARTITION_KEY : + p.add(columnName); + break; + case CLUSTERING_COLUMN : + c.add(columnName); + break; + default : + break; + } + } + + return "(" + ((p.size() > 1) ? "(" + String.join(", ", p) + ")" : p.get(0)) + + ((c.size() > 0) ? ", " + ((c.size() > 1) ? "(" + String.join(", ", c) + ")" : c.get(0)) : "") + ")"; + } + + public static SchemaStatement createMaterializedView(String keyspace, String viewName, HelenusEntity entity) { + if (entity.getType() != HelenusEntityType.VIEW) { + throw new HelenusMappingException("expected view entity " + entity); + } + + if (entity == null) { + throw new HelenusMappingException("no entity or table to select data"); + } + + List props = new ArrayList(); + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> props.add(p)); + + Select.Selection selection = QueryBuilder.select(); + + for (HelenusPropertyNode prop : props) { + String columnName = prop.getColumnName(); + selection = selection.column(columnName); + } + Class iface = entity.getMappingInterface(); + String tableName = Helenus.entity(iface.getInterfaces()[0]).getName().toCql(); + Select.Where where = selection.from(tableName).where(); + List o = new ArrayList(props.size()); + + for (HelenusPropertyNode prop : props) { + String columnName = prop.getColumnName(); + switch (prop.getProperty().getColumnType()) { + case PARTITION_KEY : + where = where.and(new IsNotNullClause(columnName)); + break; + + case CLUSTERING_COLUMN : + where = where.and(new IsNotNullClause(columnName)); + + ClusteringColumn clusteringColumn = prop.getProperty().getGetterMethod() + .getAnnotation(ClusteringColumn.class); + if (clusteringColumn != null && clusteringColumn.ordering() != null) { + o.add(columnName + " " + clusteringColumn.ordering().cql()); + } + break; + default : + break; + } + } + + String primaryKey = "PRIMARY KEY " + createPrimaryKeyPhrase(entity.getOrderedProperties()); + + String clustering = ""; + if (o.size() > 0) { + clustering = "WITH CLUSTERING ORDER BY (" + String.join(", ", o) + ")"; + } + return new CreateMaterializedView(keyspace, viewName, where, primaryKey, clustering).ifNotExists(); + } + + public static SchemaStatement dropMaterializedView(String keyspace, String viewName, HelenusEntity entity) { + return new DropMaterializedView(keyspace, viewName); + } + + public static SchemaStatement createTable(HelenusEntity entity) { + + if (entity.getType() != HelenusEntityType.TABLE) { + throw new HelenusMappingException("expected table entity " + entity); + } + + // NOTE: There is a bug in the normal path of createTable where the + // "cache" is set too early and never unset preventing more than + // one column on a table. + // SchemaBuilder.createTable(entity.getName().toCql()); + CreateTable create = new CreateTable(entity.getName().toCql()); + + create.ifNotExists(); + + List clusteringColumns = new ArrayList(); + + for (HelenusProperty prop : entity.getOrderedProperties()) { + + ColumnType columnType = prop.getColumnType(); + + if (columnType == ColumnType.CLUSTERING_COLUMN) { + clusteringColumns.add(prop); + } + + prop.getDataType().addColumn(create, prop.getColumnName()); + } + + if (!clusteringColumns.isEmpty()) { + Options options = create.withOptions(); + clusteringColumns + .forEach(p -> options.clusteringOrder(p.getColumnName().toCql(), mapDirection(p.getOrdering()))); + } + + return create; + } + + public static List alterTable(TableMetadata tmd, HelenusEntity entity, boolean dropUnusedColumns) { + + if (entity.getType() != HelenusEntityType.TABLE) { + throw new HelenusMappingException("expected table entity " + entity); + } + + List result = new ArrayList(); + + Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); + + final Set visitedColumns = dropUnusedColumns ? new HashSet() : Collections.emptySet(); + + for (HelenusProperty prop : entity.getOrderedProperties()) { + + String columnName = prop.getColumnName().getName(); + + if (dropUnusedColumns) { + visitedColumns.add(columnName); + } + + ColumnType columnType = prop.getColumnType(); + + if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { + continue; + } + + ColumnMetadata columnMetadata = tmd.getColumn(columnName); + SchemaStatement stmt = prop.getDataType().alterColumn(alter, prop.getColumnName(), + optional(columnMetadata)); + + if (stmt != null) { + result.add(stmt); + } + } + + if (dropUnusedColumns) { + for (ColumnMetadata cm : tmd.getColumns()) { + if (!visitedColumns.contains(cm.getName())) { + + result.add(alter.dropColumn(cm.getName())); + } + } + } + + return result; + } + + public static SchemaStatement dropTable(HelenusEntity entity) { + + if (entity.getType() != HelenusEntityType.TABLE) { + throw new HelenusMappingException("expected table entity " + entity); + } + + return SchemaBuilder.dropTable(entity.getName().toCql()).ifExists(); + } + + public static SchemaStatement createIndex(HelenusProperty prop) { + if (prop.caseSensitiveIndex()) { + return SchemaBuilder.createIndex(prop.getIndexName().get().toCql()).ifNotExists() + .onTable(prop.getEntity().getName().toCql()).andColumn(prop.getColumnName().toCql()); + } else { + return new CreateSasiIndex(prop.getIndexName().get().toCql()).ifNotExists() + .onTable(prop.getEntity().getName().toCql()).andColumn(prop.getColumnName().toCql()); + } + } + + public static List createIndexes(HelenusEntity entity) { + + return entity.getOrderedProperties().stream().filter(p -> p.getIndexName().isPresent()) + .map(p -> SchemaUtil.createIndex(p)).collect(Collectors.toList()); + } + + public static List alterIndexes(TableMetadata tmd, HelenusEntity entity, + boolean dropUnusedIndexes) { + + List list = new ArrayList(); + + final Set visitedColumns = dropUnusedIndexes ? new HashSet() : Collections.emptySet(); + + entity.getOrderedProperties().stream().filter(p -> p.getIndexName().isPresent()).forEach(p -> { + String columnName = p.getColumnName().getName(); + + if (dropUnusedIndexes) { + visitedColumns.add(columnName); + } + + ColumnMetadata cm = tmd.getColumn(columnName); + + if (cm != null) { + IndexMetadata im = tmd.getIndex(columnName); + if (im == null) { + list.add(createIndex(p)); + } + } else { + list.add(createIndex(p)); + } + }); + + if (dropUnusedIndexes) { + + tmd.getColumns().stream() + .filter(c -> tmd.getIndex(c.getName()) != null && !visitedColumns.contains(c.getName())) + .forEach(c -> { + list.add(SchemaBuilder.dropIndex(tmd.getIndex(c.getName()).getName()).ifExists()); + }); + } + + return list; + } + + public static SchemaStatement dropIndex(HelenusProperty prop) { + return SchemaBuilder.dropIndex(prop.getIndexName().get().toCql()).ifExists(); + } + + private static SchemaBuilder.Direction mapDirection(OrderingDirection o) { + switch (o) { + case ASC : + return SchemaBuilder.Direction.ASC; + case DESC : + return SchemaBuilder.Direction.DESC; + } + throw new HelenusMappingException("unknown ordering " + o); + } + + public static void throwNoMapping(HelenusProperty prop) { + + throw new HelenusMappingException( + "only primitive types and Set,List,Map collections and UserDefinedTypes are allowed, unknown type for property '" + + prop.getPropertyName() + "' type is '" + prop.getJavaType() + "' in the entity " + + prop.getEntity()); + } + + private static OptionalColumnMetadata optional(final ColumnMetadata columnMetadata) { + if (columnMetadata != null) { + return new OptionalColumnMetadata() { + + @Override + public String getName() { + return columnMetadata.getName(); + } + + @Override + public DataType getType() { + return columnMetadata.getType(); + } + }; + } + return null; + } + + private static OptionalColumnMetadata optional(final String name, final DataType dataType) { + if (dataType != null) { + return new OptionalColumnMetadata() { + + @Override + public String getName() { + return name; + } + + @Override + public DataType getType() { + return dataType; + } + }; + } + return null; + } } diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index f6ecfd6..d131b7c 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -15,16 +15,18 @@ */ package net.helenus.core; -import brave.Tracer; -import com.codahale.metrics.MetricRegistry; -import com.datastax.driver.core.*; -import com.google.common.util.concurrent.MoreExecutors; import java.io.IOException; import java.io.PrintStream; import java.util.*; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.Consumer; + +import com.codahale.metrics.MetricRegistry; +import com.datastax.driver.core.*; +import com.google.common.util.concurrent.MoreExecutors; + +import brave.Tracer; import net.helenus.core.reflect.DslExportable; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntityType; @@ -37,399 +39,344 @@ import net.helenus.support.PackageUtil; public final class SessionInitializer extends AbstractSessionOperations { - private final Session session; - private CodecRegistry registry; - private String usingKeyspace; - private boolean showCql = false; - private ConsistencyLevel consistencyLevel; - private boolean idempotent = true; - private MetricRegistry metricRegistry = new MetricRegistry(); - private Tracer zipkinTracer; - private PrintStream printStream = System.out; - private Executor executor = MoreExecutors.directExecutor(); - private Class unitOfWorkClass = UnitOfWorkImpl.class; - - private SessionRepositoryBuilder sessionRepository; - - private boolean dropUnusedColumns = false; - private boolean dropUnusedIndexes = false; - - private KeyspaceMetadata keyspaceMetadata; - - private final List>> initList = new ArrayList>>(); - private AutoDdl autoDdl = AutoDdl.UPDATE; - - SessionInitializer(Session session) { - this.session = Objects.requireNonNull(session, "empty session"); - this.usingKeyspace = session.getLoggedKeyspace(); // can be null - this.sessionRepository = new SessionRepositoryBuilder(session); - } - - @Override - public Session currentSession() { - return session; - } - - @Override - public String usingKeyspace() { - return usingKeyspace; - } - - @Override - public Executor getExecutor() { - return executor; - } - - @Override - public SessionRepository getSessionRepository() { - throw new HelenusException("not expected to call"); - } - - @Override - public ColumnValueProvider getValueProvider() { - throw new HelenusException("not expected to call"); - } - - @Override - public ColumnValuePreparer getValuePreparer() { - throw new HelenusException("not expected to call"); - } - - public SessionInitializer showCql() { - this.showCql = true; - return this; - } - - public SessionInitializer showCql(boolean enabled) { - this.showCql = enabled; - return this; - } - - public SessionInitializer metricRegistry(MetricRegistry metricRegistry) { - this.metricRegistry = metricRegistry; - return this; - } - - public SessionInitializer zipkinTracer(Tracer tracer) { - this.zipkinTracer = tracer; - return this; - } - - public SessionInitializer setUnitOfWorkClass(Class e) { - this.unitOfWorkClass = e; - return this; - } - - public SessionInitializer consistencyLevel(ConsistencyLevel consistencyLevel) { - this.consistencyLevel = consistencyLevel; - return this; - } - - public ConsistencyLevel getDefaultConsistencyLevel() { - return consistencyLevel; - } - - public SessionInitializer idempotentQueryExecution(boolean idempotent) { - this.idempotent = idempotent; - return this; - } - - public boolean getDefaultQueryIdempotency() { - return idempotent; - } - - @Override - public PrintStream getPrintStream() { - return printStream; - } - - public SessionInitializer printTo(PrintStream out) { - this.printStream = out; - return this; - } - - public SessionInitializer withExecutor(Executor executor) { - Objects.requireNonNull(executor, "empty executor"); - this.executor = executor; - return this; - } - - public SessionInitializer withCachingExecutor() { - this.executor = Executors.newCachedThreadPool(); - return this; - } - - public SessionInitializer dropUnusedColumns(boolean enabled) { - this.dropUnusedColumns = enabled; - return this; - } - - public SessionInitializer dropUnusedIndexes(boolean enabled) { - this.dropUnusedIndexes = enabled; - return this; - } - - public SessionInitializer withCodecRegistry(CodecRegistry registry) { - this.registry = registry; - return this; - } - - @Override - public boolean isShowCql() { - return showCql; - } - - public SessionInitializer addPackage(String packageName) { - try { - PackageUtil.getClasses(packageName) - .stream() - .filter(c -> c.isInterface() && !c.isAnnotation()) - .forEach( - clazz -> { - initList.add(Either.right(clazz)); - }); - } catch (IOException | ClassNotFoundException e) { - throw new HelenusException("fail to add package " + packageName, e); - } - return this; - } - - public SessionInitializer add(Object... dsls) { - Objects.requireNonNull(dsls, "dsls is empty"); - int len = dsls.length; - for (int i = 0; i != len; ++i) { - Object obj = Objects.requireNonNull(dsls[i], "element " + i + " is empty"); - initList.add(Either.left(obj)); - } - return this; - } - - public SessionInitializer autoValidate() { - this.autoDdl = AutoDdl.VALIDATE; - return this; - } - - public SessionInitializer autoUpdate() { - this.autoDdl = AutoDdl.UPDATE; - return this; - } - - public SessionInitializer autoCreate() { - this.autoDdl = AutoDdl.CREATE; - return this; - } - - public SessionInitializer autoCreateDrop() { - this.autoDdl = AutoDdl.CREATE_DROP; - return this; - } - - public SessionInitializer auto(AutoDdl autoDdl) { - this.autoDdl = autoDdl; - return this; - } - - public SessionInitializer use(String keyspace) { - session.execute(SchemaUtil.use(keyspace, false)); - this.usingKeyspace = keyspace; - return this; - } - - public SessionInitializer use(String keyspace, boolean forceQuote) { - session.execute(SchemaUtil.use(keyspace, forceQuote)); - this.usingKeyspace = keyspace; - return this; - } - - public void singleton() { - Helenus.setSession(get()); - } - - public synchronized HelenusSession get() { - initialize(); - return new HelenusSession( - session, - usingKeyspace, - registry, - showCql, - printStream, - sessionRepository, - executor, - autoDdl == AutoDdl.CREATE_DROP, - consistencyLevel, - idempotent, - unitOfWorkClass, - metricRegistry, - zipkinTracer); - } - - private void initialize() { - - Objects.requireNonNull(usingKeyspace, "please define keyspace by 'use' operator"); - - initList.forEach( - (either) -> { - Class iface = null; - if (either.isLeft()) { - iface = MappingUtil.getMappingInterface(either.getLeft()); - } else { - iface = either.getRight(); - } - - DslExportable dsl = (DslExportable) Helenus.dsl(iface); - dsl.setCassandraMetadataForHelenusSesion(session.getCluster().getMetadata()); - sessionRepository.add(dsl); - }); - - TableOperations tableOps = new TableOperations(this, dropUnusedColumns, dropUnusedIndexes); - UserTypeOperations userTypeOps = new UserTypeOperations(this, dropUnusedColumns); - - switch (autoDdl) { - case CREATE_DROP: - - // Drop view first, otherwise a `DROP TABLE ...` will fail as the type is still referenced - // by a view. - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.dropView(e)); - - // Drop tables second, before DROP TYPE otherwise a `DROP TYPE ...` will fail as the type is - // still referenced by a table. - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.dropTable(e)); - - eachUserTypeInReverseOrder(userTypeOps, e -> userTypeOps.dropUserType(e)); - - // FALLTHRU to CREATE case (read: the absence of a `break;` statement here is intentional!) - case CREATE: - eachUserTypeInOrder(userTypeOps, e -> userTypeOps.createUserType(e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.createTable(e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.createView(e)); - - break; - - case VALIDATE: - eachUserTypeInOrder(userTypeOps, e -> userTypeOps.validateUserType(getUserType(e), e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.validateTable(getTableMetadata(e), e)); - - break; - - case UPDATE: - eachUserTypeInOrder(userTypeOps, e -> userTypeOps.updateUserType(getUserType(e), e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.dropView(e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.updateTable(getTableMetadata(e), e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.createView(e)); - break; - } - - KeyspaceMetadata km = getKeyspaceMetadata(); - - for (UserType userType : km.getUserTypes()) { - sessionRepository.addUserType(userType.getTypeName(), userType); - } - } - - private void eachUserTypeInOrder( - UserTypeOperations userTypeOps, Consumer action) { - - Set processedSet = new HashSet(); - Set stack = new HashSet(); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.UDT) - .forEach( - e -> { - stack.clear(); - eachUserTypeInRecursion(e, processedSet, stack, userTypeOps, action); - }); - } - - private void eachUserTypeInReverseOrder( - UserTypeOperations userTypeOps, Consumer action) { - ArrayDeque deque = new ArrayDeque<>(); - eachUserTypeInOrder(userTypeOps, e -> deque.addFirst(e)); - deque - .stream() - .forEach( - e -> { - action.accept(e); - }); - } - - private void eachUserTypeInRecursion( - HelenusEntity e, - Set processedSet, - Set stack, - UserTypeOperations userTypeOps, - Consumer action) { - - stack.add(e); - - Collection createBefore = sessionRepository.getUserTypeUses(e); - - for (HelenusEntity be : createBefore) { - if (!processedSet.contains(be) && !stack.contains(be)) { - eachUserTypeInRecursion(be, processedSet, stack, userTypeOps, action); - processedSet.add(be); - } - } - - if (!processedSet.contains(e)) { - action.accept(e); - processedSet.add(e); - } - } - - private KeyspaceMetadata getKeyspaceMetadata() { - if (keyspaceMetadata == null) { - keyspaceMetadata = - session.getCluster().getMetadata().getKeyspace(usingKeyspace.toLowerCase()); - } - return keyspaceMetadata; - } - - private TableMetadata getTableMetadata(HelenusEntity entity) { - return getKeyspaceMetadata().getTable(entity.getName().getName()); - } - - private UserType getUserType(HelenusEntity entity) { - return getKeyspaceMetadata().getUserType(entity.getName().getName()); - } + private final Session session; + private final List>> initList = new ArrayList>>(); + private CodecRegistry registry; + private String usingKeyspace; + private boolean showCql = false; + private ConsistencyLevel consistencyLevel; + private boolean idempotent = true; + private MetricRegistry metricRegistry = new MetricRegistry(); + private Tracer zipkinTracer; + private PrintStream printStream = System.out; + private Executor executor = MoreExecutors.directExecutor(); + private Class unitOfWorkClass = UnitOfWorkImpl.class; + private SessionRepositoryBuilder sessionRepository; + private boolean dropUnusedColumns = false; + private boolean dropUnusedIndexes = false; + private KeyspaceMetadata keyspaceMetadata; + private AutoDdl autoDdl = AutoDdl.UPDATE; + + SessionInitializer(Session session) { + this.session = Objects.requireNonNull(session, "empty session"); + this.usingKeyspace = session.getLoggedKeyspace(); // can be null + this.sessionRepository = new SessionRepositoryBuilder(session); + } + + @Override + public Session currentSession() { + return session; + } + + @Override + public String usingKeyspace() { + return usingKeyspace; + } + + @Override + public Executor getExecutor() { + return executor; + } + + @Override + public SessionRepository getSessionRepository() { + throw new HelenusException("not expected to call"); + } + + @Override + public ColumnValueProvider getValueProvider() { + throw new HelenusException("not expected to call"); + } + + @Override + public ColumnValuePreparer getValuePreparer() { + throw new HelenusException("not expected to call"); + } + + public SessionInitializer showCql() { + this.showCql = true; + return this; + } + + public SessionInitializer showCql(boolean enabled) { + this.showCql = enabled; + return this; + } + + public SessionInitializer metricRegistry(MetricRegistry metricRegistry) { + this.metricRegistry = metricRegistry; + return this; + } + + public SessionInitializer zipkinTracer(Tracer tracer) { + this.zipkinTracer = tracer; + return this; + } + + public SessionInitializer setUnitOfWorkClass(Class e) { + this.unitOfWorkClass = e; + return this; + } + + public SessionInitializer consistencyLevel(ConsistencyLevel consistencyLevel) { + this.consistencyLevel = consistencyLevel; + return this; + } + + public ConsistencyLevel getDefaultConsistencyLevel() { + return consistencyLevel; + } + + public SessionInitializer idempotentQueryExecution(boolean idempotent) { + this.idempotent = idempotent; + return this; + } + + public boolean getDefaultQueryIdempotency() { + return idempotent; + } + + @Override + public PrintStream getPrintStream() { + return printStream; + } + + public SessionInitializer printTo(PrintStream out) { + this.printStream = out; + return this; + } + + public SessionInitializer withExecutor(Executor executor) { + Objects.requireNonNull(executor, "empty executor"); + this.executor = executor; + return this; + } + + public SessionInitializer withCachingExecutor() { + this.executor = Executors.newCachedThreadPool(); + return this; + } + + public SessionInitializer dropUnusedColumns(boolean enabled) { + this.dropUnusedColumns = enabled; + return this; + } + + public SessionInitializer dropUnusedIndexes(boolean enabled) { + this.dropUnusedIndexes = enabled; + return this; + } + + public SessionInitializer withCodecRegistry(CodecRegistry registry) { + this.registry = registry; + return this; + } + + @Override + public boolean isShowCql() { + return showCql; + } + + public SessionInitializer addPackage(String packageName) { + try { + PackageUtil.getClasses(packageName).stream().filter(c -> c.isInterface() && !c.isAnnotation()) + .forEach(clazz -> { + initList.add(Either.right(clazz)); + }); + } catch (IOException | ClassNotFoundException e) { + throw new HelenusException("fail to add package " + packageName, e); + } + return this; + } + + public SessionInitializer add(Object... dsls) { + Objects.requireNonNull(dsls, "dsls is empty"); + int len = dsls.length; + for (int i = 0; i != len; ++i) { + Object obj = Objects.requireNonNull(dsls[i], "element " + i + " is empty"); + initList.add(Either.left(obj)); + } + return this; + } + + public SessionInitializer autoValidate() { + this.autoDdl = AutoDdl.VALIDATE; + return this; + } + + public SessionInitializer autoUpdate() { + this.autoDdl = AutoDdl.UPDATE; + return this; + } + + public SessionInitializer autoCreate() { + this.autoDdl = AutoDdl.CREATE; + return this; + } + + public SessionInitializer autoCreateDrop() { + this.autoDdl = AutoDdl.CREATE_DROP; + return this; + } + + public SessionInitializer auto(AutoDdl autoDdl) { + this.autoDdl = autoDdl; + return this; + } + + public SessionInitializer use(String keyspace) { + session.execute(SchemaUtil.use(keyspace, false)); + this.usingKeyspace = keyspace; + return this; + } + + public SessionInitializer use(String keyspace, boolean forceQuote) { + session.execute(SchemaUtil.use(keyspace, forceQuote)); + this.usingKeyspace = keyspace; + return this; + } + + public void singleton() { + Helenus.setSession(get()); + } + + public synchronized HelenusSession get() { + initialize(); + return new HelenusSession(session, usingKeyspace, registry, showCql, printStream, sessionRepository, executor, + autoDdl == AutoDdl.CREATE_DROP, consistencyLevel, idempotent, unitOfWorkClass, metricRegistry, + zipkinTracer); + } + + private void initialize() { + + Objects.requireNonNull(usingKeyspace, "please define keyspace by 'use' operator"); + + initList.forEach((either) -> { + Class iface = null; + if (either.isLeft()) { + iface = MappingUtil.getMappingInterface(either.getLeft()); + } else { + iface = either.getRight(); + } + + DslExportable dsl = (DslExportable) Helenus.dsl(iface); + dsl.setCassandraMetadataForHelenusSession(session.getCluster().getMetadata()); + sessionRepository.add(dsl); + }); + + TableOperations tableOps = new TableOperations(this, dropUnusedColumns, dropUnusedIndexes); + UserTypeOperations userTypeOps = new UserTypeOperations(this, dropUnusedColumns); + + switch (autoDdl) { + case CREATE_DROP : + + // Drop view first, otherwise a `DROP TABLE ...` will fail as the type is still + // referenced + // by a view. + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.dropView(e)); + + // Drop tables second, before DROP TYPE otherwise a `DROP TYPE ...` will fail as + // the type is + // still referenced by a table. + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.dropTable(e)); + + eachUserTypeInReverseOrder(userTypeOps, e -> userTypeOps.dropUserType(e)); + + // FALLTHRU to CREATE case (read: the absence of a `break;` statement here is + // intentional!) + case CREATE : + eachUserTypeInOrder(userTypeOps, e -> userTypeOps.createUserType(e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.createTable(e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.createView(e)); + + break; + + case VALIDATE : + eachUserTypeInOrder(userTypeOps, e -> userTypeOps.validateUserType(getUserType(e), e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.validateTable(getTableMetadata(e), e)); + + break; + + case UPDATE : + eachUserTypeInOrder(userTypeOps, e -> userTypeOps.updateUserType(getUserType(e), e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.dropView(e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.updateTable(getTableMetadata(e), e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.createView(e)); + break; + } + + KeyspaceMetadata km = getKeyspaceMetadata(); + + for (UserType userType : km.getUserTypes()) { + sessionRepository.addUserType(userType.getTypeName(), userType); + } + } + + private void eachUserTypeInOrder(UserTypeOperations userTypeOps, Consumer action) { + + Set processedSet = new HashSet(); + Set stack = new HashSet(); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.UDT).forEach(e -> { + stack.clear(); + eachUserTypeInRecursion(e, processedSet, stack, userTypeOps, action); + }); + } + + private void eachUserTypeInReverseOrder(UserTypeOperations userTypeOps, Consumer action) { + ArrayDeque deque = new ArrayDeque<>(); + eachUserTypeInOrder(userTypeOps, e -> deque.addFirst(e)); + deque.stream().forEach(e -> { + action.accept(e); + }); + } + + private void eachUserTypeInRecursion(HelenusEntity e, Set processedSet, Set stack, + UserTypeOperations userTypeOps, Consumer action) { + + stack.add(e); + + Collection createBefore = sessionRepository.getUserTypeUses(e); + + for (HelenusEntity be : createBefore) { + if (!processedSet.contains(be) && !stack.contains(be)) { + eachUserTypeInRecursion(be, processedSet, stack, userTypeOps, action); + processedSet.add(be); + } + } + + if (!processedSet.contains(e)) { + action.accept(e); + processedSet.add(e); + } + } + + private KeyspaceMetadata getKeyspaceMetadata() { + if (keyspaceMetadata == null) { + keyspaceMetadata = session.getCluster().getMetadata().getKeyspace(usingKeyspace.toLowerCase()); + } + return keyspaceMetadata; + } + + private TableMetadata getTableMetadata(HelenusEntity entity) { + return getKeyspaceMetadata().getTable(entity.getName().getName()); + } + + private UserType getUserType(HelenusEntity entity) { + return getKeyspaceMetadata().getUserType(entity.getName().getName()); + } } diff --git a/src/main/java/net/helenus/core/SessionRepository.java b/src/main/java/net/helenus/core/SessionRepository.java index 05d6f64..faf7774 100644 --- a/src/main/java/net/helenus/core/SessionRepository.java +++ b/src/main/java/net/helenus/core/SessionRepository.java @@ -15,30 +15,31 @@ */ package net.helenus.core; +import java.util.Collection; + import com.datastax.driver.core.UserType; import com.google.common.collect.ImmutableMap; -import java.util.Collection; + import net.helenus.mapping.HelenusEntity; public final class SessionRepository { - private final ImmutableMap userTypeMap; + private final ImmutableMap userTypeMap; - private final ImmutableMap, HelenusEntity> entityMap; + private final ImmutableMap, HelenusEntity> entityMap; - public SessionRepository(SessionRepositoryBuilder builder) { + public SessionRepository(SessionRepositoryBuilder builder) { - userTypeMap = ImmutableMap.builder().putAll(builder.getUserTypeMap()).build(); + userTypeMap = ImmutableMap.builder().putAll(builder.getUserTypeMap()).build(); - entityMap = - ImmutableMap., HelenusEntity>builder().putAll(builder.getEntityMap()).build(); - } + entityMap = ImmutableMap., HelenusEntity>builder().putAll(builder.getEntityMap()).build(); + } - public UserType findUserType(String name) { - return userTypeMap.get(name.toLowerCase()); - } + public UserType findUserType(String name) { + return userTypeMap.get(name.toLowerCase()); + } - public Collection entities() { - return entityMap.values(); - } + public Collection entities() { + return entityMap.values(); + } } diff --git a/src/main/java/net/helenus/core/SessionRepositoryBuilder.java b/src/main/java/net/helenus/core/SessionRepositoryBuilder.java index 413ec48..8ef0734 100644 --- a/src/main/java/net/helenus/core/SessionRepositoryBuilder.java +++ b/src/main/java/net/helenus/core/SessionRepositoryBuilder.java @@ -15,15 +15,17 @@ */ package net.helenus.core; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + import com.datastax.driver.core.Session; import com.datastax.driver.core.UDTValue; import com.datastax.driver.core.UserType; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; + import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntityType; import net.helenus.mapping.HelenusProperty; @@ -33,112 +35,110 @@ import net.helenus.support.HelenusMappingException; public final class SessionRepositoryBuilder { - private static final Optional OPTIONAL_UDT = - Optional.of(HelenusEntityType.UDT); + private static final Optional OPTIONAL_UDT = Optional.of(HelenusEntityType.UDT); - private final Map, HelenusEntity> entityMap = new HashMap, HelenusEntity>(); + private final Map, HelenusEntity> entityMap = new HashMap, HelenusEntity>(); - private final Map userTypeMap = new HashMap(); + private final Map userTypeMap = new HashMap(); - private final Multimap userTypeUsesMap = HashMultimap.create(); + private final Multimap userTypeUsesMap = HashMultimap.create(); - private final Session session; + private final Session session; - SessionRepositoryBuilder(Session session) { - this.session = session; - } + SessionRepositoryBuilder(Session session) { + this.session = session; + } - public SessionRepository build() { - return new SessionRepository(this); - } + public SessionRepository build() { + return new SessionRepository(this); + } - public Collection getUserTypeUses(HelenusEntity udtName) { - return userTypeUsesMap.get(udtName); - } + public Collection getUserTypeUses(HelenusEntity udtName) { + return userTypeUsesMap.get(udtName); + } - public Collection entities() { - return entityMap.values(); - } + public Collection entities() { + return entityMap.values(); + } - protected Map, HelenusEntity> getEntityMap() { - return entityMap; - } + protected Map, HelenusEntity> getEntityMap() { + return entityMap; + } - protected Map getUserTypeMap() { - return userTypeMap; - } + protected Map getUserTypeMap() { + return userTypeMap; + } - public void addUserType(String name, UserType userType) { - userTypeMap.putIfAbsent(name.toLowerCase(), userType); - } + public void addUserType(String name, UserType userType) { + userTypeMap.putIfAbsent(name.toLowerCase(), userType); + } - public HelenusEntity add(Object dsl) { - return add(dsl, Optional.empty()); - } + public HelenusEntity add(Object dsl) { + return add(dsl, Optional.empty()); + } - public void addEntity(HelenusEntity entity) { + public void addEntity(HelenusEntity entity) { - HelenusEntity concurrentEntity = entityMap.putIfAbsent(entity.getMappingInterface(), entity); + HelenusEntity concurrentEntity = entityMap.putIfAbsent(entity.getMappingInterface(), entity); - if (concurrentEntity == null) { - addUserDefinedTypes(entity.getOrderedProperties()); - } - } + if (concurrentEntity == null) { + addUserDefinedTypes(entity.getOrderedProperties()); + } + } - public HelenusEntity add(Object dsl, Optional type) { + public HelenusEntity add(Object dsl, Optional type) { - HelenusEntity helenusEntity = Helenus.resolve(dsl, session.getCluster().getMetadata()); + HelenusEntity helenusEntity = Helenus.resolve(dsl, session.getCluster().getMetadata()); - Class iface = helenusEntity.getMappingInterface(); + Class iface = helenusEntity.getMappingInterface(); - HelenusEntity entity = entityMap.get(iface); + HelenusEntity entity = entityMap.get(iface); - if (entity == null) { + if (entity == null) { - entity = helenusEntity; + entity = helenusEntity; - if (type.isPresent() && entity.getType() != type.get()) { - throw new HelenusMappingException( - "unexpected entity type " + entity.getType() + " for " + entity); - } + if (type.isPresent() && entity.getType() != type.get()) { + throw new HelenusMappingException("unexpected entity type " + entity.getType() + " for " + entity); + } - HelenusEntity concurrentEntity = entityMap.putIfAbsent(iface, entity); + HelenusEntity concurrentEntity = entityMap.putIfAbsent(iface, entity); - if (concurrentEntity == null) { - addUserDefinedTypes(entity.getOrderedProperties()); - } else { - entity = concurrentEntity; - } - } + if (concurrentEntity == null) { + addUserDefinedTypes(entity.getOrderedProperties()); + } else { + entity = concurrentEntity; + } + } - return entity; - } + return entity; + } - private void addUserDefinedTypes(Collection props) { + private void addUserDefinedTypes(Collection props) { - for (HelenusProperty prop : props) { + for (HelenusProperty prop : props) { - AbstractDataType type = prop.getDataType(); + AbstractDataType type = prop.getDataType(); - if (type instanceof DTDataType) { - continue; - } + if (type instanceof DTDataType) { + continue; + } - if (!UDTValue.class.isAssignableFrom(prop.getJavaType())) { + if (!UDTValue.class.isAssignableFrom(prop.getJavaType())) { - for (Class udtClass : type.getTypeArguments()) { + for (Class udtClass : type.getTypeArguments()) { - if (UDTValue.class.isAssignableFrom(udtClass)) { - continue; - } + if (UDTValue.class.isAssignableFrom(udtClass)) { + continue; + } - HelenusEntity addedUserType = add(udtClass, OPTIONAL_UDT); + HelenusEntity addedUserType = add(udtClass, OPTIONAL_UDT); - if (HelenusEntityType.UDT == prop.getEntity().getType()) { - userTypeUsesMap.put(prop.getEntity(), addedUserType); - } - } - } - } - } + if (HelenusEntityType.UDT == prop.getEntity().getType()) { + userTypeUsesMap.put(prop.getEntity(), addedUserType); + } + } + } + } + } } diff --git a/src/main/java/net/helenus/core/TableOperations.java b/src/main/java/net/helenus/core/TableOperations.java index 3c602d6..354851a 100644 --- a/src/main/java/net/helenus/core/TableOperations.java +++ b/src/main/java/net/helenus/core/TableOperations.java @@ -15,97 +15,88 @@ */ package net.helenus.core; +import java.util.List; + import com.datastax.driver.core.TableMetadata; import com.datastax.driver.core.schemabuilder.SchemaStatement; -import java.util.List; + import net.helenus.mapping.HelenusEntity; import net.helenus.support.HelenusException; public final class TableOperations { - private final AbstractSessionOperations sessionOps; - private final boolean dropUnusedColumns; - private final boolean dropUnusedIndexes; + private final AbstractSessionOperations sessionOps; + private final boolean dropUnusedColumns; + private final boolean dropUnusedIndexes; - public TableOperations( - AbstractSessionOperations sessionOps, boolean dropUnusedColumns, boolean dropUnusedIndexes) { - this.sessionOps = sessionOps; - this.dropUnusedColumns = dropUnusedColumns; - this.dropUnusedIndexes = dropUnusedIndexes; - } + public TableOperations(AbstractSessionOperations sessionOps, boolean dropUnusedColumns, boolean dropUnusedIndexes) { + this.sessionOps = sessionOps; + this.dropUnusedColumns = dropUnusedColumns; + this.dropUnusedIndexes = dropUnusedIndexes; + } - public void createTable(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.createTable(entity), true); - executeBatch(SchemaUtil.createIndexes(entity)); - } + public void createTable(HelenusEntity entity) { + sessionOps.execute(SchemaUtil.createTable(entity), true); + executeBatch(SchemaUtil.createIndexes(entity)); + } - public void dropTable(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.dropTable(entity), true); - } + public void dropTable(HelenusEntity entity) { + sessionOps.execute(SchemaUtil.dropTable(entity), true); + } - public void validateTable(TableMetadata tmd, HelenusEntity entity) { + public void validateTable(TableMetadata tmd, HelenusEntity entity) { - if (tmd == null) { - throw new HelenusException( - "table does not exists " - + entity.getName() - + "for entity " - + entity.getMappingInterface()); - } + if (tmd == null) { + throw new HelenusException( + "table does not exists " + entity.getName() + "for entity " + entity.getMappingInterface()); + } - List list = SchemaUtil.alterTable(tmd, entity, dropUnusedColumns); + List list = SchemaUtil.alterTable(tmd, entity, dropUnusedColumns); - list.addAll(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); + list.addAll(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); - if (!list.isEmpty()) { - throw new HelenusException( - "schema changed for entity " - + entity.getMappingInterface() - + ", apply this command: " - + list); - } - } + if (!list.isEmpty()) { + throw new HelenusException( + "schema changed for entity " + entity.getMappingInterface() + ", apply this command: " + list); + } + } - public void updateTable(TableMetadata tmd, HelenusEntity entity) { - if (tmd == null) { - createTable(entity); - return; - } + public void updateTable(TableMetadata tmd, HelenusEntity entity) { + if (tmd == null) { + createTable(entity); + return; + } - executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); - executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); - } + executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); + executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); + } - public void createView(HelenusEntity entity) { - sessionOps.execute( - SchemaUtil.createMaterializedView( - sessionOps.usingKeyspace(), entity.getName().toCql(), entity), - true); - // executeBatch(SchemaUtil.createIndexes(entity)); NOTE: Unfortunately C* 3.10 does not yet support 2i on materialized views. - } + public void createView(HelenusEntity entity) { + sessionOps.execute( + SchemaUtil.createMaterializedView(sessionOps.usingKeyspace(), entity.getName().toCql(), entity), true); + // executeBatch(SchemaUtil.createIndexes(entity)); NOTE: Unfortunately C* 3.10 + // does not yet support 2i on materialized views. + } - public void dropView(HelenusEntity entity) { - sessionOps.execute( - SchemaUtil.dropMaterializedView( - sessionOps.usingKeyspace(), entity.getName().toCql(), entity), - true); - } + public void dropView(HelenusEntity entity) { + sessionOps.execute( + SchemaUtil.dropMaterializedView(sessionOps.usingKeyspace(), entity.getName().toCql(), entity), true); + } - public void updateView(TableMetadata tmd, HelenusEntity entity) { - if (tmd == null) { - createTable(entity); - return; - } + public void updateView(TableMetadata tmd, HelenusEntity entity) { + if (tmd == null) { + createTable(entity); + return; + } - executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); - executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); - } + executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); + executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); + } - private void executeBatch(List list) { + private void executeBatch(List list) { - list.forEach( - s -> { - sessionOps.execute(s, true); - }); - } + list.forEach(s -> { + sessionOps.execute(s, true); + }); + } } diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index f27b76c..6ff3496 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -15,42 +15,54 @@ */ package net.helenus.core; +import java.util.List; +import java.util.Optional; -import java.util.Map; -import java.util.Set; +import com.google.common.base.Stopwatch; -public interface UnitOfWork extends AutoCloseable { +import net.helenus.core.cache.Facet; - /** - * Marks the beginning of a transactional section of work. Will write a record to the shared - * write-ahead log. - * - * @return the handle used to commit or abort the work. - */ - UnitOfWork begin(); +public interface UnitOfWork extends AutoCloseable { - UnitOfWork addNestedUnitOfWork(UnitOfWork uow); + /** + * Marks the beginning of a transactional section of work. Will write a record + * to the shared write-ahead log. + * + * @return the handle used to commit or abort the work. + */ + UnitOfWork begin(); - /** - * Checks to see if the work performed between calling begin and now can be committed or not. - * - * @return a function from which to chain work that only happens when commit is successful - * @throws E when the work overlaps with other concurrent writers. - */ - PostCommitFunction commit() throws E; + void addNestedUnitOfWork(UnitOfWork uow); - /** - * Explicitly abort the work within this unit of work. Any nested aborted unit of work will - * trigger the entire unit of work to commit. - */ - void abort(); + /** + * Checks to see if the work performed between calling begin and now can be + * committed or not. + * + * @return a function from which to chain work that only happens when commit is + * successful + * @throws X + * when the work overlaps with other concurrent writers. + */ + PostCommitFunction commit() throws X; - boolean hasAborted(); + /** + * Explicitly abort the work within this unit of work. Any nested aborted unit + * of work will trigger the entire unit of work to commit. + */ + void abort(); - boolean hasCommitted(); + boolean hasAborted(); - //Either> cacheLookup(String key); - Set cacheLookup(String key); + boolean hasCommitted(); + + Optional cacheLookup(List facets); + + void cacheUpdate(Object pojo, List facets); + + UnitOfWork setPurpose(String purpose); + + Stopwatch getExecutionTimer(); + + Stopwatch getCacheLookupTimer(); - Map> getCache(); } diff --git a/src/main/java/net/helenus/core/UnitOfWorkImpl.java b/src/main/java/net/helenus/core/UnitOfWorkImpl.java index 52cae59..ce57ff9 100644 --- a/src/main/java/net/helenus/core/UnitOfWorkImpl.java +++ b/src/main/java/net/helenus/core/UnitOfWorkImpl.java @@ -19,8 +19,8 @@ import net.helenus.support.HelenusException; class UnitOfWorkImpl extends AbstractUnitOfWork { - @SuppressWarnings("unchecked") - public UnitOfWorkImpl(HelenusSession session, UnitOfWork parent) { - super(session, (AbstractUnitOfWork) parent); - } + @SuppressWarnings("unchecked") + public UnitOfWorkImpl(HelenusSession session, UnitOfWork parent) { + super(session, (AbstractUnitOfWork) parent); + } } diff --git a/src/main/java/net/helenus/core/UserTypeOperations.java b/src/main/java/net/helenus/core/UserTypeOperations.java index 2c18339..2b1ed32 100644 --- a/src/main/java/net/helenus/core/UserTypeOperations.java +++ b/src/main/java/net/helenus/core/UserTypeOperations.java @@ -15,65 +15,63 @@ */ package net.helenus.core; +import java.util.List; + import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.SchemaStatement; -import java.util.List; + import net.helenus.mapping.HelenusEntity; import net.helenus.support.HelenusException; public final class UserTypeOperations { - private final AbstractSessionOperations sessionOps; - private final boolean dropUnusedColumns; + private final AbstractSessionOperations sessionOps; + private final boolean dropUnusedColumns; - public UserTypeOperations(AbstractSessionOperations sessionOps, boolean dropUnusedColumns) { - this.sessionOps = sessionOps; - this.dropUnusedColumns = dropUnusedColumns; - } + public UserTypeOperations(AbstractSessionOperations sessionOps, boolean dropUnusedColumns) { + this.sessionOps = sessionOps; + this.dropUnusedColumns = dropUnusedColumns; + } - public void createUserType(HelenusEntity entity) { + public void createUserType(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.createUserType(entity), true); - } + sessionOps.execute(SchemaUtil.createUserType(entity), true); + } - public void dropUserType(HelenusEntity entity) { + public void dropUserType(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.dropUserType(entity), true); - } + sessionOps.execute(SchemaUtil.dropUserType(entity), true); + } - public void validateUserType(UserType userType, HelenusEntity entity) { + public void validateUserType(UserType userType, HelenusEntity entity) { - if (userType == null) { - throw new HelenusException( - "userType not exists " + entity.getName() + "for entity " + entity.getMappingInterface()); - } + if (userType == null) { + throw new HelenusException( + "userType not exists " + entity.getName() + "for entity " + entity.getMappingInterface()); + } - List list = SchemaUtil.alterUserType(userType, entity, dropUnusedColumns); + List list = SchemaUtil.alterUserType(userType, entity, dropUnusedColumns); - if (!list.isEmpty()) { - throw new HelenusException( - "schema changed for entity " - + entity.getMappingInterface() - + ", apply this command: " - + list); - } - } + if (!list.isEmpty()) { + throw new HelenusException( + "schema changed for entity " + entity.getMappingInterface() + ", apply this command: " + list); + } + } - public void updateUserType(UserType userType, HelenusEntity entity) { + public void updateUserType(UserType userType, HelenusEntity entity) { - if (userType == null) { - createUserType(entity); - return; - } + if (userType == null) { + createUserType(entity); + return; + } - executeBatch(SchemaUtil.alterUserType(userType, entity, dropUnusedColumns)); - } + executeBatch(SchemaUtil.alterUserType(userType, entity, dropUnusedColumns)); + } - private void executeBatch(List list) { + private void executeBatch(List list) { - list.forEach( - s -> { - sessionOps.execute(s, true); - }); - } + list.forEach(s -> { + sessionOps.execute(s, true); + }); + } } diff --git a/src/main/java/net/helenus/core/annotation/Cacheable.java b/src/main/java/net/helenus/core/annotation/Cacheable.java index 2160563..8202bdd 100644 --- a/src/main/java/net/helenus/core/annotation/Cacheable.java +++ b/src/main/java/net/helenus/core/annotation/Cacheable.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2015 The Helenus 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 net.helenus.core.annotation; import java.lang.annotation.ElementType; @@ -7,4 +22,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface Cacheable {} +public @interface Cacheable { +} diff --git a/src/main/java/net/helenus/core/annotation/Retry.java b/src/main/java/net/helenus/core/annotation/Retry.java index 14631da..7db5b20 100644 --- a/src/main/java/net/helenus/core/annotation/Retry.java +++ b/src/main/java/net/helenus/core/annotation/Retry.java @@ -4,13 +4,14 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; + import net.helenus.core.ConflictingUnitOfWorkException; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Retry { - Class[] on() default ConflictingUnitOfWorkException.class; + Class[] on() default ConflictingUnitOfWorkException.class; - int times() default 3; + int times() default 3; } diff --git a/src/main/java/net/helenus/core/aspect/RetryAspect.java b/src/main/java/net/helenus/core/aspect/RetryAspect.java new file mode 100644 index 0000000..587d087 --- /dev/null +++ b/src/main/java/net/helenus/core/aspect/RetryAspect.java @@ -0,0 +1,83 @@ +package net.helenus.core.aspect; + +import java.lang.reflect.Method; +import java.util.Arrays; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.util.Assert; + +import net.helenus.core.annotation.Retry; + +@Aspect +public class RetryAspect { + + private static final Logger log = LoggerFactory.getLogger(RetryAspect.class); + + @Around("@annotation(net.helenus.core.annotations.Retry)") + public Object retry(ProceedingJoinPoint pjp) throws Throwable { + Retry retryAnnotation = getRetryAnnotation(pjp); + return (retryAnnotation != null) ? proceed(pjp, retryAnnotation) : proceed(pjp); + } + + private Object proceed(ProceedingJoinPoint pjp) throws Throwable { + return pjp.proceed(); + } + + private Object proceed(ProceedingJoinPoint pjp, Retry retryAnnotation) throws Throwable { + int times = retryAnnotation.times(); + Class[] retryOn = retryAnnotation.on(); + Assert.isTrue(times > 0, "@Retry{times} should be greater than 0!"); + Assert.isTrue(retryOn.length > 0, "@Retry{on} should have at least one Throwable!"); + log.info("Proceed with {} retries on {}", times, Arrays.toString(retryOn)); + return tryProceeding(pjp, times, retryOn); + } + + private Object tryProceeding(ProceedingJoinPoint pjp, int times, Class[] retryOn) + throws Throwable { + try { + return proceed(pjp); + } catch (Throwable throwable) { + if (isRetryThrowable(throwable, retryOn) && times-- > 0) { + log.info("Conflict detected, {} remaining retries on {}", times, Arrays.toString(retryOn)); + return tryProceeding(pjp, times, retryOn); + } + throw throwable; + } + } + + private boolean isRetryThrowable(Throwable throwable, Class[] retryOn) { + Throwable[] causes = ExceptionUtils.getThrowables(throwable); + for (Throwable cause : causes) { + for (Class retryThrowable : retryOn) { + if (retryThrowable.isAssignableFrom(cause.getClass())) { + return true; + } + } + } + return false; + } + + private Retry getRetryAnnotation(ProceedingJoinPoint pjp) throws NoSuchMethodException { + MethodSignature signature = (MethodSignature) pjp.getSignature(); + Method method = signature.getMethod(); + Retry retryAnnotation = AnnotationUtils.findAnnotation(method, Retry.class); + + if (retryAnnotation != null) { + return retryAnnotation; + } + + Class[] argClasses = new Class[pjp.getArgs().length]; + for (int i = 0; i < pjp.getArgs().length; i++) { + argClasses[i] = pjp.getArgs()[i].getClass(); + } + method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argClasses); + return AnnotationUtils.findAnnotation(method, Retry.class); + } +} diff --git a/src/main/java/net/helenus/core/aspect/RetryConcurrentUnitOfWorkAspect.java b/src/main/java/net/helenus/core/aspect/RetryConcurrentUnitOfWorkAspect.java index 7d52f16..d2ad9a4 100644 --- a/src/main/java/net/helenus/core/aspect/RetryConcurrentUnitOfWorkAspect.java +++ b/src/main/java/net/helenus/core/aspect/RetryConcurrentUnitOfWorkAspect.java @@ -2,7 +2,7 @@ package net.helenus.core.aspect; import java.lang.reflect.Method; import java.util.Arrays; -import net.helenus.core.annotation.Retry; + import org.apache.commons.lang3.exception.ExceptionUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -13,69 +13,71 @@ import org.slf4j.LoggerFactory; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; +import net.helenus.core.annotation.Retry; + @Aspect public class RetryConcurrentUnitOfWorkAspect { - private static final Logger log = LoggerFactory.getLogger(RetryConcurrentUnitOfWorkAspect.class); + private static final Logger log = LoggerFactory.getLogger(RetryConcurrentUnitOfWorkAspect.class); - @Around("@annotation(net.helenus.core.annotations.Retry)") - public Object retry(ProceedingJoinPoint pjp) throws Throwable { - Retry retryAnnotation = getRetryAnnotation(pjp); - return (retryAnnotation != null) ? proceed(pjp, retryAnnotation) : proceed(pjp); - } + @Around("@annotation(net.helenus.core.annotations.Retry)") + public Object retry(ProceedingJoinPoint pjp) throws Throwable { + Retry retryAnnotation = getRetryAnnotation(pjp); + return (retryAnnotation != null) ? proceed(pjp, retryAnnotation) : proceed(pjp); + } - private Object proceed(ProceedingJoinPoint pjp) throws Throwable { - return pjp.proceed(); - } + private Object proceed(ProceedingJoinPoint pjp) throws Throwable { + return pjp.proceed(); + } - private Object proceed(ProceedingJoinPoint pjp, Retry retryAnnotation) throws Throwable { - int times = retryAnnotation.times(); - Class[] retryOn = retryAnnotation.on(); - Assert.isTrue(times > 0, "@Retry{times} should be greater than 0!"); - Assert.isTrue(retryOn.length > 0, "@Retry{on} should have at least one Throwable!"); - log.info("Proceed with {} retries on {}", times, Arrays.toString(retryOn)); - return tryProceeding(pjp, times, retryOn); - } + private Object proceed(ProceedingJoinPoint pjp, Retry retryAnnotation) throws Throwable { + int times = retryAnnotation.times(); + Class[] retryOn = retryAnnotation.on(); + Assert.isTrue(times > 0, "@Retry{times} should be greater than 0!"); + Assert.isTrue(retryOn.length > 0, "@Retry{on} should have at least one Throwable!"); + log.info("Proceed with {} retries on {}", times, Arrays.toString(retryOn)); + return tryProceeding(pjp, times, retryOn); + } - private Object tryProceeding( - ProceedingJoinPoint pjp, int times, Class[] retryOn) throws Throwable { - try { - return proceed(pjp); - } catch (Throwable throwable) { - if (isRetryThrowable(throwable, retryOn) && times-- > 0) { - log.info("Conflict detected, {} remaining retries on {}", times, Arrays.toString(retryOn)); - return tryProceeding(pjp, times, retryOn); - } - throw throwable; - } - } + private Object tryProceeding(ProceedingJoinPoint pjp, int times, Class[] retryOn) + throws Throwable { + try { + return proceed(pjp); + } catch (Throwable throwable) { + if (isRetryThrowable(throwable, retryOn) && times-- > 0) { + log.info("Conflict detected, {} remaining retries on {}", times, Arrays.toString(retryOn)); + return tryProceeding(pjp, times, retryOn); + } + throw throwable; + } + } - private boolean isRetryThrowable(Throwable throwable, Class[] retryOn) { - Throwable[] causes = ExceptionUtils.getThrowables(throwable); - for (Throwable cause : causes) { - for (Class retryThrowable : retryOn) { - if (retryThrowable.isAssignableFrom(cause.getClass())) { - return true; - } - } - } - return false; - } + private boolean isRetryThrowable(Throwable throwable, Class[] retryOn) { + Throwable[] causes = ExceptionUtils.getThrowables(throwable); + for (Throwable cause : causes) { + for (Class retryThrowable : retryOn) { + if (retryThrowable.isAssignableFrom(cause.getClass())) { + return true; + } + } + } + return false; + } - private Retry getRetryAnnotation(ProceedingJoinPoint pjp) throws NoSuchMethodException { - MethodSignature signature = (MethodSignature) pjp.getSignature(); - Method method = signature.getMethod(); - Retry retryAnnotation = AnnotationUtils.findAnnotation(method, Retry.class); + private Retry getRetryAnnotation(ProceedingJoinPoint pjp) throws NoSuchMethodException { + MethodSignature signature = (MethodSignature) pjp.getSignature(); + Method method = signature.getMethod(); + Retry retryAnnotation = AnnotationUtils.findAnnotation(method, Retry.class); - if (retryAnnotation != null) { - return retryAnnotation; - } + if (retryAnnotation != null) { + return retryAnnotation; + } - Class[] argClasses = new Class[pjp.getArgs().length]; - for (int i = 0; i < pjp.getArgs().length; i++) { - argClasses[i] = pjp.getArgs()[i].getClass(); - } - method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argClasses); - return AnnotationUtils.findAnnotation(method, Retry.class); - } + Class[] argClasses = new Class[pjp.getArgs().length]; + for (int i = 0; i < pjp.getArgs().length; i++) { + argClasses[i] = pjp.getArgs()[i].getClass(); + } + method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argClasses); + return AnnotationUtils.findAnnotation(method, Retry.class); + } } diff --git a/src/main/java/net/helenus/core/cache/BoundFacet.java b/src/main/java/net/helenus/core/cache/BoundFacet.java new file mode 100644 index 0000000..905a67f --- /dev/null +++ b/src/main/java/net/helenus/core/cache/BoundFacet.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 The Helenus 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 net.helenus.core.cache; + +import java.util.Map; +import java.util.stream.Collectors; + +import net.helenus.mapping.HelenusProperty; + +public class BoundFacet extends Facet { + private final Map properties; + + BoundFacet(String name, Map properties) { + super(name, + (properties.keySet().size() > 1) + ? "[" + String.join(", ", + properties.keySet().stream().map(key -> properties.get(key).toString()) + .collect(Collectors.toSet())) + + "]" + : String.join("", properties.keySet().stream().map(key -> properties.get(key).toString()) + .collect(Collectors.toSet()))); + this.properties = properties; + } + +} diff --git a/src/main/java/net/helenus/core/cache/CacheUtil.java b/src/main/java/net/helenus/core/cache/CacheUtil.java new file mode 100644 index 0000000..37dbc30 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/CacheUtil.java @@ -0,0 +1,49 @@ +package net.helenus.core.cache; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class CacheUtil { + + public static List combinations(List items) { + int n = items.size(); + if (n > 20 || n < 0) + throw new IllegalArgumentException(n + " is out of range"); + long e = Math.round(Math.pow(2, n)); + List out = new ArrayList((int) e - 1); + for (int k = 1; k <= items.size(); k++) { + kCombinations(items, 0, k, new String[k], out); + } + return out; + } + + private static void kCombinations(List items, int n, int k, String[] arr, List out) { + if (k == 0) { + out.add(arr.clone()); + } else { + for (int i = n; i <= items.size() - k; i++) { + arr[arr.length - k] = items.get(i); + kCombinations(items, i + 1, k - 1, arr, out); + } + } + } + + public static List flattenFacets(List facets) { + List combinations = CacheUtil.combinations( + facets.stream().filter(facet -> !facet.fixed()).filter(facet -> facet.value() != null).map(facet -> { + return facet.name() + "==" + facet.value(); + }).collect(Collectors.toList())); + return combinations; + } + + public static Object merge(Object to, Object from) { + return to; // TODO(gburd): yeah... + } + + public static String schemaName(List facets) { + return facets.stream().filter(Facet::fixed).map(facet -> facet.value().toString()) + .collect(Collectors.joining(".")); + } + +} diff --git a/src/main/java/net/helenus/core/cache/Facet.java b/src/main/java/net/helenus/core/cache/Facet.java new file mode 100644 index 0000000..4f74ab5 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/Facet.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 The Helenus 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 net.helenus.core.cache; + +/** + * An Entity is identifiable via one or more Facets + */ +public class Facet { + private final String name; + private T value; + private boolean fixed = false; + + public Facet(String name) { + this.name = name; + } + + public Facet(String name, T value) { + this.name = name; + this.value = value; + } + + public String name() { + return name; + } + + public T value() { + return value; + } + + public Facet setFixed() { + fixed = true; + return this; + } + + public boolean fixed() { + return fixed; + } + +} diff --git a/src/main/java/net/helenus/core/cache/UnboundFacet.java b/src/main/java/net/helenus/core/cache/UnboundFacet.java new file mode 100644 index 0000000..e2b618b --- /dev/null +++ b/src/main/java/net/helenus/core/cache/UnboundFacet.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 The Helenus 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 net.helenus.core.cache; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.helenus.core.SchemaUtil; +import net.helenus.mapping.HelenusProperty; + +public class UnboundFacet extends Facet { + + private final List properties; + + public UnboundFacet(List properties) { + super(SchemaUtil.createPrimaryKeyPhrase(properties)); + this.properties = properties; + } + + public UnboundFacet(HelenusProperty property) { + super(property.getPropertyName()); + properties = new ArrayList(); + properties.add(property); + } + + public List getProperties() { + return properties; + } + + public Binder binder() { + return new Binder(name(), properties); + } + + public static class Binder { + + private final String name; + private final List properties = new ArrayList(); + private Map boundProperties = new HashMap(); + + Binder(String name, List properties) { + this.name = name; + this.properties.addAll(properties); + } + + public Binder setValueForProperty(HelenusProperty prop, Object value) { + properties.remove(prop); + boundProperties.put(prop, value); + return this; + } + + public boolean isBound() { + return properties.isEmpty(); + } + + public BoundFacet bind() { + return new BoundFacet(name, boundProperties); + } + } +} diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java index 75c8979..c7a4787 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java @@ -17,92 +17,94 @@ package net.helenus.core.operation; import java.util.LinkedList; import java.util.List; + import net.helenus.core.*; public abstract class AbstractFilterOperation> - extends AbstractOperation { + extends + AbstractOperation { - protected List> filters = null; - protected List> ifFilters = null; + protected List> filters = null; + protected List> ifFilters = null; - public AbstractFilterOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractFilterOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public O where(Getter getter, Postulate postulate) { + public O where(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O where(Getter getter, Operator operator, V val) { + public O where(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O where(Filter filter) { + public O where(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Postulate postulate) { + public O and(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Operator operator, V val) { + public O and(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O and(Filter filter) { + public O and(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Postulate postulate) { + public O onlyIf(Getter getter, Postulate postulate) { - addIfFilter(Filter.create(getter, postulate)); + addIfFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Operator operator, V val) { + public O onlyIf(Getter getter, Operator operator, V val) { - addIfFilter(Filter.create(getter, operator, val)); + addIfFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Filter filter) { + public O onlyIf(Filter filter) { - addIfFilter(filter); + addIfFilter(filter); - return (O) this; - } + return (O) this; + } - private void addFilter(Filter filter) { - if (filters == null) { - filters = new LinkedList>(); - } - filters.add(filter); - } + private void addFilter(Filter filter) { + if (filters == null) { + filters = new LinkedList>(); + } + filters.add(filter); + } - private void addIfFilter(Filter filter) { - if (ifFilters == null) { - ifFilters = new LinkedList>(); - } - ifFilters.add(filter); - } + private void addIfFilter(Filter filter) { + if (ifFilters == null) { + ifFilters = new LinkedList>(); + } + ifFilters.add(filter); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java index 6abfd81..83374aa 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java @@ -19,94 +19,95 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; + import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterOptionalOperation< - E, O extends AbstractFilterOptionalOperation> - extends AbstractOptionalOperation { +public abstract class AbstractFilterOptionalOperation> + extends + AbstractOptionalOperation { - protected Map> filters = null; - protected List> ifFilters = null; + protected Map> filters = null; + protected List> ifFilters = null; - public AbstractFilterOptionalOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractFilterOptionalOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public O where(Getter getter, Postulate postulate) { + public O where(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O where(Getter getter, Operator operator, V val) { + public O where(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O where(Filter filter) { + public O where(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Postulate postulate) { + public O and(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Operator operator, V val) { + public O and(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O and(Filter filter) { + public O and(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Postulate postulate) { + public O onlyIf(Getter getter, Postulate postulate) { - addIfFilter(Filter.create(getter, postulate)); + addIfFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Operator operator, V val) { + public O onlyIf(Getter getter, Operator operator, V val) { - addIfFilter(Filter.create(getter, operator, val)); + addIfFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Filter filter) { + public O onlyIf(Filter filter) { - addIfFilter(filter); + addIfFilter(filter); - return (O) this; - } + return (O) this; + } - private void addFilter(Filter filter) { - if (filters == null) { - filters = new LinkedHashMap>(); - } - filters.put(filter.getNode().getProperty(), filter); - } + private void addFilter(Filter filter) { + if (filters == null) { + filters = new LinkedHashMap>(); + } + filters.put(filter.getNode().getProperty(), filter); + } - private void addIfFilter(Filter filter) { - if (ifFilters == null) { - ifFilters = new LinkedList>(); - } - ifFilters.add(filter); - } + private void addIfFilter(Filter filter) { + if (ifFilters == null) { + ifFilters = new LinkedList>(); + } + ifFilters.add(filter); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java index b78daf1..519f421 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java @@ -19,94 +19,95 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; + import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterStreamOperation< - E, O extends AbstractFilterStreamOperation> - extends AbstractStreamOperation { +public abstract class AbstractFilterStreamOperation> + extends + AbstractStreamOperation { - protected Map> filters = null; - protected List> ifFilters = null; + protected Map> filters = null; + protected List> ifFilters = null; - public AbstractFilterStreamOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractFilterStreamOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public O where(Getter getter, Postulate postulate) { + public O where(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O where(Getter getter, Operator operator, V val) { + public O where(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O where(Filter filter) { + public O where(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Postulate postulate) { + public O and(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Operator operator, V val) { + public O and(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O and(Filter filter) { + public O and(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Postulate postulate) { + public O onlyIf(Getter getter, Postulate postulate) { - addIfFilter(Filter.create(getter, postulate)); + addIfFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Operator operator, V val) { + public O onlyIf(Getter getter, Operator operator, V val) { - addIfFilter(Filter.create(getter, operator, val)); + addIfFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Filter filter) { + public O onlyIf(Filter filter) { - addIfFilter(filter); + addIfFilter(filter); - return (O) this; - } + return (O) this; + } - private void addFilter(Filter filter) { - if (filters == null) { - filters = new LinkedHashMap>(); - } - filters.put(filter.getNode().getProperty(), filter); - } + private void addFilter(Filter filter) { + if (filters == null) { + filters = new LinkedHashMap>(); + } + filters.put(filter.getNode().getProperty(), filter); + } - private void addIfFilter(Filter filter) { - if (ifFilters == null) { - ifFilters = new LinkedList>(); - } - ifFilters.add(filter); - } + private void addIfFilter(Filter filter) { + if (ifFilters == null) { + ifFilters = new LinkedList>(); + } + ifFilters.add(filter); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index 8eb7961..4afbdc0 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -15,58 +15,75 @@ */ package net.helenus.core.operation; +import java.util.concurrent.CompletableFuture; + import com.codahale.metrics.Timer; import com.datastax.driver.core.ResultSet; -import java.util.concurrent.CompletableFuture; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; -public abstract class AbstractOperation> - extends AbstractStatementOperation { +public abstract class AbstractOperation> extends AbstractStatementOperation { - public abstract E transform(ResultSet resultSet); + public AbstractOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public boolean cacheable() { - return false; - } + public abstract E transform(ResultSet resultSet); - public AbstractOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public boolean cacheable() { + return false; + } - public PreparedOperation prepare() { - return new PreparedOperation(prepareStatement(), this); - } + public PreparedOperation prepare() { + return new PreparedOperation(prepareStatement(), this); + } - public E sync() { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = this.execute(sessionOps, null, traceContext, showValues, false); - return transform(resultSet); - } finally { - context.stop(); - } - } + public E sync() {// throws TimeoutException { + final Timer.Context context = requestLatency.time(); + try { + ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, false); + return transform(resultSet); + } finally { + context.stop(); + } + } - public E sync(UnitOfWork uow) { - if (uow == null) return sync(); + public E sync(UnitOfWork uow) {// throws TimeoutException { + if (uow == null) + return sync(); - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = execute(sessionOps, uow, traceContext, showValues, true); - E result = transform(resultSet); - return result; - } finally { - context.stop(); - } - } + final Timer.Context context = requestLatency.time(); + try { + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); + E result = transform(resultSet); + return result; + } finally { + context.stop(); + } + } - public CompletableFuture async() { - return CompletableFuture.supplyAsync(() -> sync()); - } + public CompletableFuture async() { + return CompletableFuture.supplyAsync(() -> { + // try { + return sync(); + // } catch (TimeoutException ex) { + // throw new CompletionException(ex); + // } + }); + } - public CompletableFuture async(UnitOfWork uow) { - if (uow == null) return async(); - return CompletableFuture.supplyAsync(() -> sync(uow)); - } + public CompletableFuture async(UnitOfWork uow) { + if (uow == null) + return async(); + return CompletableFuture.supplyAsync(() -> { + // try { + return sync(); + // } catch (TimeoutException ex) { + // throw new CompletionException(ex); + // } + }); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index 1d34223..fb37c63 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -15,101 +15,158 @@ */ package net.helenus.core.operation; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + import com.codahale.metrics.Timer; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; +import com.google.common.base.Stopwatch; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.CacheUtil; +import net.helenus.core.cache.Facet; public abstract class AbstractOptionalOperation> - extends AbstractStatementOperation { + extends + AbstractStatementOperation { - public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public abstract Optional transform(ResultSet resultSet); + public abstract Optional transform(ResultSet resultSet); - public PreparedOptionalOperation prepare() { - return new PreparedOptionalOperation(prepareStatement(), this); - } + public PreparedOptionalOperation prepare() { + return new PreparedOptionalOperation(prepareStatement(), this); + } - public ListenableFuture> prepareAsync() { - final O _this = (O) this; - return Futures.transform( - prepareStatementAsync(), - new Function>() { - @Override - public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { - return new PreparedOptionalOperation(preparedStatement, _this); - } - }); - } + public ListenableFuture> prepareAsync() { + final O _this = (O) this; + return Futures.transform(prepareStatementAsync(), + new Function>() { + @Override + public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { + return new PreparedOptionalOperation(preparedStatement, _this); + } + }); + } - public Optional sync() { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = this.execute(sessionOps, null, traceContext, showValues, false); - return transform(resultSet); - } finally { - context.stop(); - } - } + public Optional sync() {// throws TimeoutException { + final Timer.Context context = requestLatency.time(); + try { + Optional result = Optional.empty(); + E cacheResult = null; + boolean updateCache = isSessionCacheable(); - public Optional sync(UnitOfWork uow) { - if (uow == null) return sync(); + if (enableCache && isSessionCacheable()) { + List facets = bindFacetValues(); + String tableName = CacheUtil.schemaName(facets); + cacheResult = (E) sessionOps.checkCache(tableName, facets); + if (cacheResult != null) { + result = Optional.of(cacheResult); + updateCache = false; + } + } - final Timer.Context context = requestLatency.time(); - try { + if (!result.isPresent()) { + // Formulate the query and execute it against the Cassandra cluster. + ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, + queryTimeoutUnits, showValues, false); - Optional result = null; - String key = getStatementCacheKey(); - if (enableCache && key != null) { - Set cachedResult = (Set) uow.cacheLookup(key); - if (cachedResult != null) { - //TODO(gburd): what about select ResultSet, Tuple... etc.? - uowCacheHits.mark(); - logger.info("UOW({}) cache hit, {}", uow.hashCode(), key); - result = cachedResult.stream().findFirst(); - } else { - uowCacheMiss.mark(); - } - } + // Transform the query result set into the desired shape. + result = transform(resultSet); + } - if (result == null) { - ResultSet resultSet = execute(sessionOps, uow, traceContext, showValues, true); - result = transform(resultSet); + if (updateCache && result.isPresent()) { + List facets = getFacets(); + if (facets != null && facets.size() > 1) { + sessionOps.updateCache(result.get(), facets); + } + } + return result; + } finally { + context.stop(); + } + } - if (key != null) { - if (result.isPresent()) { - Set set = new HashSet(1); - set.add(result.get()); - uow.getCache().put(key, set); - } else { - uow.getCache().put(key, new HashSet(0)); - } - } - } + public Optional sync(UnitOfWork uow) {// throws TimeoutException { + if (uow == null) + return sync(); - return result; - } finally { - context.stop(); - } - } + final Timer.Context context = requestLatency.time(); + try { - public CompletableFuture> async() { - return CompletableFuture.>supplyAsync(() -> sync()); - } + Optional result = Optional.empty(); + E cacheResult = null; + boolean updateCache = true; - public CompletableFuture> async(UnitOfWork uow) { - if (uow == null) return async(); - return CompletableFuture.>supplyAsync(() -> sync(uow)); - } + if (enableCache) { + Stopwatch timer = uow.getCacheLookupTimer(); + timer.start(); + List facets = bindFacetValues(); + cacheResult = checkCache(uow, facets); + if (cacheResult != null) { + result = Optional.of(cacheResult); + updateCache = false; + } else { + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cacheResult = (E) sessionOps.checkCache(tableName, facets); + if (cacheResult != null) { + result = Optional.of(cacheResult); + } + } + } + timer.stop(); + } + + if (!result.isPresent()) { + // Formulate the query and execute it against the Cassandra cluster. + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); + + // Transform the query result set into the desired shape. + result = transform(resultSet); + } + + // If we have a result, it wasn't from the UOW cache, and we're caching things + // then we + // need to put this result into the cache for future requests to find. + if (updateCache && result.isPresent()) { + updateCache(uow, result.get(), getFacets()); + } + + return result; + } finally { + context.stop(); + } + } + + public CompletableFuture> async() { + return CompletableFuture.>supplyAsync(() -> { + // try { + return sync(); + // } catch (TimeoutException ex) { + // throw new CompletionException(ex); + // } + }); + } + + public CompletableFuture> async(UnitOfWork uow) { + if (uow == null) + return async(); + return CompletableFuture.>supplyAsync(() -> { + // try { + return sync(); + // } catch (TimeoutException ex) { + // throw new CompletionException(ex); + // } + }); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 5177724..c46a0f0 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -15,8 +15,15 @@ */ package net.helenus.core.operation; -import brave.Tracer; -import brave.propagation.TraceContext; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.RegularStatement; @@ -27,268 +34,335 @@ import com.datastax.driver.core.policies.FallthroughRetryPolicy; import com.datastax.driver.core.policies.RetryPolicy; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.util.concurrent.ListenableFuture; + +import brave.Tracer; +import brave.propagation.TraceContext; import net.helenus.core.AbstractSessionOperations; +import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.UnboundFacet; +import net.helenus.core.reflect.MapExportable; +import net.helenus.mapping.value.BeanColumnValueProvider; import net.helenus.support.HelenusException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -public abstract class AbstractStatementOperation> - extends Operation { +public abstract class AbstractStatementOperation> extends Operation { - final Logger logger = LoggerFactory.getLogger(getClass()); + private static final Logger LOG = LoggerFactory.getLogger(AbstractStatementOperation.class); - public abstract Statement buildStatement(boolean cached); + protected boolean enableCache = true; + protected boolean showValues = true; + protected TraceContext traceContext; + long queryExecutionTimeout = 10; + TimeUnit queryTimeoutUnits = TimeUnit.SECONDS; + private ConsistencyLevel consistencyLevel; + private ConsistencyLevel serialConsistencyLevel; + private RetryPolicy retryPolicy; + private boolean idempotent = false; + private boolean enableTracing = false; + private long[] defaultTimestamp = null; + private int[] fetchSize = null; - protected boolean enableCache = true; - protected boolean showValues = true; - protected TraceContext traceContext; - private ConsistencyLevel consistencyLevel; - private ConsistencyLevel serialConsistencyLevel; - private RetryPolicy retryPolicy; - private boolean idempotent = false; - private boolean enableTracing = false; - private long[] defaultTimestamp = null; - private int[] fetchSize = null; + public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); + this.idempotent = sessionOperations.getDefaultQueryIdempotency(); + } - public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); - this.idempotent = sessionOperations.getDefaultQueryIdempotency(); - } + public abstract Statement buildStatement(boolean cached); - public O ignoreCache(boolean enabled) { - enableCache = enabled; - return (O) this; - } + public O ignoreCache(boolean enabled) { + enableCache = enabled; + return (O) this; + } - public O ignoreCache() { - enableCache = true; - return (O) this; - } + public O ignoreCache() { + enableCache = true; + return (O) this; + } - public O showValues(boolean enabled) { - this.showValues = enabled; - return (O) this; - } + public O showValues(boolean enabled) { + this.showValues = enabled; + return (O) this; + } - public O defaultTimestamp(long timestamp) { - this.defaultTimestamp = new long[1]; - this.defaultTimestamp[0] = timestamp; - return (O) this; - } + public O defaultTimestamp(long timestamp) { + this.defaultTimestamp = new long[1]; + this.defaultTimestamp[0] = timestamp; + return (O) this; + } - public O retryPolicy(RetryPolicy retryPolicy) { - this.retryPolicy = retryPolicy; - return (O) this; - } + public O retryPolicy(RetryPolicy retryPolicy) { + this.retryPolicy = retryPolicy; + return (O) this; + } - public O defaultRetryPolicy() { - this.retryPolicy = DefaultRetryPolicy.INSTANCE; - return (O) this; - } + public O defaultRetryPolicy() { + this.retryPolicy = DefaultRetryPolicy.INSTANCE; + return (O) this; + } - public O idempotent() { - this.idempotent = true; - return (O) this; - } + public O idempotent() { + this.idempotent = true; + return (O) this; + } - public O isIdempotent(boolean idempotent) { - this.idempotent = idempotent; - return (O) this; - } + public O isIdempotent(boolean idempotent) { + this.idempotent = idempotent; + return (O) this; + } - public O downgradingConsistencyRetryPolicy() { - this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; - return (O) this; - } + public O downgradingConsistencyRetryPolicy() { + this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; + return (O) this; + } - public O fallthroughRetryPolicy() { - this.retryPolicy = FallthroughRetryPolicy.INSTANCE; - return (O) this; - } + public O fallthroughRetryPolicy() { + this.retryPolicy = FallthroughRetryPolicy.INSTANCE; + return (O) this; + } - public O consistency(ConsistencyLevel level) { - this.consistencyLevel = level; - return (O) this; - } + public O consistency(ConsistencyLevel level) { + this.consistencyLevel = level; + return (O) this; + } - public O consistencyAny() { - this.consistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } + public O consistencyAny() { + this.consistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } - public O consistencyOne() { - this.consistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } + public O consistencyOne() { + this.consistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } - public O consistencyQuorum() { - this.consistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } + public O consistencyQuorum() { + this.consistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } - public O consistencyAll() { - this.consistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } + public O consistencyAll() { + this.consistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } - public O consistencyLocalOne() { - this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; - return (O) this; - } + public O consistencyLocalOne() { + this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; + return (O) this; + } - public O consistencyLocalQuorum() { - this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } + public O consistencyLocalQuorum() { + this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } - public O consistencyEachQuorum() { - this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; - return (O) this; - } + public O consistencyEachQuorum() { + this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; + return (O) this; + } - public O serialConsistency(ConsistencyLevel level) { - this.serialConsistencyLevel = level; - return (O) this; - } + public O serialConsistency(ConsistencyLevel level) { + this.serialConsistencyLevel = level; + return (O) this; + } - public O serialConsistencyAny() { - this.serialConsistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } + public O serialConsistencyAny() { + this.serialConsistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } - public O serialConsistencyOne() { - this.serialConsistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } + public O serialConsistencyOne() { + this.serialConsistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } - public O serialConsistencyQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } + public O serialConsistencyQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } - public O serialConsistencyAll() { - this.serialConsistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } + public O serialConsistencyAll() { + this.serialConsistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } - public O serialConsistencyLocal() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; - return (O) this; - } + public O serialConsistencyLocal() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; + return (O) this; + } - public O serialConsistencyLocalQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } + public O serialConsistencyLocalQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } - public O disableTracing() { - this.enableTracing = false; - return (O) this; - } + public O disableTracing() { + this.enableTracing = false; + return (O) this; + } - public O enableTracing() { - this.enableTracing = true; - return (O) this; - } + public O enableTracing() { + this.enableTracing = true; + return (O) this; + } - public O tracing(boolean enable) { - this.enableTracing = enable; - return (O) this; - } + public O tracing(boolean enable) { + this.enableTracing = enable; + return (O) this; + } - public O fetchSize(int fetchSize) { - this.fetchSize = new int[1]; - this.fetchSize[0] = fetchSize; - return (O) this; - } + public O fetchSize(int fetchSize) { + this.fetchSize = new int[1]; + this.fetchSize[0] = fetchSize; + return (O) this; + } - public Statement options(Statement statement) { + public O queryTimeoutMs(long ms) { + this.queryExecutionTimeout = ms; + this.queryTimeoutUnits = TimeUnit.MILLISECONDS; + return (O) this; + } - if (defaultTimestamp != null) { - statement.setDefaultTimestamp(defaultTimestamp[0]); - } + public O queryTimeout(long timeout, TimeUnit units) { + this.queryExecutionTimeout = timeout; + this.queryTimeoutUnits = units; + return (O) this; + } - if (consistencyLevel != null) { - statement.setConsistencyLevel(consistencyLevel); - } + public Statement options(Statement statement) { - if (serialConsistencyLevel != null) { - statement.setSerialConsistencyLevel(serialConsistencyLevel); - } + if (defaultTimestamp != null) { + statement.setDefaultTimestamp(defaultTimestamp[0]); + } - if (retryPolicy != null) { - statement.setRetryPolicy(retryPolicy); - } + if (consistencyLevel != null) { + statement.setConsistencyLevel(consistencyLevel); + } - if (enableTracing) { - statement.enableTracing(); - } else { - statement.disableTracing(); - } + if (serialConsistencyLevel != null) { + statement.setSerialConsistencyLevel(serialConsistencyLevel); + } - if (fetchSize != null) { - statement.setFetchSize(fetchSize[0]); - } + if (retryPolicy != null) { + statement.setRetryPolicy(retryPolicy); + } - if (idempotent) { - statement.setIdempotent(true); - } + if (enableTracing) { + statement.enableTracing(); + } else { + statement.disableTracing(); + } - return statement; - } + if (fetchSize != null) { + statement.setFetchSize(fetchSize[0]); + } - public O zipkinContext(TraceContext traceContext) { - if (traceContext != null) { - Tracer tracer = this.sessionOps.getZipkinTracer(); - if (tracer != null) { - this.traceContext = traceContext; - } - } + if (idempotent) { + statement.setIdempotent(true); + } - return (O) this; - } + return statement; + } - public Statement statement() { - return buildStatement(false); - } + public O zipkinContext(TraceContext traceContext) { + if (traceContext != null) { + Tracer tracer = this.sessionOps.getZipkinTracer(); + if (tracer != null) { + this.traceContext = traceContext; + } + } - public String cql() { - Statement statement = buildStatement(false); - if (statement == null) return ""; - if (statement instanceof BuiltStatement) { - BuiltStatement buildStatement = (BuiltStatement) statement; - return buildStatement.setForceNoValues(true).getQueryString(); - } else { - return statement.toString(); - } - } + return (O) this; + } - public PreparedStatement prepareStatement() { + public Statement statement() { + return buildStatement(false); + } - Statement statement = buildStatement(true); + public String cql() { + Statement statement = buildStatement(false); + if (statement == null) + return ""; + if (statement instanceof BuiltStatement) { + BuiltStatement buildStatement = (BuiltStatement) statement; + return buildStatement.setForceNoValues(true).getQueryString(); + } else { + return statement.toString(); + } + } - if (statement instanceof RegularStatement) { + public PreparedStatement prepareStatement() { - RegularStatement regularStatement = (RegularStatement) statement; + Statement statement = buildStatement(true); - return sessionOps.prepare(regularStatement); - } + if (statement instanceof RegularStatement) { - throw new HelenusException("only RegularStatements can be prepared"); - } + RegularStatement regularStatement = (RegularStatement) statement; - public ListenableFuture prepareStatementAsync() { + return sessionOps.prepare(regularStatement); + } - Statement statement = buildStatement(true); + throw new HelenusException("only RegularStatements can be prepared"); + } - if (statement instanceof RegularStatement) { + public ListenableFuture prepareStatementAsync() { - RegularStatement regularStatement = (RegularStatement) statement; + Statement statement = buildStatement(true); - return sessionOps.prepareAsync(regularStatement); - } + if (statement instanceof RegularStatement) { - throw new HelenusException("only RegularStatements can be prepared"); - } + RegularStatement regularStatement = (RegularStatement) statement; + + return sessionOps.prepareAsync(regularStatement); + } + + throw new HelenusException("only RegularStatements can be prepared"); + } + + protected E checkCache(UnitOfWork uow, List facets) { + E result = null; + Optional optionalCachedResult = Optional.empty(); + + if (!facets.isEmpty()) { + optionalCachedResult = uow.cacheLookup(facets); + if (optionalCachedResult.isPresent()) { + uowCacheHits.mark(); + LOG.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); + result = (E) optionalCachedResult.get(); + } + } + + if (result == null) { + uowCacheMiss.mark(); + LOG.info("UnitOfWork({}) cache miss", uow.hashCode()); + } + + return result; + } + + protected void updateCache(UnitOfWork uow, E pojo, List identifyingFacets) { + List facets = new ArrayList<>(); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + + for (Facet facet : identifyingFacets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + facets.add(binder.bind()); + }); + } else { + facets.add(facet); + } + } + + // Cache the value (pojo), the statement key, and the fully bound facets. + uow.cacheUpdate(pojo, facets); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index 2db668a..05201ab 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -15,93 +15,158 @@ */ package net.helenus.core.operation; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; + import com.codahale.metrics.Timer; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; +import com.google.common.base.Stopwatch; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Stream; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.CacheUtil; +import net.helenus.core.cache.Facet; public abstract class AbstractStreamOperation> - extends AbstractStatementOperation { + extends + AbstractStatementOperation { - public AbstractStreamOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractStreamOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public abstract Stream transform(ResultSet resultSet); + public abstract Stream transform(ResultSet resultSet); - public PreparedStreamOperation prepare() { - return new PreparedStreamOperation(prepareStatement(), this); - } + public PreparedStreamOperation prepare() { + return new PreparedStreamOperation(prepareStatement(), this); + } - public ListenableFuture> prepareAsync() { - final O _this = (O) this; - return Futures.transform( - prepareStatementAsync(), - new Function>() { - @Override - public PreparedStreamOperation apply(PreparedStatement preparedStatement) { - return new PreparedStreamOperation(preparedStatement, _this); - } - }); - } + public ListenableFuture> prepareAsync() { + final O _this = (O) this; + return Futures.transform(prepareStatementAsync(), + new Function>() { + @Override + public PreparedStreamOperation apply(PreparedStatement preparedStatement) { + return new PreparedStreamOperation(preparedStatement, _this); + } + }); + } - public Stream sync() { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = this.execute(sessionOps, null, traceContext, showValues, false); - return transform(resultSet); - } finally { - context.stop(); - } - } + public Stream sync() {// throws TimeoutException { + final Timer.Context context = requestLatency.time(); + try { + Stream resultStream = null; + E cacheResult = null; + boolean updateCache = isSessionCacheable(); - public Stream sync(UnitOfWork uow) { - if (uow == null) return sync(); + if (enableCache && isSessionCacheable()) { + List facets = bindFacetValues(); + String tableName = CacheUtil.schemaName(facets); + cacheResult = (E) sessionOps.checkCache(tableName, facets); + if (cacheResult != null) { + resultStream = Stream.of(cacheResult); + updateCache = false; + } + } - final Timer.Context context = requestLatency.time(); - try { - Stream result = null; - String key = getStatementCacheKey(); - if (enableCache && key != null) { - Set cachedResult = (Set) uow.cacheLookup(key); - if (cachedResult != null) { - //TODO(gburd): what about select ResultSet, Tuple... etc.? - uowCacheHits.mark(); - logger.info("UOW({}) cache hit, {}", uow.hashCode()); - result = cachedResult.stream(); - } else { - uowCacheMiss.mark(); - } - } + if (resultStream == null) { + // Formulate the query and execute it against the Cassandra cluster. + ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, + queryTimeoutUnits, showValues, false); - if (result == null) { - ResultSet resultSet = execute(sessionOps, uow, traceContext, showValues, true); - result = transform(resultSet); + // Transform the query result set into the desired shape. + resultStream = transform(resultSet); + } - if (key != null) { - uow.getCache().put(key, (Set) result); - } - } + if (updateCache && resultStream != null) { + List facets = getFacets(); + if (facets != null && facets.size() > 1) { + List again = new ArrayList<>(); + resultStream.forEach(result -> { + sessionOps.updateCache(result, facets); + again.add(result); + }); + resultStream = again.stream(); + } + } + return resultStream; - return result; - } finally { - context.stop(); - } - } + } finally { + context.stop(); + } + } - public CompletableFuture> async() { - return CompletableFuture.>supplyAsync(() -> sync()); - } + public Stream sync(UnitOfWork uow) {// throws TimeoutException { + if (uow == null) + return sync(); - public CompletableFuture> async(UnitOfWork uow) { - if (uow == null) return async(); - return CompletableFuture.>supplyAsync(() -> sync(uow)); - } + final Timer.Context context = requestLatency.time(); + try { + Stream resultStream = null; + E cachedResult = null; + boolean updateCache = true; + + if (enableCache) { + Stopwatch timer = uow.getCacheLookupTimer(); + timer.start(); + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + updateCache = false; + } + timer.stop(); + } + + if (resultStream == null) { + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); + resultStream = transform(resultSet); + } + + // If we have a result and we're caching then we need to put it into the cache + // for future requests to find. + if (updateCache && resultStream != null) { + List again = new ArrayList<>(); + List facets = getFacets(); + resultStream.forEach(result -> { + updateCache(uow, result, facets); + again.add(result); + }); + resultStream = again.stream(); + } + + return resultStream; + } finally { + context.stop(); + } + } + + public CompletableFuture> async() { + return CompletableFuture.>supplyAsync(() -> { + // try { + return sync(); + // } catch (TimeoutException ex) { + // throw new CompletionException(ex); + // } + }); + } + + public CompletableFuture> async(UnitOfWork uow) { + if (uow == null) + return async(); + return CompletableFuture.>supplyAsync(() -> { + // try { + return sync(); + // } catch (TimeoutException ex) { + // throw new CompletionException(ex); + // } + }); + } } diff --git a/src/main/java/net/helenus/core/operation/BoundOperation.java b/src/main/java/net/helenus/core/operation/BoundOperation.java index 28c134f..002dbd6 100644 --- a/src/main/java/net/helenus/core/operation/BoundOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundOperation.java @@ -21,22 +21,27 @@ import com.datastax.driver.core.Statement; public final class BoundOperation extends AbstractOperation> { - private final BoundStatement boundStatement; - private final AbstractOperation delegate; + private final BoundStatement boundStatement; + private final AbstractOperation delegate; - public BoundOperation(BoundStatement boundStatement, AbstractOperation operation) { - super(operation.sessionOps); - this.boundStatement = boundStatement; - this.delegate = operation; - } + public BoundOperation(BoundStatement boundStatement, AbstractOperation operation) { + super(operation.sessionOps); + this.boundStatement = boundStatement; + this.delegate = operation; + } - @Override - public E transform(ResultSet resultSet) { - return delegate.transform(resultSet); - } + @Override + public E transform(ResultSet resultSet) { + return delegate.transform(resultSet); + } - @Override - public Statement buildStatement(boolean cached) { - return boundStatement; - } + @Override + public Statement buildStatement(boolean cached) { + return boundStatement; + } + + @Override + public boolean isSessionCacheable() { + return delegate.isSessionCacheable(); + } } diff --git a/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java b/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java index c3f5332..40eb2a0 100644 --- a/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java @@ -15,31 +15,35 @@ */ package net.helenus.core.operation; +import java.util.Optional; + import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Statement; -import java.util.Optional; -public final class BoundOptionalOperation - extends AbstractOptionalOperation> { +public final class BoundOptionalOperation extends AbstractOptionalOperation> { - private final BoundStatement boundStatement; - private final AbstractOptionalOperation delegate; + private final BoundStatement boundStatement; + private final AbstractOptionalOperation delegate; - public BoundOptionalOperation( - BoundStatement boundStatement, AbstractOptionalOperation operation) { - super(operation.sessionOps); - this.boundStatement = boundStatement; - this.delegate = operation; - } + public BoundOptionalOperation(BoundStatement boundStatement, AbstractOptionalOperation operation) { + super(operation.sessionOps); + this.boundStatement = boundStatement; + this.delegate = operation; + } - @Override - public Optional transform(ResultSet resultSet) { - return delegate.transform(resultSet); - } + @Override + public Optional transform(ResultSet resultSet) { + return delegate.transform(resultSet); + } - @Override - public Statement buildStatement(boolean cached) { - return boundStatement; - } + @Override + public Statement buildStatement(boolean cached) { + return boundStatement; + } + + @Override + public boolean isSessionCacheable() { + return delegate.isSessionCacheable(); + } } diff --git a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java index 7a3cf2c..7b7c087 100644 --- a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java @@ -15,36 +15,43 @@ */ package net.helenus.core.operation; +import java.util.List; +import java.util.stream.Stream; + import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Statement; -import java.util.stream.Stream; -public final class BoundStreamOperation - extends AbstractStreamOperation> { +import net.helenus.core.cache.Facet; - private final BoundStatement boundStatement; - private final AbstractStreamOperation delegate; +public final class BoundStreamOperation extends AbstractStreamOperation> { - public BoundStreamOperation( - BoundStatement boundStatement, AbstractStreamOperation operation) { - super(operation.sessionOps); - this.boundStatement = boundStatement; - this.delegate = operation; - } + private final BoundStatement boundStatement; + private final AbstractStreamOperation delegate; - @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); - } + public BoundStreamOperation(BoundStatement boundStatement, AbstractStreamOperation operation) { + super(operation.sessionOps); + this.boundStatement = boundStatement; + this.delegate = operation; + } - @Override - public Stream transform(ResultSet resultSet) { - return delegate.transform(resultSet); - } + @Override + public List bindFacetValues() { + return delegate.bindFacetValues(); + } - @Override - public Statement buildStatement(boolean cached) { - return boundStatement; - } + @Override + public Stream transform(ResultSet resultSet) { + return delegate.transform(resultSet); + } + + @Override + public Statement buildStatement(boolean cached) { + return boundStatement; + } + + @Override + public boolean isSessionCacheable() { + return delegate.isSessionCacheable(); + } } diff --git a/src/main/java/net/helenus/core/operation/CountOperation.java b/src/main/java/net/helenus/core/operation/CountOperation.java index b751cfb..3631b93 100644 --- a/src/main/java/net/helenus/core/operation/CountOperation.java +++ b/src/main/java/net/helenus/core/operation/CountOperation.java @@ -20,6 +20,7 @@ import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Where; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Filter; import net.helenus.core.reflect.HelenusPropertyNode; @@ -28,56 +29,53 @@ import net.helenus.support.HelenusMappingException; public final class CountOperation extends AbstractFilterOperation { - private HelenusEntity entity; + private HelenusEntity entity; - public CountOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public CountOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public CountOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { - super(sessionOperations); - this.entity = entity; - } + public CountOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { + super(sessionOperations); + this.entity = entity; + } - @Override - public BuiltStatement buildStatement(boolean cached) { + @Override + public BuiltStatement buildStatement(boolean cached) { - if (filters != null && !filters.isEmpty()) { - filters.forEach(f -> addPropertyNode(f.getNode())); - } + if (filters != null && !filters.isEmpty()) { + filters.forEach(f -> addPropertyNode(f.getNode())); + } - if (entity == null) { - throw new HelenusMappingException("unknown entity"); - } + if (entity == null) { + throw new HelenusMappingException("unknown entity"); + } - Select select = QueryBuilder.select().countAll().from(entity.getName().toCql()); + Select select = QueryBuilder.select().countAll().from(entity.getName().toCql()); - if (filters != null && !filters.isEmpty()) { + if (filters != null && !filters.isEmpty()) { - Where where = select.where(); + Where where = select.where(); - for (Filter filter : filters) { - where.and(filter.getClause(sessionOps.getValuePreparer())); - } - } + for (Filter filter : filters) { + where.and(filter.getClause(sessionOps.getValuePreparer())); + } + } - return select; - } + return select; + } - @Override - public Long transform(ResultSet resultSet) { - return resultSet.one().getLong(0); - } + @Override + public Long transform(ResultSet resultSet) { + return resultSet.one().getLong(0); + } - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can count columns only in single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can count columns only in single entity " + + entity.getMappingInterface() + " or " + p.getEntity().getMappingInterface()); + } + } } diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index 7b6dffb..d95c567 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -20,6 +20,7 @@ import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Delete; import com.datastax.driver.core.querybuilder.Delete.Where; import com.datastax.driver.core.querybuilder.QueryBuilder; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Filter; import net.helenus.core.reflect.HelenusPropertyNode; @@ -28,100 +29,97 @@ import net.helenus.support.HelenusMappingException; public final class DeleteOperation extends AbstractFilterOperation { - private HelenusEntity entity; + private HelenusEntity entity; - private boolean ifExists = false; + private boolean ifExists = false; - private int[] ttl; - private long[] timestamp; + private int[] ttl; + private long[] timestamp; - public DeleteOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public DeleteOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public DeleteOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { - super(sessionOperations); + public DeleteOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { + super(sessionOperations); - this.entity = entity; - } + this.entity = entity; + } - @Override - public BuiltStatement buildStatement(boolean cached) { + @Override + public BuiltStatement buildStatement(boolean cached) { - if (filters != null && !filters.isEmpty()) { - filters.forEach(f -> addPropertyNode(f.getNode())); - } + if (filters != null && !filters.isEmpty()) { + filters.forEach(f -> addPropertyNode(f.getNode())); + } - if (entity == null) { - throw new HelenusMappingException("unknown entity"); - } + if (entity == null) { + throw new HelenusMappingException("unknown entity"); + } - if (filters != null && !filters.isEmpty()) { + if (filters != null && !filters.isEmpty()) { - Delete delete = QueryBuilder.delete().from(entity.getName().toCql()); + Delete delete = QueryBuilder.delete().from(entity.getName().toCql()); - if (this.ifExists) { - delete.ifExists(); - } + if (this.ifExists) { + delete.ifExists(); + } - Where where = delete.where(); + Where where = delete.where(); - for (Filter filter : filters) { - where.and(filter.getClause(sessionOps.getValuePreparer())); - } + for (Filter filter : filters) { + where.and(filter.getClause(sessionOps.getValuePreparer())); + } - if (ifFilters != null && !ifFilters.isEmpty()) { + if (ifFilters != null && !ifFilters.isEmpty()) { - for (Filter filter : ifFilters) { - delete.onlyIf(filter.getClause(sessionOps.getValuePreparer())); - } - } + for (Filter filter : ifFilters) { + delete.onlyIf(filter.getClause(sessionOps.getValuePreparer())); + } + } - if (this.ttl != null) { - delete.using(QueryBuilder.ttl(this.ttl[0])); - } - if (this.timestamp != null) { - delete.using(QueryBuilder.timestamp(this.timestamp[0])); - } + if (this.ttl != null) { + delete.using(QueryBuilder.ttl(this.ttl[0])); + } + if (this.timestamp != null) { + delete.using(QueryBuilder.timestamp(this.timestamp[0])); + } - return delete; + return delete; - } else { - return QueryBuilder.truncate(entity.getName().toCql()); - } - } + } else { + return QueryBuilder.truncate(entity.getName().toCql()); + } + } - @Override - public ResultSet transform(ResultSet resultSet) { - return resultSet; - } + @Override + public ResultSet transform(ResultSet resultSet) { + return resultSet; + } - public DeleteOperation ifExists() { - this.ifExists = true; - return this; - } + public DeleteOperation ifExists() { + this.ifExists = true; + return this; + } - public DeleteOperation usingTtl(int ttl) { - this.ttl = new int[1]; - this.ttl[0] = ttl; - return this; - } + public DeleteOperation usingTtl(int ttl) { + this.ttl = new int[1]; + this.ttl[0] = ttl; + return this; + } - public DeleteOperation usingTimestamp(long timestamp) { - this.timestamp = new long[1]; - this.timestamp[0] = timestamp; - return this; - } + public DeleteOperation usingTimestamp(long timestamp) { + this.timestamp = new long[1]; + this.timestamp[0] = timestamp; + return this; + } - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can delete rows only in single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can delete rows only in single entity " + + entity.getMappingInterface() + " or " + p.getEntity().getMappingInterface()); + } + } } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 3ee0c8a..fe05cde 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -15,18 +15,20 @@ */ package net.helenus.core.operation; +import java.util.*; +import java.util.function.Function; + import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.google.common.base.Joiner; -import java.util.*; -import java.util.function.Function; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Getter; import net.helenus.core.Helenus; import net.helenus.core.UnitOfWork; import net.helenus.core.reflect.DefaultPrimitiveTypes; +import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; @@ -38,230 +40,210 @@ import net.helenus.support.HelenusMappingException; public final class InsertOperation extends AbstractOperation> { - private HelenusEntity entity; + private final List> values = new ArrayList>(); + private final T pojo; + private final Class resultType; + private HelenusEntity entity; + private boolean ifNotExists; - private final List> values = - new ArrayList>(); - private final T pojo; - private final Class resultType; - private boolean ifNotExists; + private int[] ttl; + private long[] timestamp; - private int[] ttl; - private long[] timestamp; + public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) { + super(sessionOperations); - public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) { - super(sessionOperations); + this.ifNotExists = ifNotExists; + this.pojo = null; + this.resultType = ResultSet.class; + } - this.ifNotExists = ifNotExists; - this.pojo = null; - this.resultType = ResultSet.class; - } + public InsertOperation(AbstractSessionOperations sessionOperations, Class resultType, boolean ifNotExists) { + super(sessionOperations); - public InsertOperation( - AbstractSessionOperations sessionOperations, Class resultType, boolean ifNotExists) { - super(sessionOperations); + this.ifNotExists = ifNotExists; + this.pojo = null; + this.resultType = resultType; + } - this.ifNotExists = ifNotExists; - this.pojo = null; - this.resultType = resultType; - } + public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, T pojo, + Set mutations, boolean ifNotExists) { + super(sessionOperations); - public InsertOperation( - AbstractSessionOperations sessionOperations, - HelenusEntity entity, - T pojo, - Set mutations, - boolean ifNotExists) { - super(sessionOperations); + this.entity = entity; + this.pojo = pojo; + this.ifNotExists = ifNotExists; + this.resultType = entity.getMappingInterface(); - this.entity = entity; - this.pojo = pojo; - this.ifNotExists = ifNotExists; - this.resultType = entity.getMappingInterface(); + Collection properties = entity.getOrderedProperties(); + Set keys = (mutations == null) ? null : mutations; - Collection properties = entity.getOrderedProperties(); - Set keys = (mutations == null) ? null : mutations; + for (HelenusProperty prop : properties) { + boolean addProp = false; - for (HelenusProperty prop : properties) { + switch (prop.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + addProp = true; + break; + default : + addProp = (keys == null || keys.contains(prop.getPropertyName())); + } - if (keys == null || keys.contains(prop.getPropertyName())) { + if (addProp) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); + value = sessionOps.getValuePreparer().prepareColumnValue(value, prop); - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); - value = sessionOps.getValuePreparer().prepareColumnValue(value, prop); + if (value != null) { + HelenusPropertyNode node = new HelenusPropertyNode(prop, Optional.empty()); + values.add(Fun.Tuple2.of(node, value)); + } + } + } + } - if (value != null) { - HelenusPropertyNode node = new HelenusPropertyNode(prop, Optional.empty()); - values.add(Fun.Tuple2.of(node, value)); - } - } - } - } + public InsertOperation ifNotExists() { + this.ifNotExists = true; + return this; + } - public InsertOperation ifNotExists() { - this.ifNotExists = true; - return this; - } + public InsertOperation ifNotExists(boolean enable) { + this.ifNotExists = enable; + return this; + } - public InsertOperation ifNotExists(boolean enable) { - this.ifNotExists = enable; - return this; - } + public InsertOperation value(Getter getter, V val) { - public InsertOperation value(Getter getter, V val) { + Objects.requireNonNull(getter, "getter is empty"); - Objects.requireNonNull(getter, "getter is empty"); + if (val != null) { + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty()); - if (val != null) { - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty()); + if (value != null) { + values.add(Fun.Tuple2.of(node, value)); + } + } - if (value != null) { - values.add(Fun.Tuple2.of(node, value)); - } - } + return this; + } - return this; - } + @Override + public BuiltStatement buildStatement(boolean cached) { - @Override - public BuiltStatement buildStatement(boolean cached) { + values.forEach(t -> addPropertyNode(t._1)); - values.forEach(t -> addPropertyNode(t._1)); + if (values.isEmpty()) + return null; - if (values.isEmpty()) return null; + if (entity == null) { + throw new HelenusMappingException("unknown entity"); + } - if (entity == null) { - throw new HelenusMappingException("unknown entity"); - } + Insert insert = QueryBuilder.insertInto(entity.getName().toCql()); - Insert insert = QueryBuilder.insertInto(entity.getName().toCql()); + if (ifNotExists) { + insert.ifNotExists(); + } - if (ifNotExists) { - insert.ifNotExists(); - } + values.forEach(t -> { + insert.value(t._1.getColumnName(), t._2); + }); - values.forEach( - t -> { - insert.value(t._1.getColumnName(), t._2); - }); + if (this.ttl != null) { + insert.using(QueryBuilder.ttl(this.ttl[0])); + } + if (this.timestamp != null) { + insert.using(QueryBuilder.timestamp(this.timestamp[0])); + } - if (this.ttl != null) { - insert.using(QueryBuilder.ttl(this.ttl[0])); - } - if (this.timestamp != null) { - insert.using(QueryBuilder.timestamp(this.timestamp[0])); - } + return insert; + } - return insert; - } + @Override + public T transform(ResultSet resultSet) { + Class iface = entity.getMappingInterface(); + if (resultType == iface) { + if (values.size() > 0) { + boolean immutable = iface.isAssignableFrom(Drafted.class); + Collection properties = entity.getOrderedProperties(); + Map backingMap = new HashMap(properties.size()); - @Override - public T transform(ResultSet resultSet) { - Class iface = entity.getMappingInterface(); - if (resultType == iface) { - if (values.size() > 0) { - Collection properties = entity.getOrderedProperties(); - Map backingMap = new HashMap(properties.size()); + // First, add all the inserted values into our new map. + values.forEach(t -> backingMap.put(t._1.getProperty().getPropertyName(), t._2)); - // First, add all the inserted values into our new map. - values.forEach(t -> backingMap.put(t._1.getProperty().getPropertyName(), t._2)); + // Then, fill in all the rest of the properties. + for (HelenusProperty prop : properties) { + String key = prop.getPropertyName(); + if (backingMap.containsKey(key)) { + // Some values man need to be converted (e.g. from String to Enum). This is done + // within the BeanColumnValueProvider below. + Optional> converter = prop + .getReadConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + backingMap.put(key, converter.get().apply(backingMap.get(key))); + } + } else { + // If we started this operation with an instance of this type, use values from + // that. + if (pojo != null) { + backingMap.put(key, + BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, immutable)); + } else { + // Otherwise we'll use default values for the property type if available. + Class propType = prop.getJavaType(); + if (propType.isPrimitive()) { + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(propType); + if (type == null) { + throw new HelenusException("unknown primitive type " + propType); + } + backingMap.put(key, type.getDefaultValue()); + } + } + } + } - // Then, fill in all the rest of the properties. - for (HelenusProperty prop : properties) { - String key = prop.getPropertyName(); - if (backingMap.containsKey(key)) { - // Some values man need to be converted (e.g. from String to Enum). This is done - // within the BeanColumnValueProvider below. - Optional> converter = - prop.getReadConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - backingMap.put(key, converter.get().apply(backingMap.get(key))); - } - } else { - // If we started this operation with an instance of this type, use values from that. - if (pojo != null) { - backingMap.put(key, BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - } else { - // Otherwise we'll use default values for the property type if available. - Class propType = prop.getJavaType(); - if (propType.isPrimitive()) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(propType); - if (type == null) { - throw new HelenusException("unknown primitive type " + propType); - } - backingMap.put(key, type.getDefaultValue()); - } - } - } - } + // Lastly, create a new proxy object for the entity and return the new instance. + return (T) Helenus.map(iface, backingMap); + } + // Oddly, this insert didn't change any value so simply return the pojo. + // TODO(gburd): this pojo is the result of a Draft.build() call which will not + // preserve object identity (o1 == o2), ... fix me. + return (T) pojo; + } + return (T) resultSet; + } - // Lastly, create a new proxy object for the entity and return the new instance. - return (T) Helenus.map(iface, backingMap); - } - // Oddly, this insert didn't change any value so simply return the pojo. - // TODO(gburd): this pojo is the result of a Draft.build() call which will not preserve object identity (o1 == o2), ... fix me. - return (T) pojo; - } - return (T) resultSet; - } + public InsertOperation usingTtl(int ttl) { + this.ttl = new int[1]; + this.ttl[0] = ttl; + return this; + } - public InsertOperation usingTtl(int ttl) { - this.ttl = new int[1]; - this.ttl[0] = ttl; - return this; - } + public InsertOperation usingTimestamp(long timestamp) { + this.timestamp = new long[1]; + this.timestamp[0] = timestamp; + return this; + } - public InsertOperation usingTimestamp(long timestamp) { - this.timestamp = new long[1]; - this.timestamp[0] = timestamp; - return this; - } + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface() + + " or " + p.getEntity().getMappingInterface()); + } + } - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can insert only single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } - - @Override - public String getStatementCacheKey() { - List keys = new ArrayList<>(values.size()); - values.forEach( - t -> { - HelenusPropertyNode prop = t._1; - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - keys.add(prop.getColumnName() + "==" + t._2.toString()); - break; - default: - break; - } - }); - return entity.getName() + ": " + Joiner.on(",").join(keys); - } - - @Override - public T sync(UnitOfWork uow) { - if (uow == null) { - return sync(); - } - T result = super.sync(uow); - Class iface = entity.getMappingInterface(); - if (resultType == iface) { - String key = getStatementCacheKey(); - if (key != null) { - Set set = new HashSet(1); - set.add(result); - uow.getCache().put(key, set); - } - } - return result; - } + @Override + public T sync(UnitOfWork uow) {// throws TimeoutException { + if (uow == null) { + return sync(); + } + T result = super.sync(uow); + Class iface = entity.getMappingInterface(); + if (resultType == iface) { + updateCache(uow, result, entity.getFacets()); + } + return result; + } } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index ef94f96..452a809 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -1,79 +1,111 @@ +/* + * Copyright (C) 2015 The Helenus 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 net.helenus.core.operation; -import brave.Span; -import brave.Tracer; -import brave.propagation.TraceContext; +import java.util.List; +import java.util.concurrent.TimeUnit; + import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.Statement; -import java.util.concurrent.ExecutionException; +import com.google.common.base.Stopwatch; + +import brave.Span; +import brave.Tracer; +import brave.propagation.TraceContext; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.Facet; public abstract class Operation { - protected final AbstractSessionOperations sessionOps; - protected final Meter uowCacheHits; - protected final Meter uowCacheMiss; - protected final Timer requestLatency; + protected final AbstractSessionOperations sessionOps; + protected final Meter uowCacheHits; + protected final Meter uowCacheMiss; + protected final Timer requestLatency; - Operation(AbstractSessionOperations sessionOperations) { - this.sessionOps = sessionOperations; - MetricRegistry metrics = sessionOperations.getMetricRegistry(); - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); - this.requestLatency = metrics.timer("net.helenus.request-latency"); - } + Operation(AbstractSessionOperations sessionOperations) { + this.sessionOps = sessionOperations; + MetricRegistry metrics = sessionOperations.getMetricRegistry(); + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.requestLatency = metrics.timer("net.helenus.request-latency"); + } - public ResultSet execute( - AbstractSessionOperations session, - UnitOfWork uow, - TraceContext traceContext, - boolean showValues, - boolean cached) { + public ResultSet execute(AbstractSessionOperations session, UnitOfWork uow, TraceContext traceContext, long timeout, + TimeUnit units, boolean showValues, boolean cached) { // throws TimeoutException { - // Start recording in a Zipkin sub-span our execution time to perform this operation. - Tracer tracer = session.getZipkinTracer(); - Span span = null; - if (tracer != null && traceContext != null) { - span = tracer.newChild(traceContext); - } + // Start recording in a Zipkin sub-span our execution time to perform this + // operation. + Tracer tracer = session.getZipkinTracer(); + Span span = null; + if (tracer != null && traceContext != null) { + span = tracer.newChild(traceContext); + } - try { + try { - if (span != null) { - span.name("cassandra"); - span.start(); - } + if (span != null) { + span.name("cassandra"); + span.start(); + } - Statement statement = options(buildStatement(cached)); - ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); - return futureResultSet.get(); + Statement statement = options(buildStatement(cached)); + Stopwatch timer = null; + if (uow != null) { + timer = uow.getExecutionTimer(); + timer.start(); + } + ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); + ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); - } catch (InterruptedException | ExecutionException e) { + if (uow != null) + timer.stop(); - throw new RuntimeException(e); + return resultSet; - } finally { + } finally { - if (span != null) { - span.finish(); - } - } - } + if (span != null) { + span.finish(); + } + } + } - public Statement options(Statement statement) { - return statement; - } + public Statement options(Statement statement) { + return statement; + } - public Statement buildStatement(boolean cached) { - return null; - } + public Statement buildStatement(boolean cached) { + return null; + } + + public List getFacets() { + return null; + } + + public List bindFacetValues() { + return null; + } + + public boolean isSessionCacheable() { + return false; + } - public String getStatementCacheKey() { - return null; - } } diff --git a/src/main/java/net/helenus/core/operation/PreparedOperation.java b/src/main/java/net/helenus/core/operation/PreparedOperation.java index baba8df..43a56c2 100644 --- a/src/main/java/net/helenus/core/operation/PreparedOperation.java +++ b/src/main/java/net/helenus/core/operation/PreparedOperation.java @@ -20,27 +20,28 @@ import com.datastax.driver.core.PreparedStatement; public final class PreparedOperation { - private final PreparedStatement preparedStatement; - private final AbstractOperation operation; + private final PreparedStatement preparedStatement; + private final AbstractOperation operation; - public PreparedOperation(PreparedStatement statement, AbstractOperation operation) { - this.preparedStatement = statement; - this.operation = operation; - } + public PreparedOperation(PreparedStatement statement, AbstractOperation operation) { + this.preparedStatement = statement; + this.operation = operation; + } - public PreparedStatement getPreparedStatement() { - return preparedStatement; - } + public PreparedStatement getPreparedStatement() { + return preparedStatement; + } - public BoundOperation bind(Object... params) { + public BoundOperation bind(Object... params) { - BoundStatement boundStatement = preparedStatement.bind(params); + BoundStatement boundStatement = preparedStatement.bind(params); - return new BoundOperation(boundStatement, operation); - } + return new BoundOperation(boundStatement, operation); + } + + @Override + public String toString() { + return preparedStatement.getQueryString(); + } - @Override - public String toString() { - return preparedStatement.getQueryString(); - } } diff --git a/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java b/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java index 2ee7e29..31feb2b 100644 --- a/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java @@ -20,28 +20,27 @@ import com.datastax.driver.core.PreparedStatement; public final class PreparedOptionalOperation { - private final PreparedStatement preparedStatement; - private final AbstractOptionalOperation operation; + private final PreparedStatement preparedStatement; + private final AbstractOptionalOperation operation; - public PreparedOptionalOperation( - PreparedStatement statement, AbstractOptionalOperation operation) { - this.preparedStatement = statement; - this.operation = operation; - } + public PreparedOptionalOperation(PreparedStatement statement, AbstractOptionalOperation operation) { + this.preparedStatement = statement; + this.operation = operation; + } - public PreparedStatement getPreparedStatement() { - return preparedStatement; - } + public PreparedStatement getPreparedStatement() { + return preparedStatement; + } - public BoundOptionalOperation bind(Object... params) { + public BoundOptionalOperation bind(Object... params) { - BoundStatement boundStatement = preparedStatement.bind(params); + BoundStatement boundStatement = preparedStatement.bind(params); - return new BoundOptionalOperation(boundStatement, operation); - } + return new BoundOptionalOperation(boundStatement, operation); + } - @Override - public String toString() { - return preparedStatement.getQueryString(); - } + @Override + public String toString() { + return preparedStatement.getQueryString(); + } } diff --git a/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java b/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java index cd0f6be..132e39c 100644 --- a/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java @@ -20,26 +20,25 @@ import com.datastax.driver.core.PreparedStatement; public final class PreparedStreamOperation { - private final PreparedStatement preparedStatement; - private final AbstractStreamOperation operation; + private final PreparedStatement preparedStatement; + private final AbstractStreamOperation operation; - public PreparedStreamOperation( - PreparedStatement statement, AbstractStreamOperation operation) { - this.preparedStatement = statement; - this.operation = operation; - } + public PreparedStreamOperation(PreparedStatement statement, AbstractStreamOperation operation) { + this.preparedStatement = statement; + this.operation = operation; + } - public PreparedStatement getPreparedStatement() { - return preparedStatement; - } + public PreparedStatement getPreparedStatement() { + return preparedStatement; + } - public BoundStreamOperation bind(Object... params) { - BoundStatement boundStatement = preparedStatement.bind(params); - return new BoundStreamOperation(boundStatement, operation); - } + public BoundStreamOperation bind(Object... params) { + BoundStatement boundStatement = preparedStatement.bind(params); + return new BoundStreamOperation(boundStatement, operation); + } - @Override - public String toString() { - return preparedStatement.getQueryString(); - } + @Override + public String toString() { + return preparedStatement.getQueryString(); + } } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java index d5cf01e..15a25a6 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java @@ -15,40 +15,53 @@ */ package net.helenus.core.operation; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.querybuilder.BuiltStatement; +import java.util.List; import java.util.Optional; import java.util.function.Function; -public final class SelectFirstOperation - extends AbstractFilterOptionalOperation> { +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.querybuilder.BuiltStatement; - private final SelectOperation delegate; +import net.helenus.core.cache.Facet; - public SelectFirstOperation(SelectOperation delegate) { - super(delegate.sessionOps); +public final class SelectFirstOperation extends AbstractFilterOptionalOperation> { - this.delegate = delegate; - this.filters = delegate.filters; - this.ifFilters = delegate.ifFilters; - } + private final SelectOperation delegate; - public SelectFirstTransformingOperation map(Function fn) { - return new SelectFirstTransformingOperation(delegate, fn); - } + public SelectFirstOperation(SelectOperation delegate) { + super(delegate.sessionOps); - @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); - } + this.delegate = delegate; + this.filters = delegate.filters; + this.ifFilters = delegate.ifFilters; + } - @Override - public BuiltStatement buildStatement(boolean cached) { - return delegate.buildStatement(cached); - } + public SelectFirstTransformingOperation map(Function fn) { + return new SelectFirstTransformingOperation(delegate, fn); + } - @Override - public Optional transform(ResultSet resultSet) { - return delegate.transform(resultSet).findFirst(); - } + @Override + public BuiltStatement buildStatement(boolean cached) { + return delegate.buildStatement(cached); + } + + @Override + public List getFacets() { + return delegate.getFacets(); + } + + @Override + public List bindFacetValues() { + return delegate.bindFacetValues(); + } + + @Override + public Optional transform(ResultSet resultSet) { + return delegate.transform(resultSet).findFirst(); + } + + @Override + public boolean isSessionCacheable() { + return delegate.isSessionCacheable(); + } } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java index 8ef4f60..727d663 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java @@ -15,38 +15,48 @@ */ package net.helenus.core.operation; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.querybuilder.BuiltStatement; +import java.util.List; import java.util.Optional; import java.util.function.Function; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.querybuilder.BuiltStatement; + +import net.helenus.core.cache.Facet; + public final class SelectFirstTransformingOperation - extends AbstractFilterOptionalOperation> { + extends + AbstractFilterOptionalOperation> { - private final SelectOperation delegate; - private final Function fn; + private final SelectOperation delegate; + private final Function fn; - public SelectFirstTransformingOperation(SelectOperation delegate, Function fn) { - super(delegate.sessionOps); + public SelectFirstTransformingOperation(SelectOperation delegate, Function fn) { + super(delegate.sessionOps); - this.delegate = delegate; - this.fn = fn; - this.filters = delegate.filters; - this.ifFilters = delegate.ifFilters; - } + this.delegate = delegate; + this.fn = fn; + this.filters = delegate.filters; + this.ifFilters = delegate.ifFilters; + } - @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); - } + @Override + public List bindFacetValues() { + return delegate.bindFacetValues(); + } - @Override - public BuiltStatement buildStatement(boolean cached) { - return delegate.buildStatement(cached); - } + @Override + public BuiltStatement buildStatement(boolean cached) { + return delegate.buildStatement(cached); + } - @Override - public Optional transform(ResultSet resultSet) { - return delegate.transform(resultSet).findFirst().map(fn); - } + @Override + public Optional transform(ResultSet resultSet) { + return delegate.transform(resultSet).findFirst().map(fn); + } + + @Override + public boolean isSessionCacheable() { + return delegate.isSessionCacheable(); + } } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index e483659..bc658f2 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -15,6 +15,14 @@ */ package net.helenus.core.operation; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.querybuilder.BuiltStatement; @@ -23,13 +31,11 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Selection; import com.datastax.driver.core.querybuilder.Select.Where; -import com.google.common.base.Joiner; import com.google.common.collect.Iterables; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; + import net.helenus.core.*; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.UnboundFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.MappingUtil; @@ -41,283 +47,278 @@ import net.helenus.support.HelenusMappingException; public final class SelectOperation extends AbstractFilterStreamOperation> { - protected Function rowMapper = null; - protected final List props = new ArrayList(); + private static final Logger LOG = LoggerFactory.getLogger(SelectOperation.class); - protected List ordering = null; - protected Integer limit = null; - protected boolean allowFiltering = false; - protected String alternateTableName = null; + protected final List props = new ArrayList(); + protected Function rowMapper = null; + protected List ordering = null; + protected Integer limit = null; + protected boolean allowFiltering = false; + protected String alternateTableName = null; + protected boolean isCacheable = false; - @SuppressWarnings("unchecked") - public SelectOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); + @SuppressWarnings("unchecked") + public SelectOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); - this.rowMapper = - new Function() { + this.rowMapper = new Function() { - @Override - public E apply(Row source) { + @Override + public E apply(Row source) { - ColumnValueProvider valueProvider = sessionOps.getValueProvider(); - Object[] arr = new Object[props.size()]; + ColumnValueProvider valueProvider = sessionOps.getValueProvider(); + Object[] arr = new Object[props.size()]; - int i = 0; - for (HelenusPropertyNode p : props) { - Object value = valueProvider.getColumnValue(source, -1, p.getProperty()); - arr[i++] = value; - } + int i = 0; + for (HelenusPropertyNode p : props) { + Object value = valueProvider.getColumnValue(source, -1, p.getProperty()); + arr[i++] = value; + } - return (E) Fun.ArrayTuple.of(arr); - } - }; - } + return (E) Fun.ArrayTuple.of(arr); + } + }; + } - public SelectOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { + public SelectOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { - super(sessionOperations); + super(sessionOperations); - entity - .getOrderedProperties() - .stream() - .map(p -> new HelenusPropertyNode(p, Optional.empty())) - .forEach(p -> this.props.add(p)); - } + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> this.props.add(p)); - public SelectOperation( - AbstractSessionOperations sessionOperations, - HelenusEntity entity, - Function rowMapper) { + isCacheable = entity.isCacheable(); + } - super(sessionOperations); - this.rowMapper = rowMapper; + public SelectOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, + Function rowMapper) { - entity - .getOrderedProperties() - .stream() - .map(p -> new HelenusPropertyNode(p, Optional.empty())) - .forEach(p -> this.props.add(p)); - } + super(sessionOperations); + this.rowMapper = rowMapper; - public SelectOperation( - AbstractSessionOperations sessionOperations, - Function rowMapper, - HelenusPropertyNode... props) { + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> this.props.add(p)); - super(sessionOperations); + isCacheable = entity.isCacheable(); + } - this.rowMapper = rowMapper; - Collections.addAll(this.props, props); - } + public SelectOperation(AbstractSessionOperations sessionOperations, Function rowMapper, + HelenusPropertyNode... props) { - public CountOperation count() { + super(sessionOperations); - HelenusEntity entity = null; - for (HelenusPropertyNode prop : props) { + this.rowMapper = rowMapper; + Collections.addAll(this.props, props); + } - if (entity == null) { - entity = prop.getEntity(); - } else if (entity != prop.getEntity()) { - throw new HelenusMappingException( - "you can count records only from a single entity " - + entity.getMappingInterface() - + " or " - + prop.getEntity().getMappingInterface()); - } - } + public CountOperation count() { - return new CountOperation(sessionOps, entity); - } + HelenusEntity entity = null; + for (HelenusPropertyNode prop : props) { - public SelectOperation from(Class materializedViewClass) { - Objects.requireNonNull(materializedViewClass); - HelenusEntity entity = Helenus.entity(materializedViewClass); - this.alternateTableName = entity.getName().toCql(); - this.allowFiltering = true; - return this; - } + if (entity == null) { + entity = prop.getEntity(); + } else if (entity != prop.getEntity()) { + throw new HelenusMappingException("you can count records only from a single entity " + + entity.getMappingInterface() + " or " + prop.getEntity().getMappingInterface()); + } + } - public SelectOperation from(String alternateTableName) { - this.alternateTableName = alternateTableName; - return this; - } + return new CountOperation(sessionOps, entity); + } - public SelectFirstOperation single() { - limit(1); - return new SelectFirstOperation(this); - } + public SelectOperation from(Class materializedViewClass) { + Objects.requireNonNull(materializedViewClass); + HelenusEntity entity = Helenus.entity(materializedViewClass); + this.alternateTableName = entity.getName().toCql(); + this.props.clear(); + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> this.props.add(p)); + return this; + } - public SelectTransformingOperation mapTo(Class entityClass) { + public SelectFirstOperation single() { + limit(1); + return new SelectFirstOperation(this); + } - Objects.requireNonNull(entityClass, "entityClass is null"); + public SelectTransformingOperation mapTo(Class entityClass) { - HelenusEntity entity = Helenus.entity(entityClass); + Objects.requireNonNull(entityClass, "entityClass is null"); - this.rowMapper = null; + HelenusEntity entity = Helenus.entity(entityClass); - return new SelectTransformingOperation( - this, - (r) -> { - Map map = new ValueProviderMap(r, sessionOps.getValueProvider(), entity); - return (R) Helenus.map(entityClass, map); - }); - } + this.rowMapper = null; - public SelectTransformingOperation map(Function fn) { - return new SelectTransformingOperation(this, fn); - } + return new SelectTransformingOperation(this, (r) -> { + Map map = new ValueProviderMap(r, sessionOps.getValueProvider(), entity); + return (R) Helenus.map(entityClass, map); + }); + } - public SelectOperation column(Getter getter) { - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); - this.props.add(p); - return this; - } + public SelectTransformingOperation map(Function fn) { + return new SelectTransformingOperation(this, fn); + } - public SelectOperation orderBy(Getter getter, OrderingDirection direction) { - getOrCreateOrdering().add(new Ordered(getter, direction).getOrdering()); - return this; - } + public SelectOperation column(Getter getter) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); + this.props.add(p); + return this; + } - public SelectOperation orderBy(Ordered ordered) { - getOrCreateOrdering().add(ordered.getOrdering()); - return this; - } + public SelectOperation orderBy(Getter getter, OrderingDirection direction) { + getOrCreateOrdering().add(new Ordered(getter, direction).getOrdering()); + return this; + } - public SelectOperation limit(Integer limit) { - this.limit = limit; - return this; - } + public SelectOperation orderBy(Ordered ordered) { + getOrCreateOrdering().add(ordered.getOrdering()); + return this; + } - public SelectOperation allowFiltering() { - this.allowFiltering = true; - return this; - } + public SelectOperation limit(Integer limit) { + this.limit = limit; + return this; + } - @Override - public String getStatementCacheKey() { - List keys = new ArrayList<>(filters.size()); - HelenusEntity entity = props.get(0).getEntity(); + public SelectOperation allowFiltering() { + this.allowFiltering = true; + return this; + } - for (HelenusPropertyNode prop : props) { - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - Filter filter = filters.get(prop.getProperty()); - if (filter != null) { - keys.add(filter.toString()); - } else { - return null; - } - break; - default: - if (keys.size() > 0) { - return entity.getName() + ": " + Joiner.on(",").join(keys); - } - return null; - } - } - return null; - } + @Override + public boolean isSessionCacheable() { + return isCacheable; + } - @Override - public BuiltStatement buildStatement(boolean cached) { + @Override + public List getFacets() { + HelenusEntity entity = props.get(0).getEntity(); + return entity.getFacets(); + } - HelenusEntity entity = null; - Selection selection = QueryBuilder.select(); + @Override + public List bindFacetValues() { + HelenusEntity entity = props.get(0).getEntity(); + List boundFacets = new ArrayList<>(); - for (HelenusPropertyNode prop : props) { - String columnName = prop.getColumnName(); - selection = selection.column(columnName); + for (Facet facet : entity.getFacets()) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + Filter filter = filters.get(prop); + if (filter != null) { + Object[] postulates = filter.postulateValues(); + for (Object p : postulates) { + binder.setValueForProperty(prop, p.toString()); + } + } - if (prop.getProperty().caseSensitiveIndex()) { - allowFiltering = true; - } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + return boundFacets; + } - if (entity == null) { - entity = prop.getEntity(); - } else if (entity != prop.getEntity()) { - throw new HelenusMappingException( - "you can select columns only from a single entity " - + entity.getMappingInterface() - + " or " - + prop.getEntity().getMappingInterface()); - } + @Override + public BuiltStatement buildStatement(boolean cached) { - if (cached) { - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - break; - default: - if (entity.equals(prop.getEntity())) { - if (prop.getNext().isPresent()) { - columnName = Iterables.getLast(prop).getColumnName().toCql(true); - } - if (!prop.getProperty().getDataType().isCollectionType()) { - selection.writeTime(columnName).as(columnName + "_writeTime"); - selection.ttl(columnName).as(columnName + "_ttl"); - } - } - break; - } - } - } + HelenusEntity entity = null; + Selection selection = QueryBuilder.select(); - if (entity == null) { - throw new HelenusMappingException("no entity or table to select data"); - } + for (HelenusPropertyNode prop : props) { + String columnName = prop.getColumnName(); + selection = selection.column(columnName); - String tableName = alternateTableName == null ? entity.getName().toCql() : alternateTableName; - Select select = selection.from(tableName); + if (prop.getProperty().caseSensitiveIndex()) { + allowFiltering = true; + } - if (ordering != null && !ordering.isEmpty()) { - select.orderBy(ordering.toArray(new Ordering[ordering.size()])); - } + if (entity == null) { + entity = prop.getEntity(); + } else if (entity != prop.getEntity()) { + throw new HelenusMappingException("you can select columns only from a single entity " + + entity.getMappingInterface() + " or " + prop.getEntity().getMappingInterface()); + } - if (limit != null) { - select.limit(limit); - } + if (cached) { + switch (prop.getProperty().getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + break; + default : + if (entity.equals(prop.getEntity())) { + if (prop.getNext().isPresent()) { + columnName = Iterables.getLast(prop).getColumnName().toCql(true); + } + if (!prop.getProperty().getDataType().isCollectionType()) { + selection.writeTime(columnName).as(columnName + "_writeTime"); + selection.ttl(columnName).as(columnName + "_ttl"); + } + } + break; + } + } + } - if (filters != null && !filters.isEmpty()) { + if (entity == null) { + throw new HelenusMappingException("no entity or table to select data"); + } - Where where = select.where(); + String tableName = alternateTableName == null ? entity.getName().toCql() : alternateTableName; + Select select = selection.from(tableName); - for (Filter filter : filters.values()) { - where.and(filter.getClause(sessionOps.getValuePreparer())); - } - } + if (ordering != null && !ordering.isEmpty()) { + select.orderBy(ordering.toArray(new Ordering[ordering.size()])); + } - if (ifFilters != null && !ifFilters.isEmpty()) { - logger.error( - "onlyIf conditions " + ifFilters + " would be ignored in the statement " + select); - } + if (limit != null) { + select.limit(limit); + } - if (allowFiltering) { - select.allowFiltering(); - } + if (filters != null && !filters.isEmpty()) { - return select; - } + Where where = select.where(); - @SuppressWarnings("unchecked") - @Override - public Stream transform(ResultSet resultSet) { - if (rowMapper != null) { - return StreamSupport.stream( - Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false) - .map(rowMapper); - } else { - return (Stream) - StreamSupport.stream( - Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), - false); - } - } + for (Filter filter : filters.values()) { + where.and(filter.getClause(sessionOps.getValuePreparer())); + } + } - private List getOrCreateOrdering() { - if (ordering == null) { - ordering = new ArrayList(); - } - return ordering; - } + if (ifFilters != null && !ifFilters.isEmpty()) { + LOG.error("onlyIf conditions " + ifFilters + " would be ignored in the statement " + select); + } + + if (allowFiltering) { + select.allowFiltering(); + } + + return select; + } + + @SuppressWarnings("unchecked") + @Override + public Stream transform(ResultSet resultSet) { + if (rowMapper != null) { + return StreamSupport + .stream(Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false) + .map(rowMapper); + } else { + return (Stream) StreamSupport + .stream(Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false); + } + } + + private List getOrCreateOrdering() { + if (ordering == null) { + ordering = new ArrayList(); + } + return ordering; + } } diff --git a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java index f93ca41..4a7720e 100644 --- a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java @@ -15,38 +15,48 @@ */ package net.helenus.core.operation; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.querybuilder.BuiltStatement; +import java.util.List; import java.util.function.Function; import java.util.stream.Stream; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.querybuilder.BuiltStatement; + +import net.helenus.core.cache.Facet; + public final class SelectTransformingOperation - extends AbstractFilterStreamOperation> { + extends + AbstractFilterStreamOperation> { - private final SelectOperation delegate; - private final Function fn; + private final SelectOperation delegate; + private final Function fn; - public SelectTransformingOperation(SelectOperation delegate, Function fn) { - super(delegate.sessionOps); + public SelectTransformingOperation(SelectOperation delegate, Function fn) { + super(delegate.sessionOps); - this.delegate = delegate; - this.fn = fn; - this.filters = delegate.filters; - this.ifFilters = delegate.ifFilters; - } + this.delegate = delegate; + this.fn = fn; + this.filters = delegate.filters; + this.ifFilters = delegate.ifFilters; + } - @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); - } + @Override + public List bindFacetValues() { + return delegate.bindFacetValues(); + } - @Override - public BuiltStatement buildStatement(boolean cached) { - return delegate.buildStatement(cached); - } + @Override + public List getFacets() { + return delegate.getFacets(); + } - @Override - public Stream transform(ResultSet resultSet) { - return delegate.transform(resultSet).map(fn); - } + @Override + public BuiltStatement buildStatement(boolean cached) { + return delegate.buildStatement(cached); + } + + @Override + public Stream transform(ResultSet resultSet) { + return delegate.transform(resultSet).map(fn); + } } diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index b918bc6..04ed538 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -15,13 +15,15 @@ */ package net.helenus.core.operation; +import java.util.*; +import java.util.function.Function; + import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.Assignment; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Update; -import java.util.*; -import java.util.function.Function; + import net.helenus.core.*; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; @@ -32,565 +34,549 @@ import net.helenus.support.Immutables; public final class UpdateOperation extends AbstractFilterOperation> { - private HelenusEntity entity = null; + private final List assignments = new ArrayList(); + private final AbstractEntityDraft draft; + private final Map draftMap; + private HelenusEntity entity = null; + private int[] ttl; + private long[] timestamp; - private final List assignments = new ArrayList(); - private final AbstractEntityDraft draft; - private final Map draftMap; + public UpdateOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + this.draft = null; + this.draftMap = null; + } - private int[] ttl; - private long[] timestamp; + public UpdateOperation(AbstractSessionOperations sessionOperations, AbstractEntityDraft draft) { + super(sessionOperations); + this.draft = draft; + this.draftMap = draft.toMap(); + } - public UpdateOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - this.draft = null; - this.draftMap = null; - } + public UpdateOperation(AbstractSessionOperations sessionOperations, HelenusPropertyNode p, Object v) { + super(sessionOperations); + this.draft = null; + this.draftMap = null; - public UpdateOperation( - AbstractSessionOperations sessionOperations, AbstractEntityDraft draft) { - super(sessionOperations); - this.draft = draft; - this.draftMap = draft.toMap(); - } + Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); + assignments.add(QueryBuilder.set(p.getColumnName(), value)); - public UpdateOperation( - AbstractSessionOperations sessionOperations, HelenusPropertyNode p, Object v) { - super(sessionOperations); - this.draft = null; - this.draftMap = null; + addPropertyNode(p); + } - Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); - assignments.add(QueryBuilder.set(p.getColumnName(), value)); + public UpdateOperation set(Getter getter, V v) { + Objects.requireNonNull(getter, "getter is empty"); - addPropertyNode(p); - } + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); - public UpdateOperation set(Getter getter, V v) { - Objects.requireNonNull(getter, "getter is empty"); + Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); + assignments.add(QueryBuilder.set(p.getColumnName(), value)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); + addPropertyNode(p); - Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); - assignments.add(QueryBuilder.set(p.getColumnName(), value)); + return this; + } - addPropertyNode(p); + /* + * + * + * COUNTER + * + * + */ - return this; - } + public UpdateOperation increment(Getter counterGetter) { + return increment(counterGetter, 1L); + } - /* - * - * - * COUNTER - * - * - */ + public UpdateOperation increment(Getter counterGetter, long delta) { - public UpdateOperation increment(Getter counterGetter) { - return increment(counterGetter, 1L); - } + Objects.requireNonNull(counterGetter, "counterGetter is empty"); - public UpdateOperation increment(Getter counterGetter, long delta) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); - Objects.requireNonNull(counterGetter, "counterGetter is empty"); + assignments.add(QueryBuilder.incr(p.getColumnName(), delta)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); + addPropertyNode(p); - assignments.add(QueryBuilder.incr(p.getColumnName(), delta)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + draftMap.put(key, (Long) draftMap.get(key) + delta); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - draftMap.put(key, (Long) draftMap.get(key) + delta); - } + public UpdateOperation decrement(Getter counterGetter) { + return decrement(counterGetter, 1L); + } - return this; - } + public UpdateOperation decrement(Getter counterGetter, long delta) { - public UpdateOperation decrement(Getter counterGetter) { - return decrement(counterGetter, 1L); - } + Objects.requireNonNull(counterGetter, "counterGetter is empty"); - public UpdateOperation decrement(Getter counterGetter, long delta) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); - Objects.requireNonNull(counterGetter, "counterGetter is empty"); + assignments.add(QueryBuilder.decr(p.getColumnName(), delta)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); + addPropertyNode(p); - assignments.add(QueryBuilder.decr(p.getColumnName(), delta)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + draftMap.put(key, (Long) draftMap.get(key) - delta); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - draftMap.put(key, (Long) draftMap.get(key) - delta); - } + /* + * + * + * LIST + * + */ - return this; - } + public UpdateOperation prepend(Getter> listGetter, V value) { - /* - * - * - * LIST - * - */ + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation prepend(Getter> listGetter, V value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.prepend(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.prepend(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(0, value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(0, value); - } + public UpdateOperation prependAll(Getter> listGetter, List value) { - return this; - } + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation prependAll(Getter> listGetter, List value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + List valueObj = prepareListValue(p, value); - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.prependAll(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - List valueObj = prepareListValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.prependAll(p.getColumnName(), valueObj)); + if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(0, value); + } - addPropertyNode(p); + return this; + } - if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(0, value); - } + public UpdateOperation setIdx(Getter> listGetter, int idx, V value) { - return this; - } + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation setIdx(Getter> listGetter, int idx, V value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + if (idx < 0) { + list.add(0, value); + } else if (idx > list.size()) { + list.add(list.size(), value); + } else { + list.add(idx, value); + } + list.add(0, value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - if (idx < 0) { - list.add(0, value); - } else if (idx > list.size()) { - list.add(list.size(), value); - } else { - list.add(idx, value); - } - list.add(0, value); - } + public UpdateOperation append(Getter> listGetter, V value) { - return this; - } + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation append(Getter> listGetter, V value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.append(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.append(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(value); - } + public UpdateOperation appendAll(Getter> listGetter, List value) { - return this; - } + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation appendAll(Getter> listGetter, List value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + List valueObj = prepareListValue(p, value); - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.appendAll(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - List valueObj = prepareListValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.appendAll(p.getColumnName(), valueObj)); + if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(value); + } - addPropertyNode(p); + return this; + } - if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(value); - } + public UpdateOperation discard(Getter> listGetter, V value) { - return this; - } + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation discard(Getter> listGetter, V value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.discard(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.discard(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.remove(value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.remove(value); - } + public UpdateOperation discardAll(Getter> listGetter, List value) { - return this; - } + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation discardAll(Getter> listGetter, List value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + List valueObj = prepareListValue(p, value); - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.discardAll(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - List valueObj = prepareListValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.discardAll(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.removeAll(value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.removeAll(value); - } + private Object prepareSingleListValue(HelenusPropertyNode p, Object value) { + HelenusProperty prop = p.getProperty(); - return this; - } + Object valueObj = value; - private Object prepareSingleListValue(HelenusPropertyNode p, Object value) { - HelenusProperty prop = p.getProperty(); + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + List convertedList = (List) converter.get().apply(Immutables.listOf(value)); + valueObj = convertedList.get(0); + } - Object valueObj = value; + return valueObj; + } - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - List convertedList = (List) converter.get().apply(Immutables.listOf(value)); - valueObj = convertedList.get(0); - } + private List prepareListValue(HelenusPropertyNode p, List value) { - return valueObj; - } + HelenusProperty prop = p.getProperty(); - private List prepareListValue(HelenusPropertyNode p, List value) { + List valueObj = value; - HelenusProperty prop = p.getProperty(); + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + valueObj = (List) converter.get().apply(value); + } - List valueObj = value; + return valueObj; + } - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - valueObj = (List) converter.get().apply(value); - } + /* + * + * + * SET + * + * + */ - return valueObj; - } + public UpdateOperation add(Getter> setGetter, V value) { - /* - * - * - * SET - * - * - */ + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation add(Getter> setGetter, V value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Object valueObj = prepareSingleSetValue(p, value); - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.add(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Object valueObj = prepareSingleSetValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.add(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.add(value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.add(value); - } + public UpdateOperation addAll(Getter> setGetter, Set value) { - return this; - } + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation addAll(Getter> setGetter, Set value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Set valueObj = prepareSetValue(p, value); - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.addAll(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Set valueObj = prepareSetValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.addAll(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.addAll(value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.addAll(value); - } + public UpdateOperation remove(Getter> setGetter, V value) { - return this; - } + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation remove(Getter> setGetter, V value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Object valueObj = prepareSingleSetValue(p, value); - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.remove(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Object valueObj = prepareSingleSetValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.remove(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.remove(value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.remove(value); - } + public UpdateOperation removeAll(Getter> setGetter, Set value) { - return this; - } + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - public UpdateOperation removeAll(Getter> setGetter, Set value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Set valueObj = prepareSetValue(p, value); - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + assignments.add(QueryBuilder.removeAll(p.getColumnName(), valueObj)); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Set valueObj = prepareSetValue(p, value); + addPropertyNode(p); - assignments.add(QueryBuilder.removeAll(p.getColumnName(), valueObj)); + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.removeAll(value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.removeAll(value); - } + private Object prepareSingleSetValue(HelenusPropertyNode p, Object value) { - return this; - } + HelenusProperty prop = p.getProperty(); + Object valueObj = value; - private Object prepareSingleSetValue(HelenusPropertyNode p, Object value) { + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + Set convertedSet = (Set) converter.get().apply(Immutables.setOf(value)); + valueObj = convertedSet.iterator().next(); + } - HelenusProperty prop = p.getProperty(); - Object valueObj = value; + return valueObj; + } - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - Set convertedSet = (Set) converter.get().apply(Immutables.setOf(value)); - valueObj = convertedSet.iterator().next(); - } + private Set prepareSetValue(HelenusPropertyNode p, Set value) { - return valueObj; - } + HelenusProperty prop = p.getProperty(); + Set valueObj = value; - private Set prepareSetValue(HelenusPropertyNode p, Set value) { + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + valueObj = (Set) converter.get().apply(value); + } - HelenusProperty prop = p.getProperty(); - Set valueObj = value; + return valueObj; + } - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - valueObj = (Set) converter.get().apply(value); - } + /* + * + * + * MAP + * + * + */ - return valueObj; - } + public UpdateOperation put(Getter> mapGetter, K key, V value) { - /* - * - * - * MAP - * - * - */ + Objects.requireNonNull(mapGetter, "mapGetter is empty"); + Objects.requireNonNull(key, "key is empty"); - public UpdateOperation put(Getter> mapGetter, K key, V value) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); + HelenusProperty prop = p.getProperty(); - Objects.requireNonNull(mapGetter, "mapGetter is empty"); - Objects.requireNonNull(key, "key is empty"); + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + Map convertedMap = (Map) converter.get() + .apply(Immutables.mapOf(key, value)); + for (Map.Entry e : convertedMap.entrySet()) { + assignments.add(QueryBuilder.put(p.getColumnName(), e.getKey(), e.getValue())); + } + } else { + assignments.add(QueryBuilder.put(p.getColumnName(), key, value)); + } - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); - HelenusProperty prop = p.getProperty(); + addPropertyNode(p); - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - Map convertedMap = - (Map) converter.get().apply(Immutables.mapOf(key, value)); - for (Map.Entry e : convertedMap.entrySet()) { - assignments.add(QueryBuilder.put(p.getColumnName(), e.getKey(), e.getValue())); - } - } else { - assignments.add(QueryBuilder.put(p.getColumnName(), key, value)); - } + if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).put(key, value); + } - addPropertyNode(p); + return this; + } - if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).put(key, value); - } + public UpdateOperation putAll(Getter> mapGetter, Map map) { - return this; - } - - public UpdateOperation putAll(Getter> mapGetter, Map map) { - - Objects.requireNonNull(mapGetter, "mapGetter is empty"); - Objects.requireNonNull(map, "map is empty"); - - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); - HelenusProperty prop = p.getProperty(); - - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - Map convertedMap = (Map) converter.get().apply(map); - assignments.add(QueryBuilder.putAll(p.getColumnName(), convertedMap)); - } else { - assignments.add(QueryBuilder.putAll(p.getColumnName(), map)); - } - - addPropertyNode(p); - - if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).putAll(map); - } - - return this; - } - - @Override - public BuiltStatement buildStatement(boolean cached) { - - if (entity == null) { - throw new HelenusMappingException("empty update operation"); - } - - Update update = QueryBuilder.update(entity.getName().toCql()); - - for (Assignment assignment : assignments) { - update.with(assignment); - } - - if (filters != null && !filters.isEmpty()) { - - for (Filter filter : filters) { - update.where(filter.getClause(sessionOps.getValuePreparer())); - } - } - - if (ifFilters != null && !ifFilters.isEmpty()) { - - for (Filter filter : ifFilters) { - update.onlyIf(filter.getClause(sessionOps.getValuePreparer())); - } - } - - if (this.ttl != null) { - update.using(QueryBuilder.ttl(this.ttl[0])); - } - - if (this.timestamp != null) { - update.using(QueryBuilder.timestamp(this.timestamp[0])); - } - - return update; - } - - @Override - public E transform(ResultSet resultSet) { - if (draft != null) { - return Helenus.map(draft.getEntityClass(), draft.toMap(draftMap)); - } else { - return (E) resultSet; - } - } - - public UpdateOperation usingTtl(int ttl) { - this.ttl = new int[1]; - this.ttl[0] = ttl; - return this; - } - - public UpdateOperation usingTimestamp(long timestamp) { - this.timestamp = new long[1]; - this.timestamp[0] = timestamp; - return this; - } - - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can update columns only in single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } - - @Override - public E sync(UnitOfWork uow) { - if (uow == null) { - return sync(); - } - E result = super.sync(uow); - if (draft != null) { - String key = getStatementCacheKey(); - if (key != null) { - Set set = new HashSet(1); - set.add(result); - uow.getCache().put(key, set); - } - } - return result; - } + Objects.requireNonNull(mapGetter, "mapGetter is empty"); + Objects.requireNonNull(map, "map is empty"); + + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); + HelenusProperty prop = p.getProperty(); + + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + Map convertedMap = (Map) converter.get().apply(map); + assignments.add(QueryBuilder.putAll(p.getColumnName(), convertedMap)); + } else { + assignments.add(QueryBuilder.putAll(p.getColumnName(), map)); + } + + addPropertyNode(p); + + if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).putAll(map); + } + + return this; + } + + @Override + public BuiltStatement buildStatement(boolean cached) { + + if (entity == null) { + throw new HelenusMappingException("empty update operation"); + } + + Update update = QueryBuilder.update(entity.getName().toCql()); + + for (Assignment assignment : assignments) { + update.with(assignment); + } + + if (filters != null && !filters.isEmpty()) { + + for (Filter filter : filters) { + update.where(filter.getClause(sessionOps.getValuePreparer())); + } + } + + if (ifFilters != null && !ifFilters.isEmpty()) { + + for (Filter filter : ifFilters) { + update.onlyIf(filter.getClause(sessionOps.getValuePreparer())); + } + } + + if (this.ttl != null) { + update.using(QueryBuilder.ttl(this.ttl[0])); + } + + if (this.timestamp != null) { + update.using(QueryBuilder.timestamp(this.timestamp[0])); + } + + return update; + } + + @Override + public E transform(ResultSet resultSet) { + if (draft != null) { + return Helenus.map(draft.getEntityClass(), draft.toMap(draftMap)); + } else { + return (E) resultSet; + } + } + + public UpdateOperation usingTtl(int ttl) { + this.ttl = new int[1]; + this.ttl[0] = ttl; + return this; + } + + public UpdateOperation usingTimestamp(long timestamp) { + this.timestamp = new long[1]; + this.timestamp[0] = timestamp; + return this; + } + + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can update columns only in single entity " + + entity.getMappingInterface() + " or " + p.getEntity().getMappingInterface()); + } + } + + @Override + public E sync(UnitOfWork uow) {// throws TimeoutException { + if (uow == null) { + return sync(); + } + E result = super.sync(uow); + // TODO(gburd): Only drafted entity objects are updated in the cache at this + // time. + if (draft != null) { + updateCache(uow, result, getFacets()); + } + return result; + } } diff --git a/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java b/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java index 10eedcb..e2a05ad 100644 --- a/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java +++ b/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java @@ -19,41 +19,34 @@ import java.util.HashMap; import java.util.Map; public enum DefaultPrimitiveTypes { - BOOLEAN(boolean.class, false), - BYTE(byte.class, (byte) 0x0), - CHAR(char.class, (char) 0x0), - SHORT(short.class, (short) 0), - INT(int.class, 0), - LONG(long.class, 0L), - FLOAT(float.class, 0.0f), - DOUBLE(double.class, 0.0); + BOOLEAN(boolean.class, false), BYTE(byte.class, (byte) 0x0), CHAR(char.class, (char) 0x0), SHORT(short.class, + (short) 0), INT(int.class, 0), LONG(long.class, 0L), FLOAT(float.class, 0.0f), DOUBLE(double.class, 0.0); - private final Class primitiveClass; - private final Object defaultValue; + private static final Map, DefaultPrimitiveTypes> map = new HashMap, DefaultPrimitiveTypes>(); - private static final Map, DefaultPrimitiveTypes> map = - new HashMap, DefaultPrimitiveTypes>(); + static { + for (DefaultPrimitiveTypes type : DefaultPrimitiveTypes.values()) { + map.put(type.getPrimitiveClass(), type); + } + } - static { - for (DefaultPrimitiveTypes type : DefaultPrimitiveTypes.values()) { - map.put(type.getPrimitiveClass(), type); - } - } + private final Class primitiveClass; + private final Object defaultValue; - private DefaultPrimitiveTypes(Class primitiveClass, Object defaultValue) { - this.primitiveClass = primitiveClass; - this.defaultValue = defaultValue; - } + private DefaultPrimitiveTypes(Class primitiveClass, Object defaultValue) { + this.primitiveClass = primitiveClass; + this.defaultValue = defaultValue; + } - public static DefaultPrimitiveTypes lookup(Class primitiveClass) { - return map.get(primitiveClass); - } + public static DefaultPrimitiveTypes lookup(Class primitiveClass) { + return map.get(primitiveClass); + } - public Class getPrimitiveClass() { - return primitiveClass; - } + public Class getPrimitiveClass() { + return primitiveClass; + } - public Object getDefaultValue() { - return defaultValue; - } + public Object getDefaultValue() { + return defaultValue; + } } diff --git a/src/main/java/net/helenus/core/reflect/Drafted.java b/src/main/java/net/helenus/core/reflect/Drafted.java index ac134d2..52810b6 100644 --- a/src/main/java/net/helenus/core/reflect/Drafted.java +++ b/src/main/java/net/helenus/core/reflect/Drafted.java @@ -1,11 +1,25 @@ +/* + * Copyright (C) 2015 The Helenus 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 net.helenus.core.reflect; - import java.util.Set; public interface Drafted extends MapExportable { - Set mutated(); + Set mutated(); - T build(); + T build(); } diff --git a/src/main/java/net/helenus/core/reflect/DslExportable.java b/src/main/java/net/helenus/core/reflect/DslExportable.java index 62adcde..fbe7cbc 100644 --- a/src/main/java/net/helenus/core/reflect/DslExportable.java +++ b/src/main/java/net/helenus/core/reflect/DslExportable.java @@ -16,17 +16,18 @@ package net.helenus.core.reflect; import com.datastax.driver.core.Metadata; + import net.helenus.mapping.HelenusEntity; public interface DslExportable { - public static final String GET_ENTITY_METHOD = "getHelenusMappingEntity"; - public static final String GET_PARENT_METHOD = "getParentDslHelenusPropertyNode"; - public static final String SET_METADATA_METHOD = "setCassandraMetadataForHelenusSesion"; + String GET_ENTITY_METHOD = "getHelenusMappingEntity"; + String GET_PARENT_METHOD = "getParentDslHelenusPropertyNode"; + String SET_METADATA_METHOD = "setCassandraMetadataForHelenusSession"; - HelenusEntity getHelenusMappingEntity(); + HelenusEntity getHelenusMappingEntity(); - HelenusPropertyNode getParentDslHelenusPropertyNode(); + HelenusPropertyNode getParentDslHelenusPropertyNode(); - void setCassandraMetadataForHelenusSesion(Metadata metadata); + void setCassandraMetadataForHelenusSession(Metadata metadata); } diff --git a/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java b/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java index d065427..8e40d67 100644 --- a/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java @@ -15,13 +15,15 @@ */ package net.helenus.core.reflect; -import com.datastax.driver.core.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; import java.util.Optional; + +import com.datastax.driver.core.*; + import net.helenus.core.Helenus; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusMappingEntity; @@ -34,180 +36,162 @@ import net.helenus.support.HelenusException; public class DslInvocationHandler implements InvocationHandler { - private HelenusEntity entity = null; - private Metadata metadata = null; + private final Class iface; + private final ClassLoader classLoader; + private final Optional parent; + private final Map map = new HashMap(); + private final Map udtMap = new HashMap(); + private final Map tupleMap = new HashMap(); + private HelenusEntity entity = null; + private Metadata metadata = null; - private final Class iface; - private final ClassLoader classLoader; + public DslInvocationHandler(Class iface, ClassLoader classLoader, Optional parent, + Metadata metadata) { - private final Optional parent; + this.metadata = metadata; + this.parent = parent; + this.iface = iface; + this.classLoader = classLoader; + } - private final Map map = new HashMap(); + public void setCassandraMetadataForHelenusSession(Metadata metadata) { + if (metadata != null) { + this.metadata = metadata; + entity = init(metadata); + } + } - private final Map udtMap = new HashMap(); - private final Map tupleMap = new HashMap(); + private HelenusEntity init(Metadata metadata) { + HelenusEntity entity = new HelenusMappingEntity(iface, metadata); - public DslInvocationHandler( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata) { + for (HelenusProperty prop : entity.getOrderedProperties()) { - this.metadata = metadata; - this.parent = parent; - this.iface = iface; - this.classLoader = classLoader; - } + map.put(prop.getGetterMethod(), prop); - public void setCassandraMetadataForHelenusSesion(Metadata metadata) { - if (metadata != null) { - this.metadata = metadata; - entity = init(metadata); - } - } + AbstractDataType type = prop.getDataType(); + Class javaType = prop.getJavaType(); - private HelenusEntity init(Metadata metadata) { - HelenusEntity entity = new HelenusMappingEntity(iface, metadata); + if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { - for (HelenusProperty prop : entity.getOrderedProperties()) { + Object childDsl = Helenus.dsl(javaType, classLoader, Optional.of(new HelenusPropertyNode(prop, parent)), + metadata); - map.put(prop.getGetterMethod(), prop); + udtMap.put(prop.getGetterMethod(), childDsl); + } - AbstractDataType type = prop.getDataType(); - Class javaType = prop.getJavaType(); + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; - if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { + if (dataType.getDataType() instanceof TupleType && !TupleValue.class.isAssignableFrom(javaType)) { - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + Object childDsl = Helenus.dsl(javaType, classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), metadata); - udtMap.put(prop.getGetterMethod(), childDsl); - } + tupleMap.put(prop.getGetterMethod(), childDsl); + } + } + } - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; + return entity; + } - if (dataType.getDataType() instanceof TupleType - && !TupleValue.class.isAssignableFrom(javaType)) { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + HelenusEntity entity = this.entity; + String methodName = method.getName(); - tupleMap.put(prop.getGetterMethod(), childDsl); - } - } - } + if ("equals".equals(methodName) && method.getParameterCount() == 1) { + Object otherObj = args[0]; + if (otherObj == null) { + return false; + } + if (Proxy.isProxyClass(otherObj.getClass())) { + return this == Proxy.getInvocationHandler(otherObj); + } + return false; + } - return entity; - } + if (DslExportable.SET_METADATA_METHOD.equals(methodName) && args.length == 1 && args[0] instanceof Metadata) { + if (metadata == null) { + this.setCassandraMetadataForHelenusSession((Metadata) args[0]); + } + return null; + } - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { + throw new HelenusException("invalid getter method " + method); + } - HelenusEntity entity = this.entity; - String methodName = method.getName(); + if ("hashCode".equals(methodName)) { + return hashCode(); + } - if ("equals".equals(methodName) && method.getParameterCount() == 1) { - Object otherObj = args[0]; - if (otherObj == null) { - return false; - } - if (Proxy.isProxyClass(otherObj.getClass())) { - return this == Proxy.getInvocationHandler(otherObj); - } - return false; - } + if (DslExportable.GET_PARENT_METHOD.equals(methodName)) { + return parent.get(); + } - if (DslExportable.SET_METADATA_METHOD.equals(methodName) - && args.length == 1 - && args[0] instanceof Metadata) { - if (metadata == null) { - this.setCassandraMetadataForHelenusSesion((Metadata) args[0]); - } - return null; - } + if (entity == null) { + entity = init(metadata); + } - if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { - throw new HelenusException("invalid getter method " + method); - } + if ("toString".equals(methodName)) { + return entity.toString(); + } - if ("hashCode".equals(methodName)) { - return hashCode(); - } + if (DslExportable.GET_ENTITY_METHOD.equals(methodName)) { + return entity; + } - if (DslExportable.GET_PARENT_METHOD.equals(methodName)) { - return parent.get(); - } + HelenusProperty prop = map.get(method); + if (prop == null) { + prop = entity.getProperty(methodName); + } - if (entity == null) { - entity = init(metadata); - } + if (prop != null) { - if ("toString".equals(methodName)) { - return entity.toString(); - } + AbstractDataType type = prop.getDataType(); - if (DslExportable.GET_ENTITY_METHOD.equals(methodName)) { - return entity; - } + if (type instanceof UDTDataType) { - HelenusProperty prop = map.get(method); - if (prop == null) { - prop = entity.getProperty(methodName); - } + Object childDsl = udtMap.get(method); - if (prop != null) { + if (childDsl != null) { + return childDsl; + } + } - AbstractDataType type = prop.getDataType(); + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; + DataType dt = dataType.getDataType(); - if (type instanceof UDTDataType) { + switch (dt.getName()) { + case TUPLE : + Object childDsl = tupleMap.get(method); - Object childDsl = udtMap.get(method); + if (childDsl != null) { + return childDsl; + } - if (childDsl != null) { - return childDsl; - } - } + break; - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; - DataType dt = dataType.getDataType(); + case SET : + return new SetDsl(new HelenusPropertyNode(prop, parent)); - switch (dt.getName()) { - case TUPLE: - Object childDsl = tupleMap.get(method); + case LIST : + return new ListDsl(new HelenusPropertyNode(prop, parent)); - if (childDsl != null) { - return childDsl; - } + case MAP : + return new MapDsl(new HelenusPropertyNode(prop, parent)); - break; + default : + break; + } + } - case SET: - return new SetDsl(new HelenusPropertyNode(prop, parent)); + throw new DslPropertyException(new HelenusPropertyNode(prop, parent)); + } - case LIST: - return new ListDsl(new HelenusPropertyNode(prop, parent)); - - case MAP: - return new MapDsl(new HelenusPropertyNode(prop, parent)); - - default: - break; - } - } - - throw new DslPropertyException(new HelenusPropertyNode(prop, parent)); - } - - throw new HelenusException("invalid method call " + method); - } + throw new HelenusException("invalid method call " + method); + } } diff --git a/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java b/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java index 9c4e448..93bfdf2 100644 --- a/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java +++ b/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java @@ -19,7 +19,9 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Optional; import java.util.function.Function; + import javax.validation.ConstraintValidator; + import net.helenus.core.SessionRepository; import net.helenus.mapping.*; import net.helenus.mapping.type.AbstractDataType; @@ -27,79 +29,79 @@ import net.helenus.support.HelenusMappingException; public final class HelenusNamedProperty implements HelenusProperty { - private final String name; + private final String name; - public HelenusNamedProperty(String name) { - this.name = name; - } + public HelenusNamedProperty(String name) { + this.name = name; + } - @Override - public HelenusEntity getEntity() { - throw new HelenusMappingException("will never called"); - } + @Override + public HelenusEntity getEntity() { + throw new HelenusMappingException("will never called"); + } - @Override - public String getPropertyName() { - return name; - } + @Override + public String getPropertyName() { + return name; + } - @Override - public Method getGetterMethod() { - throw new HelenusMappingException("will never called"); - } + @Override + public Method getGetterMethod() { + throw new HelenusMappingException("will never called"); + } - @Override - public IdentityName getColumnName() { - return IdentityName.of(name, false); - } + @Override + public IdentityName getColumnName() { + return IdentityName.of(name, false); + } - @Override - public Optional getIndexName() { - return Optional.empty(); - } + @Override + public Optional getIndexName() { + return Optional.empty(); + } - @Override - public boolean caseSensitiveIndex() { - return false; - } + @Override + public boolean caseSensitiveIndex() { + return false; + } - @Override - public Class getJavaType() { - throw new HelenusMappingException("will never called"); - } + @Override + public Class getJavaType() { + throw new HelenusMappingException("will never called"); + } - @Override - public AbstractDataType getDataType() { - throw new HelenusMappingException("will never called"); - } + @Override + public AbstractDataType getDataType() { + throw new HelenusMappingException("will never called"); + } - @Override - public ColumnType getColumnType() { - return ColumnType.COLUMN; - } + @Override + public ColumnType getColumnType() { + return ColumnType.COLUMN; + } - @Override - public int getOrdinal() { - return 0; - } + @Override + public int getOrdinal() { + return 0; + } - @Override - public OrderingDirection getOrdering() { - return OrderingDirection.ASC; - } + @Override + public OrderingDirection getOrdering() { + return OrderingDirection.ASC; + } - @Override - public Optional> getReadConverter(SessionRepository repository) { - return Optional.empty(); - } + @Override + public Optional> getReadConverter(SessionRepository repository) { + return Optional.empty(); + } - @Override - public Optional> getWriteConverter(SessionRepository repository) { - return Optional.empty(); - } + @Override + public Optional> getWriteConverter(SessionRepository repository) { + return Optional.empty(); + } - @Override - public ConstraintValidator[] getValidators() { - return MappingUtil.EMPTY_VALIDATORS; - } + @Override + public ConstraintValidator[] getValidators() { + return MappingUtil.EMPTY_VALIDATORS; + } } diff --git a/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java b/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java index b148433..0c28931 100644 --- a/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java +++ b/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java @@ -17,89 +17,90 @@ package net.helenus.core.reflect; import java.util.*; import java.util.stream.Collectors; + import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; public final class HelenusPropertyNode implements Iterable { - private final HelenusProperty prop; - private final Optional next; + private final HelenusProperty prop; + private final Optional next; - public HelenusPropertyNode(HelenusProperty prop, Optional next) { - this.prop = prop; - this.next = next; - } + public HelenusPropertyNode(HelenusProperty prop, Optional next) { + this.prop = prop; + this.next = next; + } - public String getColumnName() { - if (next.isPresent()) { + public String getColumnName() { + if (next.isPresent()) { - List columnNames = new ArrayList(); - for (HelenusProperty p : this) { - columnNames.add(p.getColumnName().toCql(true)); - } - Collections.reverse(columnNames); + List columnNames = new ArrayList(); + for (HelenusProperty p : this) { + columnNames.add(p.getColumnName().toCql(true)); + } + Collections.reverse(columnNames); - if (prop instanceof HelenusNamedProperty) { - int size = columnNames.size(); - StringBuilder str = new StringBuilder(); - for (int i = 0; i != size - 1; ++i) { - if (str.length() != 0) { - str.append("."); - } - str.append(columnNames.get(i)); - } - str.append("[").append(columnNames.get(size - 1)).append("]"); - return str.toString(); - } else { - return columnNames.stream().collect(Collectors.joining(".")); - } - } else { - return prop.getColumnName().toCql(); - } - } + if (prop instanceof HelenusNamedProperty) { + int size = columnNames.size(); + StringBuilder str = new StringBuilder(); + for (int i = 0; i != size - 1; ++i) { + if (str.length() != 0) { + str.append("."); + } + str.append(columnNames.get(i)); + } + str.append("[").append(columnNames.get(size - 1)).append("]"); + return str.toString(); + } else { + return columnNames.stream().collect(Collectors.joining(".")); + } + } else { + return prop.getColumnName().toCql(); + } + } - public HelenusEntity getEntity() { - if (next.isPresent()) { - HelenusProperty last = prop; - for (HelenusProperty p : this) { - last = p; - } - return last.getEntity(); - } else { - return prop.getEntity(); - } - } + public HelenusEntity getEntity() { + if (next.isPresent()) { + HelenusProperty last = prop; + for (HelenusProperty p : this) { + last = p; + } + return last.getEntity(); + } else { + return prop.getEntity(); + } + } - public HelenusProperty getProperty() { - return prop; - } + public HelenusProperty getProperty() { + return prop; + } - public Optional getNext() { - return next; - } + public Optional getNext() { + return next; + } - public Iterator iterator() { - return new PropertyNodeIterator(Optional.of(this)); - } + public Iterator iterator() { + return new PropertyNodeIterator(Optional.of(this)); + } - private static class PropertyNodeIterator implements Iterator { + private static class PropertyNodeIterator implements Iterator { - private Optional next; + private Optional next; - public PropertyNodeIterator(Optional next) { - this.next = next; - } + public PropertyNodeIterator(Optional next) { + this.next = next; + } - @Override - public boolean hasNext() { - return next.isPresent(); - } + @Override + public boolean hasNext() { + return next.isPresent(); + } - @Override - public HelenusProperty next() { - HelenusPropertyNode node = next.get(); - next = node.next; - return node.prop; - } - } + @Override + public HelenusProperty next() { + HelenusPropertyNode node = next.get(); + next = node.next; + return node.prop; + } + } } diff --git a/src/main/java/net/helenus/core/reflect/ListDsl.java b/src/main/java/net/helenus/core/reflect/ListDsl.java index b834098..3a8755f 100644 --- a/src/main/java/net/helenus/core/reflect/ListDsl.java +++ b/src/main/java/net/helenus/core/reflect/ListDsl.java @@ -16,164 +16,165 @@ package net.helenus.core.reflect; import java.util.*; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.DslPropertyException; import net.helenus.support.HelenusMappingException; public final class ListDsl implements List { - private final HelenusPropertyNode parent; + private final HelenusPropertyNode parent; - public ListDsl(HelenusPropertyNode parent) { - this.parent = parent; - } + public ListDsl(HelenusPropertyNode parent) { + this.parent = parent; + } - public HelenusPropertyNode getParent() { - return parent; - } + public HelenusPropertyNode getParent() { + return parent; + } - @Override - public V get(int index) { - HelenusProperty prop = new HelenusNamedProperty(Integer.toString(index)); - throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); - } + @Override + public V get(int index) { + HelenusProperty prop = new HelenusNamedProperty(Integer.toString(index)); + throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); + } - @Override - public int size() { - throwShouldNeverCall(); - return 0; - } + @Override + public int size() { + throwShouldNeverCall(); + return 0; + } - @Override - public boolean isEmpty() { - throwShouldNeverCall(); - return false; - } + @Override + public boolean isEmpty() { + throwShouldNeverCall(); + return false; + } - @Override - public boolean contains(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean contains(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public Iterator iterator() { - throwShouldNeverCall(); - return null; - } + @Override + public Iterator iterator() { + throwShouldNeverCall(); + return null; + } - @Override - public Object[] toArray() { - throwShouldNeverCall(); - return null; - } + @Override + public Object[] toArray() { + throwShouldNeverCall(); + return null; + } - @Override - public T[] toArray(T[] a) { - throwShouldNeverCall(); - return null; - } + @Override + public T[] toArray(T[] a) { + throwShouldNeverCall(); + return null; + } - @Override - public boolean add(V e) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean add(V e) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean remove(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean remove(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean addAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean addAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean addAll(int index, Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean addAll(int index, Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean removeAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean removeAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean retainAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean retainAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public void clear() { - throwShouldNeverCall(); - } + @Override + public void clear() { + throwShouldNeverCall(); + } - @Override - public V set(int index, V element) { - throwShouldNeverCall(); - return null; - } + @Override + public V set(int index, V element) { + throwShouldNeverCall(); + return null; + } - @Override - public void add(int index, V element) { - throwShouldNeverCall(); - } + @Override + public void add(int index, V element) { + throwShouldNeverCall(); + } - @Override - public V remove(int index) { - throwShouldNeverCall(); - return null; - } + @Override + public V remove(int index) { + throwShouldNeverCall(); + return null; + } - @Override - public int indexOf(Object o) { - throwShouldNeverCall(); - return 0; - } + @Override + public int indexOf(Object o) { + throwShouldNeverCall(); + return 0; + } - @Override - public int lastIndexOf(Object o) { - throwShouldNeverCall(); - return 0; - } + @Override + public int lastIndexOf(Object o) { + throwShouldNeverCall(); + return 0; + } - @Override - public ListIterator listIterator() { - throwShouldNeverCall(); - return null; - } + @Override + public ListIterator listIterator() { + throwShouldNeverCall(); + return null; + } - @Override - public ListIterator listIterator(int index) { - throwShouldNeverCall(); - return null; - } + @Override + public ListIterator listIterator(int index) { + throwShouldNeverCall(); + return null; + } - @Override - public List subList(int fromIndex, int toIndex) { - throwShouldNeverCall(); - return null; - } + @Override + public List subList(int fromIndex, int toIndex) { + throwShouldNeverCall(); + return null; + } - private void throwShouldNeverCall() { - throw new HelenusMappingException("should be never called"); - } + private void throwShouldNeverCall() { + throw new HelenusMappingException("should be never called"); + } - @Override - public String toString() { - return "ListDsl"; - } + @Override + public String toString() { + return "ListDsl"; + } } diff --git a/src/main/java/net/helenus/core/reflect/MapDsl.java b/src/main/java/net/helenus/core/reflect/MapDsl.java index 7c1828d..c6d4cc6 100644 --- a/src/main/java/net/helenus/core/reflect/MapDsl.java +++ b/src/main/java/net/helenus/core/reflect/MapDsl.java @@ -19,98 +19,99 @@ import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.Set; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.DslPropertyException; import net.helenus.support.HelenusMappingException; public final class MapDsl implements Map { - private final HelenusPropertyNode parent; + private final HelenusPropertyNode parent; - public MapDsl(HelenusPropertyNode parent) { - this.parent = parent; - } + public MapDsl(HelenusPropertyNode parent) { + this.parent = parent; + } - public HelenusPropertyNode getParent() { - return parent; - } + public HelenusPropertyNode getParent() { + return parent; + } - @Override - public V get(Object key) { - HelenusProperty prop = new HelenusNamedProperty(key.toString()); - throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); - } + @Override + public V get(Object key) { + HelenusProperty prop = new HelenusNamedProperty(key.toString()); + throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); + } - @Override - public int size() { - throwShouldNeverCall(); - return 0; - } + @Override + public int size() { + throwShouldNeverCall(); + return 0; + } - @Override - public boolean isEmpty() { - throwShouldNeverCall(); - return false; - } + @Override + public boolean isEmpty() { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsKey(Object key) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsKey(Object key) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsValue(Object value) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsValue(Object value) { + throwShouldNeverCall(); + return false; + } - @Override - public V put(K key, V value) { - throwShouldNeverCall(); - return null; - } + @Override + public V put(K key, V value) { + throwShouldNeverCall(); + return null; + } - @Override - public V remove(Object key) { - throwShouldNeverCall(); - return null; - } + @Override + public V remove(Object key) { + throwShouldNeverCall(); + return null; + } - @Override - public void putAll(Map m) { - throwShouldNeverCall(); - } + @Override + public void putAll(Map m) { + throwShouldNeverCall(); + } - @Override - public void clear() { - throwShouldNeverCall(); - } + @Override + public void clear() { + throwShouldNeverCall(); + } - @Override - public Set keySet() { - throwShouldNeverCall(); - return null; - } + @Override + public Set keySet() { + throwShouldNeverCall(); + return null; + } - @Override - public Collection values() { - throwShouldNeverCall(); - return null; - } + @Override + public Collection values() { + throwShouldNeverCall(); + return null; + } - @Override - public Set> entrySet() { - throwShouldNeverCall(); - return null; - } + @Override + public Set> entrySet() { + throwShouldNeverCall(); + return null; + } - private void throwShouldNeverCall() { - throw new HelenusMappingException("should be never called"); - } + private void throwShouldNeverCall() { + throw new HelenusMappingException("should be never called"); + } - @Override - public String toString() { - return "MapDsl"; - } + @Override + public String toString() { + return "MapDsl"; + } } diff --git a/src/main/java/net/helenus/core/reflect/MapExportable.java b/src/main/java/net/helenus/core/reflect/MapExportable.java index 9160cc8..2e71bdf 100644 --- a/src/main/java/net/helenus/core/reflect/MapExportable.java +++ b/src/main/java/net/helenus/core/reflect/MapExportable.java @@ -19,7 +19,7 @@ import java.util.Map; public interface MapExportable { - public static final String TO_MAP_METHOD = "toMap"; + public static final String TO_MAP_METHOD = "toMap"; - Map toMap(); + Map toMap(); } diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 4845c11..e45b6f7 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -23,106 +23,113 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collections; import java.util.Map; + import net.helenus.core.Helenus; import net.helenus.mapping.annotation.Transient; import net.helenus.support.HelenusException; public class MapperInvocationHandler implements InvocationHandler, Serializable { - private static final long serialVersionUID = -7044209982830584984L; + private static final long serialVersionUID = -7044209982830584984L; - private final Map src; - private final Class iface; + private final Map src; + private final Class iface; - public MapperInvocationHandler(Class iface, Map src) { - this.src = src; - this.iface = iface; - } + public MapperInvocationHandler(Class iface, Map src) { + this.src = src; + this.iface = iface; + } - private Object invokeDefault(Object proxy, Method method, Object[] args) throws Throwable { - // NOTE: This is reflection magic to invoke (non-recursively) a default method implemented on an interface - // that we've proxied (in ReflectionDslInstantiator). I found the answer in this article. - // https://zeroturnaround.com/rebellabs/recognize-and-conquer-java-proxies-default-methods-and-method-handles/ + private Object invokeDefault(Object proxy, Method method, Object[] args) throws Throwable { + // NOTE: This is reflection magic to invoke (non-recursively) a default method + // implemented on an interface + // that we've proxied (in ReflectionDslInstantiator). I found the answer in this + // article. + // https://zeroturnaround.com/rebellabs/recognize-and-conquer-java-proxies-default-methods-and-method-handles/ - // First, we need an instance of a private inner-class found in MethodHandles. - Constructor constructor = - MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class); - constructor.setAccessible(true); + // First, we need an instance of a private inner-class found in MethodHandles. + Constructor constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, + int.class); + constructor.setAccessible(true); - // Now we need to lookup and invoke special the default method on the interface class. - final Class declaringClass = method.getDeclaringClass(); - Object result = - constructor - .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) - .unreflectSpecial(method, declaringClass) - .bindTo(proxy) - .invokeWithArguments(args); - return result; - } + // Now we need to lookup and invoke special the default method on the interface + // class. + final Class declaringClass = method.getDeclaringClass(); + Object result = constructor.newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) + .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); + return result; + } - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // Transient, default methods should simply be invoked as-is. - if (method.isDefault() && method.getDeclaredAnnotation(Transient.class) != null) { - return invokeDefault(proxy, method, args); - } + // Transient, default methods should simply be invoked as-is. + if (method.isDefault() && method.getDeclaredAnnotation(Transient.class) != null) { + return invokeDefault(proxy, method, args); + } - String methodName = method.getName(); + String methodName = method.getName(); - if ("equals".equals(methodName) && method.getParameterCount() == 1) { - Object otherObj = args[0]; - if (otherObj == null) { - return false; - } - if (Proxy.isProxyClass(otherObj.getClass())) { - return this == Proxy.getInvocationHandler(otherObj); - } - return false; - } + if ("equals".equals(methodName) && method.getParameterCount() == 1) { + Object otherObj = args[0]; + if (otherObj == null) { + return false; + } + if (Proxy.isProxyClass(otherObj.getClass())) { + if (this == Proxy.getInvocationHandler(otherObj)) { + return true; + } + } + if (otherObj instanceof MapExportable && src.equals(((MapExportable) otherObj).toMap())) { + return true; + } + return false; + } - if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { - throw new HelenusException("invalid getter method " + method); - } + if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { + throw new HelenusException("invalid getter method " + method); + } - if ("hashCode".equals(methodName)) { - return hashCode(); - } + if ("hashCode".equals(methodName)) { + return hashCode(); + } - if ("toString".equals(methodName)) { - return iface.getSimpleName() + ": " + src.toString(); - } + if ("toString".equals(methodName)) { + return iface.getSimpleName() + ": " + src.toString(); + } - if ("dsl".equals(methodName)) { - return Helenus.dsl(iface); - } + if ("dsl".equals(methodName)) { + return Helenus.dsl(iface); + } - if (MapExportable.TO_MAP_METHOD.equals(methodName)) { - return Collections.unmodifiableMap(src); - } + if (MapExportable.TO_MAP_METHOD.equals(methodName)) { + return Collections.unmodifiableMap(src); + } - Object value = src.get(methodName); + Object value = src.get(methodName); - Class returnType = method.getReturnType(); + Class returnType = method.getReturnType(); - if (value == null) { + if (value == null) { - // Default implementations of non-Transient methods in entities are the default value when the - // map contains 'null'. - if (method.isDefault()) { - return invokeDefault(proxy, method, args); - } + // Default implementations of non-Transient methods in entities are the default + // value when the + // map contains 'null'. + if (method.isDefault()) { + return invokeDefault(proxy, method, args); + } - // Otherwise, if the return type of the method is a primitive Java type then we'll return the standard - // default values to avoid a NPE in user code. - if (returnType.isPrimitive()) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); - if (type == null) { - throw new HelenusException("unknown primitive type " + returnType); - } - return type.getDefaultValue(); - } - } + // Otherwise, if the return type of the method is a primitive Java type then + // we'll return the standard + // default values to avoid a NPE in user code. + if (returnType.isPrimitive()) { + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); + if (type == null) { + throw new HelenusException("unknown primitive type " + returnType); + } + return type.getDefaultValue(); + } + } - return value; - } + return value; + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java index 7f1b218..7e30435 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java @@ -15,25 +15,22 @@ */ package net.helenus.core.reflect; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Proxy; import java.util.Optional; + +import com.datastax.driver.core.Metadata; + import net.helenus.core.DslInstantiator; public enum ReflectionDslInstantiator implements DslInstantiator { - INSTANCE; + INSTANCE; - @Override - @SuppressWarnings("unchecked") - public E instantiate( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata) { - DslInvocationHandler handler = - new DslInvocationHandler(iface, classLoader, parent, metadata); - E proxy = - (E) Proxy.newProxyInstance(classLoader, new Class[] {iface, DslExportable.class}, handler); - return proxy; - } + @Override + @SuppressWarnings("unchecked") + public E instantiate(Class iface, ClassLoader classLoader, Optional parent, + Metadata metadata) { + DslInvocationHandler handler = new DslInvocationHandler(iface, classLoader, parent, metadata); + E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, DslExportable.class}, handler); + return proxy; + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java index c7e40f8..748d88a 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java @@ -19,14 +19,15 @@ import net.helenus.support.HelenusMappingException; public final class ReflectionInstantiator { - private ReflectionInstantiator() {} + private ReflectionInstantiator() { + } - public static T instantiateClass(Class clazz) { + public static T instantiateClass(Class clazz) { - try { - return clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new HelenusMappingException("invalid class " + clazz, e); - } - } + try { + return clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new HelenusMappingException("invalid class " + clazz, e); + } + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java index a3df3f1..811a682 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java @@ -17,18 +17,18 @@ package net.helenus.core.reflect; import java.lang.reflect.Proxy; import java.util.Map; + import net.helenus.core.MapperInstantiator; public enum ReflectionMapperInstantiator implements MapperInstantiator { - INSTANCE; + INSTANCE; - @Override - @SuppressWarnings("unchecked") - public E instantiate(Class iface, Map src, ClassLoader classLoader) { + @Override + @SuppressWarnings("unchecked") + public E instantiate(Class iface, Map src, ClassLoader classLoader) { - MapperInvocationHandler handler = new MapperInvocationHandler(iface, src); - E proxy = - (E) Proxy.newProxyInstance(classLoader, new Class[] {iface, MapExportable.class}, handler); - return proxy; - } + MapperInvocationHandler handler = new MapperInvocationHandler(iface, src); + E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, MapExportable.class}, handler); + return proxy; + } } diff --git a/src/main/java/net/helenus/core/reflect/SetDsl.java b/src/main/java/net/helenus/core/reflect/SetDsl.java index 6a55118..663b945 100644 --- a/src/main/java/net/helenus/core/reflect/SetDsl.java +++ b/src/main/java/net/helenus/core/reflect/SetDsl.java @@ -18,103 +18,104 @@ package net.helenus.core.reflect; import java.util.Collection; import java.util.Iterator; import java.util.Set; + import net.helenus.support.HelenusMappingException; public final class SetDsl implements Set { - private final HelenusPropertyNode parent; + private final HelenusPropertyNode parent; - public SetDsl(HelenusPropertyNode parent) { - this.parent = parent; - } + public SetDsl(HelenusPropertyNode parent) { + this.parent = parent; + } - public HelenusPropertyNode getParent() { - return parent; - } + public HelenusPropertyNode getParent() { + return parent; + } - @Override - public int size() { - throwShouldNeverCall(); - return 0; - } + @Override + public int size() { + throwShouldNeverCall(); + return 0; + } - @Override - public boolean isEmpty() { - throwShouldNeverCall(); - return false; - } + @Override + public boolean isEmpty() { + throwShouldNeverCall(); + return false; + } - @Override - public boolean contains(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean contains(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public Iterator iterator() { - throwShouldNeverCall(); - return null; - } + @Override + public Iterator iterator() { + throwShouldNeverCall(); + return null; + } - @Override - public Object[] toArray() { - throwShouldNeverCall(); - return null; - } + @Override + public Object[] toArray() { + throwShouldNeverCall(); + return null; + } - @Override - public T[] toArray(T[] a) { - throwShouldNeverCall(); - return null; - } + @Override + public T[] toArray(T[] a) { + throwShouldNeverCall(); + return null; + } - @Override - public boolean add(V e) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean add(V e) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean remove(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean remove(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean addAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean addAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean retainAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean retainAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean removeAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean removeAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public void clear() { - throwShouldNeverCall(); - } + @Override + public void clear() { + throwShouldNeverCall(); + } - private void throwShouldNeverCall() { - throw new HelenusMappingException("should be never called"); - } + private void throwShouldNeverCall() { + throw new HelenusMappingException("should be never called"); + } - @Override - public String toString() { - return "SetDsl"; - } + @Override + public String toString() { + return "SetDsl"; + } } diff --git a/src/main/java/net/helenus/mapping/ColumnInformation.java b/src/main/java/net/helenus/mapping/ColumnInformation.java index fa6d25f..5ba9ddd 100644 --- a/src/main/java/net/helenus/mapping/ColumnInformation.java +++ b/src/main/java/net/helenus/mapping/ColumnInformation.java @@ -16,6 +16,7 @@ package net.helenus.mapping; import java.lang.reflect.Method; + import net.helenus.mapping.annotation.ClusteringColumn; import net.helenus.mapping.annotation.Column; import net.helenus.mapping.annotation.PartitionKey; @@ -24,99 +25,91 @@ import net.helenus.support.HelenusMappingException; public final class ColumnInformation { - private final IdentityName columnName; - private final ColumnType columnType; - private final int ordinal; - private final OrderingDirection ordering; + private final IdentityName columnName; + private final ColumnType columnType; + private final int ordinal; + private final OrderingDirection ordering; - public ColumnInformation(Method getter) { + public ColumnInformation(Method getter) { - String columnName = null; - boolean forceQuote = false; - ColumnType columnTypeLocal = ColumnType.COLUMN; - int ordinalLocal = 0; - OrderingDirection orderingLocal = OrderingDirection.ASC; + String columnName = null; + boolean forceQuote = false; + ColumnType columnTypeLocal = ColumnType.COLUMN; + int ordinalLocal = 0; + OrderingDirection orderingLocal = OrderingDirection.ASC; - PartitionKey partitionKey = getter.getDeclaredAnnotation(PartitionKey.class); - if (partitionKey != null) { - columnName = partitionKey.value(); - forceQuote = partitionKey.forceQuote(); - columnTypeLocal = ColumnType.PARTITION_KEY; - ordinalLocal = partitionKey.ordinal(); - } + PartitionKey partitionKey = getter.getDeclaredAnnotation(PartitionKey.class); + if (partitionKey != null) { + columnName = partitionKey.value(); + forceQuote = partitionKey.forceQuote(); + columnTypeLocal = ColumnType.PARTITION_KEY; + ordinalLocal = partitionKey.ordinal(); + } - ClusteringColumn clusteringColumn = getter.getDeclaredAnnotation(ClusteringColumn.class); - if (clusteringColumn != null) { - ensureSingleColumnType(columnTypeLocal, getter); - columnName = clusteringColumn.value(); - forceQuote = clusteringColumn.forceQuote(); - columnTypeLocal = ColumnType.CLUSTERING_COLUMN; - ordinalLocal = clusteringColumn.ordinal(); - orderingLocal = clusteringColumn.ordering(); - } + ClusteringColumn clusteringColumn = getter.getDeclaredAnnotation(ClusteringColumn.class); + if (clusteringColumn != null) { + ensureSingleColumnType(columnTypeLocal, getter); + columnName = clusteringColumn.value(); + forceQuote = clusteringColumn.forceQuote(); + columnTypeLocal = ColumnType.CLUSTERING_COLUMN; + ordinalLocal = clusteringColumn.ordinal(); + orderingLocal = clusteringColumn.ordering(); + } - StaticColumn staticColumn = getter.getDeclaredAnnotation(StaticColumn.class); - if (staticColumn != null) { - ensureSingleColumnType(columnTypeLocal, getter); - columnName = staticColumn.value(); - forceQuote = staticColumn.forceQuote(); - columnTypeLocal = ColumnType.STATIC_COLUMN; - ordinalLocal = staticColumn.ordinal(); - } + StaticColumn staticColumn = getter.getDeclaredAnnotation(StaticColumn.class); + if (staticColumn != null) { + ensureSingleColumnType(columnTypeLocal, getter); + columnName = staticColumn.value(); + forceQuote = staticColumn.forceQuote(); + columnTypeLocal = ColumnType.STATIC_COLUMN; + ordinalLocal = staticColumn.ordinal(); + } - Column column = getter.getDeclaredAnnotation(Column.class); - if (column != null) { - ensureSingleColumnType(columnTypeLocal, getter); - columnName = column.value(); - forceQuote = column.forceQuote(); - columnTypeLocal = ColumnType.COLUMN; - ordinalLocal = column.ordinal(); - } + Column column = getter.getDeclaredAnnotation(Column.class); + if (column != null) { + ensureSingleColumnType(columnTypeLocal, getter); + columnName = column.value(); + forceQuote = column.forceQuote(); + columnTypeLocal = ColumnType.COLUMN; + ordinalLocal = column.ordinal(); + } - if (columnName == null || columnName.isEmpty()) { - columnName = MappingUtil.getDefaultColumnName(getter); - } + if (columnName == null || columnName.isEmpty()) { + columnName = MappingUtil.getDefaultColumnName(getter); + } - this.columnName = new IdentityName(columnName, forceQuote); - this.columnType = columnTypeLocal; - this.ordinal = ordinalLocal; - this.ordering = orderingLocal; - } + this.columnName = new IdentityName(columnName, forceQuote); + this.columnType = columnTypeLocal; + this.ordinal = ordinalLocal; + this.ordering = orderingLocal; + } - public IdentityName getColumnName() { - return columnName; - } + public IdentityName getColumnName() { + return columnName; + } - public ColumnType getColumnType() { - return columnType; - } + public ColumnType getColumnType() { + return columnType; + } - public int getOrdinal() { - return ordinal; - } + public int getOrdinal() { + return ordinal; + } - public OrderingDirection getOrdering() { - return ordering; - } + public OrderingDirection getOrdering() { + return ordering; + } - private void ensureSingleColumnType(ColumnType columnTypeLocal, Method getter) { + private void ensureSingleColumnType(ColumnType columnTypeLocal, Method getter) { - if (columnTypeLocal != ColumnType.COLUMN) { - throw new HelenusMappingException( - "property can be annotated only by a single column type " + getter); - } - } + if (columnTypeLocal != ColumnType.COLUMN) { + throw new HelenusMappingException("property can be annotated only by a single column type " + getter); + } + } - @Override - public String toString() { - return "ColumnInformation [columnName=" - + columnName - + ", columnType=" - + columnType - + ", ordinal=" - + ordinal - + ", ordering=" - + ordering - + "]"; - } + @Override + public String toString() { + return "ColumnInformation [columnName=" + columnName + ", columnType=" + columnType + ", ordinal=" + ordinal + + ", ordering=" + ordering + "]"; + } } diff --git a/src/main/java/net/helenus/mapping/ColumnType.java b/src/main/java/net/helenus/mapping/ColumnType.java index eb8407d..e56b079 100644 --- a/src/main/java/net/helenus/mapping/ColumnType.java +++ b/src/main/java/net/helenus/mapping/ColumnType.java @@ -16,8 +16,5 @@ package net.helenus.mapping; public enum ColumnType { - PARTITION_KEY, - CLUSTERING_COLUMN, - STATIC_COLUMN, - COLUMN; + PARTITION_KEY, CLUSTERING_COLUMN, STATIC_COLUMN, COLUMN; } diff --git a/src/main/java/net/helenus/mapping/HelenusEntity.java b/src/main/java/net/helenus/mapping/HelenusEntity.java index 6953d2e..3b99de5 100644 --- a/src/main/java/net/helenus/mapping/HelenusEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusEntity.java @@ -16,18 +16,23 @@ package net.helenus.mapping; import java.util.Collection; +import java.util.List; + +import net.helenus.core.cache.Facet; public interface HelenusEntity { - HelenusEntityType getType(); + HelenusEntityType getType(); - boolean isCacheable(); + boolean isCacheable(); - Class getMappingInterface(); + Class getMappingInterface(); - IdentityName getName(); + IdentityName getName(); - Collection getOrderedProperties(); + Collection getOrderedProperties(); - HelenusProperty getProperty(String name); + HelenusProperty getProperty(String name); + + List getFacets(); } diff --git a/src/main/java/net/helenus/mapping/HelenusEntityType.java b/src/main/java/net/helenus/mapping/HelenusEntityType.java index 2ef8d63..0924ec7 100644 --- a/src/main/java/net/helenus/mapping/HelenusEntityType.java +++ b/src/main/java/net/helenus/mapping/HelenusEntityType.java @@ -16,8 +16,5 @@ package net.helenus.mapping; public enum HelenusEntityType { - TABLE, - VIEW, - TUPLE, - UDT; + TABLE, VIEW, TUPLE, UDT; } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index 570d7b9..11f9790 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -15,275 +15,293 @@ */ package net.helenus.mapping; -import com.datastax.driver.core.*; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import java.lang.reflect.Method; import java.util.*; + +import org.apache.commons.lang3.ClassUtils; + +import com.datastax.driver.core.DefaultMetadata; +import com.datastax.driver.core.Metadata; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + import net.helenus.config.HelenusSettings; import net.helenus.core.Helenus; import net.helenus.core.annotation.Cacheable; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.UnboundFacet; import net.helenus.mapping.annotation.*; import net.helenus.support.HelenusMappingException; -import org.apache.commons.lang3.ClassUtils; public final class HelenusMappingEntity implements HelenusEntity { - private final Class iface; - private final HelenusEntityType type; - private final IdentityName name; - private final boolean cacheable; - private final ImmutableMap methods; - private final ImmutableMap props; - private final ImmutableList orderedProps; + private final Class iface; + private final HelenusEntityType type; + private final IdentityName name; + private final boolean cacheable; + private final ImmutableMap methods; + private final ImmutableMap props; + private final ImmutableList orderedProps; + private final List facets; - public HelenusMappingEntity(Class iface, Metadata metadata) { - this(iface, autoDetectType(iface), metadata); - } + public HelenusMappingEntity(Class iface, Metadata metadata) { + this(iface, autoDetectType(iface), metadata); + } - public HelenusMappingEntity(Class iface, HelenusEntityType type, Metadata metadata) { + public HelenusMappingEntity(Class iface, HelenusEntityType type, Metadata metadata) { - if (iface == null || !iface.isInterface()) { - throw new IllegalArgumentException("invalid parameter " + iface); - } + if (iface == null || !iface.isInterface()) { + throw new IllegalArgumentException("invalid parameter " + iface); + } - this.iface = iface; - this.type = Objects.requireNonNull(type, "type is empty"); - this.name = resolveName(iface, type); + this.iface = iface; + this.type = Objects.requireNonNull(type, "type is empty"); + this.name = resolveName(iface, type); - HelenusSettings settings = Helenus.settings(); + HelenusSettings settings = Helenus.settings(); - Map methods = new HashMap(); - for (Method m : iface.getDeclaredMethods()) { - methods.put(m.getName(), m); - } + Map methods = new HashMap(); + for (Method m : iface.getDeclaredMethods()) { + methods.put(m.getName(), m); + } - for (Class c : ClassUtils.getAllInterfaces(iface)) { - if (c.getDeclaredAnnotation(Table.class) != null - || c.getDeclaredAnnotation(InheritedTable.class) != null) { - for (Method m : c.getDeclaredMethods()) { - Method o = methods.get(m.getName()); - if (o != null) { - // Prefer overridden method implementation. - if (o.getDeclaringClass().isAssignableFrom(m.getDeclaringClass())) { - methods.put(m.getName(), m); - } - } else { - methods.put(m.getName(), m); - } - } - } - } + for (Class c : ClassUtils.getAllInterfaces(iface)) { + if (c.getDeclaredAnnotation(Table.class) != null || c.getDeclaredAnnotation(InheritedTable.class) != null) { + for (Method m : c.getDeclaredMethods()) { + Method o = methods.get(m.getName()); + if (o != null) { + // Prefer overridden method implementation. + if (o.getDeclaringClass().isAssignableFrom(m.getDeclaringClass())) { + methods.put(m.getName(), m); + } + } else { + methods.put(m.getName(), m); + } + } + } + } - List propsLocal = new ArrayList(); - ImmutableMap.Builder propsBuilder = ImmutableMap.builder(); - ImmutableMap.Builder methodsBuilder = ImmutableMap.builder(); + List propsLocal = new ArrayList(); + ImmutableMap.Builder propsBuilder = ImmutableMap.builder(); + ImmutableMap.Builder methodsBuilder = ImmutableMap.builder(); - for (Method method : methods.values()) { + for (Method method : methods.values()) { - if (settings.getGetterMethodDetector().apply(method)) { + if (settings.getGetterMethodDetector().apply(method)) { - methodsBuilder.put(method.getName(), method); + methodsBuilder.put(method.getName(), method); - if (metadata != null) { - HelenusProperty prop = new HelenusMappingProperty(this, method, metadata); + if (metadata != null) { + HelenusProperty prop = new HelenusMappingProperty(this, method, metadata); - propsBuilder.put(prop.getPropertyName(), prop); - propsLocal.add(prop); - } - } - } + propsBuilder.put(prop.getPropertyName(), prop); + propsLocal.add(prop); + } + } + } - this.methods = methodsBuilder.build(); - this.props = propsBuilder.build(); + this.methods = methodsBuilder.build(); + this.props = propsBuilder.build(); - Collections.sort(propsLocal, TypeAndOrdinalColumnComparator.INSTANCE); - this.orderedProps = ImmutableList.copyOf(propsLocal); + Collections.sort(propsLocal, TypeAndOrdinalColumnComparator.INSTANCE); + this.orderedProps = ImmutableList.copyOf(propsLocal); - validateOrdinals(); + validateOrdinals(); - cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class)); - } + // Caching + cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class)); - @Override - public HelenusEntityType getType() { - return type; - } + List primaryKeyProperties = new ArrayList<>(); + ImmutableList.Builder facetsBuilder = ImmutableList.builder(); + facetsBuilder.add(new Facet("table", name.toCql()).setFixed()); + for (HelenusProperty prop : orderedProps) { + switch (prop.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + primaryKeyProperties.add(prop); + break; + default : + if (primaryKeyProperties != null && primaryKeyProperties.size() > 0) { + facetsBuilder.add(new UnboundFacet(primaryKeyProperties)); + primaryKeyProperties = null; + } + Optional optionalIndexName = prop.getIndexName(); + if (optionalIndexName.isPresent()) { + UnboundFacet facet = new UnboundFacet(prop); + facetsBuilder.add(facet); + } + } + } + if (primaryKeyProperties != null && primaryKeyProperties.size() > 0) { + facetsBuilder.add(new UnboundFacet(primaryKeyProperties)); + } + this.facets = facetsBuilder.build(); + } - @Override - public boolean isCacheable() { - return cacheable; - } + private static IdentityName resolveName(Class iface, HelenusEntityType type) { - @Override - public Class getMappingInterface() { - return iface; - } + switch (type) { + case TABLE : + return MappingUtil.getTableName(iface, true); - @Override - public Collection getOrderedProperties() { - return orderedProps; - } + case VIEW : + return MappingUtil.getViewName(iface, true); - @Override - public HelenusProperty getProperty(String name) { - HelenusProperty property = props.get(name); - if (property == null && methods.containsKey(name)) { - property = new HelenusMappingProperty(this, methods.get(name), new DefaultMetadata()); - return property; //TODO(gburd): review adding these into the props map... - } - return props.get(name); - } + case TUPLE : + return IdentityName.of(MappingUtil.getDefaultEntityName(iface), false); - @Override - public IdentityName getName() { - return name; - } + case UDT : + return MappingUtil.getUserDefinedTypeName(iface, true); + } - private static IdentityName resolveName(Class iface, HelenusEntityType type) { + throw new HelenusMappingException("invalid entity type " + type + " in " + type); + } - switch (type) { - case TABLE: - return MappingUtil.getTableName(iface, true); + private static HelenusEntityType autoDetectType(Class iface) { - case VIEW: - return MappingUtil.getViewName(iface, true); + Objects.requireNonNull(iface, "empty iface"); - case TUPLE: - return IdentityName.of(MappingUtil.getDefaultEntityName(iface), false); + if (null != iface.getDeclaredAnnotation(Table.class)) { + return HelenusEntityType.TABLE; + } else if (null != iface.getDeclaredAnnotation(MaterializedView.class)) { + return HelenusEntityType.VIEW; + } else if (null != iface.getDeclaredAnnotation(Tuple.class)) { + return HelenusEntityType.TUPLE; + } else if (null != iface.getDeclaredAnnotation(UDT.class)) { + return HelenusEntityType.UDT; + } - case UDT: - return MappingUtil.getUserDefinedTypeName(iface, true); - } + throw new HelenusMappingException("entity must be annotated by @Table or @Tuple or @UserDefinedType " + iface); + } - throw new HelenusMappingException("invalid entity type " + type + " in " + type); - } + @Override + public HelenusEntityType getType() { + return type; + } - private static HelenusEntityType autoDetectType(Class iface) { + @Override + public boolean isCacheable() { + return cacheable; + } - Objects.requireNonNull(iface, "empty iface"); + @Override + public Class getMappingInterface() { + return iface; + } - if (null != iface.getDeclaredAnnotation(Table.class)) { - return HelenusEntityType.TABLE; - } else if (null != iface.getDeclaredAnnotation(MaterializedView.class)) { - return HelenusEntityType.VIEW; - } else if (null != iface.getDeclaredAnnotation(Tuple.class)) { - return HelenusEntityType.TUPLE; - } else if (null != iface.getDeclaredAnnotation(UDT.class)) { - return HelenusEntityType.UDT; - } + @Override + public Collection getOrderedProperties() { + return orderedProps; + } - throw new HelenusMappingException( - "entity must be annotated by @Table or @Tuple or @UserDefinedType " + iface); - } + @Override + public HelenusProperty getProperty(String name) { + HelenusProperty property = props.get(name); + if (property == null && methods.containsKey(name)) { + property = new HelenusMappingProperty(this, methods.get(name), new DefaultMetadata()); + return property; // TODO(gburd): review adding these into the props map... + } + return props.get(name); + } - private void validateOrdinals() { + @Override + public List getFacets() { + return facets; + } - switch (getType()) { - case TABLE: - validateOrdinalsForTable(); - break; + @Override + public IdentityName getName() { + return name; + } - case TUPLE: - validateOrdinalsInTuple(); - break; + private void validateOrdinals() { - default: - break; - } - } + switch (getType()) { + case TABLE : + validateOrdinalsForTable(); + break; - private void validateOrdinalsForTable() { + case TUPLE : + validateOrdinalsInTuple(); + break; - BitSet partitionKeys = new BitSet(); - BitSet clusteringColumns = new BitSet(); + default : + break; + } + } - for (HelenusProperty prop : getOrderedProperties()) { + private void validateOrdinalsForTable() { - ColumnType type = prop.getColumnType(); + BitSet partitionKeys = new BitSet(); + BitSet clusteringColumns = new BitSet(); - int ordinal = prop.getOrdinal(); + for (HelenusProperty prop : getOrderedProperties()) { - switch (type) { - case PARTITION_KEY: - if (partitionKeys.get(ordinal)) { - throw new HelenusMappingException( - "detected two or more partition key columns with the same ordinal " - + ordinal - + " in " - + prop.getEntity()); - } - partitionKeys.set(ordinal); - break; + ColumnType type = prop.getColumnType(); - case CLUSTERING_COLUMN: - if (clusteringColumns.get(ordinal)) { - throw new HelenusMappingException( - "detected two or clustering columns with the same ordinal " - + ordinal - + " in " - + prop.getEntity()); - } - clusteringColumns.set(ordinal); - break; + int ordinal = prop.getOrdinal(); - default: - break; - } - } - } + switch (type) { + case PARTITION_KEY : + if (partitionKeys.get(ordinal)) { + throw new HelenusMappingException( + "detected two or more partition key columns with the same ordinal " + ordinal + " in " + + prop.getEntity()); + } + partitionKeys.set(ordinal); + break; - private void validateOrdinalsInTuple() { - boolean[] ordinals = new boolean[props.size()]; + case CLUSTERING_COLUMN : + if (clusteringColumns.get(ordinal)) { + throw new HelenusMappingException("detected two or clustering columns with the same ordinal " + + ordinal + " in " + prop.getEntity()); + } + clusteringColumns.set(ordinal); + break; - getOrderedProperties() - .forEach( - p -> { - int ordinal = p.getOrdinal(); + default : + break; + } + } + } - if (ordinal < 0 || ordinal >= ordinals.length) { - throw new HelenusMappingException( - "invalid ordinal " - + ordinal - + " found for property " - + p.getPropertyName() - + " in " - + p.getEntity()); - } + private void validateOrdinalsInTuple() { + boolean[] ordinals = new boolean[props.size()]; - if (ordinals[ordinal]) { - throw new HelenusMappingException( - "detected two or more properties with the same ordinal " - + ordinal - + " in " - + p.getEntity()); - } + getOrderedProperties().forEach(p -> { + int ordinal = p.getOrdinal(); - ordinals[ordinal] = true; - }); + if (ordinal < 0 || ordinal >= ordinals.length) { + throw new HelenusMappingException("invalid ordinal " + ordinal + " found for property " + + p.getPropertyName() + " in " + p.getEntity()); + } - for (int i = 0; i != ordinals.length; ++i) { - if (!ordinals[i]) { - throw new HelenusMappingException("detected absent ordinal " + i + " in " + this); - } - } - } + if (ordinals[ordinal]) { + throw new HelenusMappingException( + "detected two or more properties with the same ordinal " + ordinal + " in " + p.getEntity()); + } - @Override - public String toString() { + ordinals[ordinal] = true; + }); - StringBuilder str = new StringBuilder(); - str.append(iface.getSimpleName()) - .append("(") - .append(name.getName()) - .append(") ") - .append(type.name().toLowerCase()) - .append(":\n"); + for (int i = 0; i != ordinals.length; ++i) { + if (!ordinals[i]) { + throw new HelenusMappingException("detected absent ordinal " + i + " in " + this); + } + } + } - for (HelenusProperty prop : getOrderedProperties()) { - str.append(prop.toString()); - str.append("\n"); - } - return str.toString(); - } + @Override + public String toString() { + + StringBuilder str = new StringBuilder(); + str.append(iface.getSimpleName()).append("(").append(name.getName()).append(") ") + .append(type.name().toLowerCase()).append(":\n"); + + for (HelenusProperty prop : getOrderedProperties()) { + str.append(prop.toString()); + str.append("\n"); + } + return str.toString(); + } } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingProperty.java b/src/main/java/net/helenus/mapping/HelenusMappingProperty.java index b7927f2..1382829 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingProperty.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingProperty.java @@ -15,13 +15,16 @@ */ package net.helenus.mapping; -import com.datastax.driver.core.Metadata; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + import javax.validation.ConstraintValidator; + +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.javatype.AbstractJavaType; import net.helenus.mapping.javatype.MappingJavaTypes; @@ -29,174 +32,171 @@ import net.helenus.mapping.type.AbstractDataType; public final class HelenusMappingProperty implements HelenusProperty { - private final HelenusEntity entity; - private final Method getter; + private final HelenusEntity entity; + private final Method getter; - private final String propertyName; - private final Optional indexName; - private final boolean caseSensitiveIndex; + private final String propertyName; + private final Optional indexName; + private final boolean caseSensitiveIndex; - private final ColumnInformation columnInfo; + private final ColumnInformation columnInfo; - private final Type genericJavaType; - private final Class javaType; - private final AbstractJavaType abstractJavaType; - private final AbstractDataType dataType; + private final Type genericJavaType; + private final Class javaType; + private final AbstractJavaType abstractJavaType; + private final AbstractDataType dataType; + private final ConstraintValidator[] validators; + private volatile Optional> readConverter = null; + private volatile Optional> writeConverter = null; - private volatile Optional> readConverter = null; - private volatile Optional> writeConverter = null; + public HelenusMappingProperty(HelenusMappingEntity entity, Method getter, Metadata metadata) { + this.entity = entity; + this.getter = getter; - private final ConstraintValidator[] validators; + this.propertyName = MappingUtil.getPropertyName(getter); + this.indexName = MappingUtil.getIndexName(getter); + this.caseSensitiveIndex = MappingUtil.caseSensitiveIndex(getter); - public HelenusMappingProperty(HelenusMappingEntity entity, Method getter, Metadata metadata) { - this.entity = entity; - this.getter = getter; + this.columnInfo = new ColumnInformation(getter); - this.propertyName = MappingUtil.getPropertyName(getter); - this.indexName = MappingUtil.getIndexName(getter); - this.caseSensitiveIndex = MappingUtil.caseSensitiveIndex(getter); + this.genericJavaType = getter.getGenericReturnType(); + this.javaType = getter.getReturnType(); + this.abstractJavaType = MappingJavaTypes.resolveJavaType(this.javaType); - this.columnInfo = new ColumnInformation(getter); + this.dataType = abstractJavaType.resolveDataType(this.getter, this.genericJavaType, + this.columnInfo.getColumnType(), metadata); - this.genericJavaType = getter.getGenericReturnType(); - this.javaType = getter.getReturnType(); - this.abstractJavaType = MappingJavaTypes.resolveJavaType(this.javaType); + this.validators = MappingUtil.getValidators(getter); + } - this.dataType = - abstractJavaType.resolveDataType( - this.getter, this.genericJavaType, this.columnInfo.getColumnType(), metadata); + @Override + public HelenusEntity getEntity() { + return entity; + } - this.validators = MappingUtil.getValidators(getter); - } + @Override + public Class getJavaType() { + return (Class) javaType; + } - @Override - public HelenusEntity getEntity() { - return entity; - } + @Override + public AbstractDataType getDataType() { + return dataType; + } - @Override - public Class getJavaType() { - return (Class) javaType; - } + @Override + public ColumnType getColumnType() { + return columnInfo.getColumnType(); + } - @Override - public AbstractDataType getDataType() { - return dataType; - } + @Override + public int getOrdinal() { + return columnInfo.getOrdinal(); + } - @Override - public ColumnType getColumnType() { - return columnInfo.getColumnType(); - } + @Override + public OrderingDirection getOrdering() { + return columnInfo.getOrdering(); + } - @Override - public int getOrdinal() { - return columnInfo.getOrdinal(); - } + @Override + public IdentityName getColumnName() { + return columnInfo.getColumnName(); + } - @Override - public OrderingDirection getOrdering() { - return columnInfo.getOrdering(); - } + @Override + public Optional getIndexName() { + return indexName; + } - @Override - public IdentityName getColumnName() { - return columnInfo.getColumnName(); - } + @Override + public boolean caseSensitiveIndex() { + return caseSensitiveIndex; + } - @Override - public Optional getIndexName() { - return indexName; - } + @Override + public String getPropertyName() { + return propertyName; + } - @Override - public boolean caseSensitiveIndex() { - return caseSensitiveIndex; - } + @Override + public Method getGetterMethod() { + return getter; + } - @Override - public String getPropertyName() { - return propertyName; - } + @Override + public Optional> getReadConverter(SessionRepository repository) { - @Override - public Method getGetterMethod() { - return getter; - } + if (readConverter == null) { + readConverter = abstractJavaType.resolveReadConverter(this.dataType, repository); + } - @Override - public Optional> getReadConverter(SessionRepository repository) { + return readConverter; + } - if (readConverter == null) { - readConverter = abstractJavaType.resolveReadConverter(this.dataType, repository); - } + @Override + public Optional> getWriteConverter(SessionRepository repository) { - return readConverter; - } + if (writeConverter == null) { + writeConverter = abstractJavaType.resolveWriteConverter(this.dataType, repository); + } - @Override - public Optional> getWriteConverter(SessionRepository repository) { + return writeConverter; + } - if (writeConverter == null) { - writeConverter = abstractJavaType.resolveWriteConverter(this.dataType, repository); - } + @Override + public ConstraintValidator[] getValidators() { + return validators; + } - return writeConverter; - } + @Override + public String toString() { - @Override - public ConstraintValidator[] getValidators() { - return validators; - } + StringBuilder str = new StringBuilder(); - @Override - public String toString() { + String columnName = this.getColumnName().getName(); + str.append(" "); + str.append(this.getDataType()); + str.append(" "); + str.append(this.getPropertyName()); + str.append("("); + if (!columnName.equals(this.getPropertyName())) { + str.append(columnName); + } + str.append(") "); - StringBuilder str = new StringBuilder(); + ColumnType type = this.getColumnType(); - String columnName = this.getColumnName().getName(); - str.append(" "); - str.append(this.getDataType()); - str.append(" "); - str.append(this.getPropertyName()); - str.append("("); - if (!columnName.equals(this.getPropertyName())) { - str.append(columnName); - } - str.append(") "); + switch (type) { + case PARTITION_KEY : + str.append("partition_key["); + str.append(this.getOrdinal()); + str.append("] "); + break; - ColumnType type = this.getColumnType(); + case CLUSTERING_COLUMN : + str.append("clustering_column["); + str.append(this.getOrdinal()); + str.append("] "); + OrderingDirection od = this.getOrdering(); + if (od != null) { + str.append(od.name().toLowerCase()).append(" "); + } + break; - switch (type) { - case PARTITION_KEY: - str.append("partition_key["); - str.append(this.getOrdinal()); - str.append("] "); - break; + case STATIC_COLUMN : + str.append("static "); + break; - case CLUSTERING_COLUMN: - str.append("clustering_column["); - str.append(this.getOrdinal()); - str.append("] "); - OrderingDirection od = this.getOrdering(); - if (od != null) { - str.append(od.name().toLowerCase()).append(" "); - } - break; + case COLUMN : + break; + } - case STATIC_COLUMN: - str.append("static "); - break; + Optional idx = this.getIndexName(); + if (idx.isPresent()) { + str.append("index(").append(idx.get().getName()).append(") "); + } - case COLUMN: - break; - } - - Optional idx = this.getIndexName(); - if (idx.isPresent()) { - str.append("index(").append(idx.get().getName()).append(") "); - } - - return str.toString(); - } + return str.toString(); + } } diff --git a/src/main/java/net/helenus/mapping/HelenusProperty.java b/src/main/java/net/helenus/mapping/HelenusProperty.java index 08b428e..fecc550 100644 --- a/src/main/java/net/helenus/mapping/HelenusProperty.java +++ b/src/main/java/net/helenus/mapping/HelenusProperty.java @@ -19,37 +19,39 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Optional; import java.util.function.Function; + import javax.validation.ConstraintValidator; + import net.helenus.core.SessionRepository; import net.helenus.mapping.type.AbstractDataType; public interface HelenusProperty { - HelenusEntity getEntity(); + HelenusEntity getEntity(); - String getPropertyName(); + String getPropertyName(); - Method getGetterMethod(); + Method getGetterMethod(); - IdentityName getColumnName(); + IdentityName getColumnName(); - Optional getIndexName(); + Optional getIndexName(); - boolean caseSensitiveIndex(); + boolean caseSensitiveIndex(); - Class getJavaType(); + Class getJavaType(); - AbstractDataType getDataType(); + AbstractDataType getDataType(); - ColumnType getColumnType(); + ColumnType getColumnType(); - int getOrdinal(); + int getOrdinal(); - OrderingDirection getOrdering(); + OrderingDirection getOrdering(); - Optional> getReadConverter(SessionRepository repository); + Optional> getReadConverter(SessionRepository repository); - Optional> getWriteConverter(SessionRepository repository); + Optional> getWriteConverter(SessionRepository repository); - ConstraintValidator[] getValidators(); + ConstraintValidator[] getValidators(); } diff --git a/src/main/java/net/helenus/mapping/IdentityName.java b/src/main/java/net/helenus/mapping/IdentityName.java index 02f0858..cf61cbe 100644 --- a/src/main/java/net/helenus/mapping/IdentityName.java +++ b/src/main/java/net/helenus/mapping/IdentityName.java @@ -19,41 +19,41 @@ import net.helenus.support.CqlUtil; public final class IdentityName { - private final String name; + private final String name; - private final boolean forceQuote; + private final boolean forceQuote; - public IdentityName(String name, boolean forceQuote) { - this.name = name.toLowerCase(); - this.forceQuote = forceQuote; - } + public IdentityName(String name, boolean forceQuote) { + this.name = name.toLowerCase(); + this.forceQuote = forceQuote; + } - public static IdentityName of(String name, boolean forceQuote) { - return new IdentityName(name, forceQuote); - } + public static IdentityName of(String name, boolean forceQuote) { + return new IdentityName(name, forceQuote); + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public boolean isForceQuote() { - return forceQuote; - } + public boolean isForceQuote() { + return forceQuote; + } - public String toCql(boolean overrideForceQuote) { - if (overrideForceQuote) { - return CqlUtil.forceQuote(name); - } else { - return name; - } - } + public String toCql(boolean overrideForceQuote) { + if (overrideForceQuote) { + return CqlUtil.forceQuote(name); + } else { + return name; + } + } - public String toCql() { - return toCql(forceQuote); - } + public String toCql() { + return toCql(forceQuote); + } - @Override - public String toString() { - return toCql(); - } + @Override + public String toString() { + return toCql(); + } } diff --git a/src/main/java/net/helenus/mapping/MappingUtil.java b/src/main/java/net/helenus/mapping/MappingUtil.java index cf84c05..8eadfac 100644 --- a/src/main/java/net/helenus/mapping/MappingUtil.java +++ b/src/main/java/net/helenus/mapping/MappingUtil.java @@ -20,8 +20,10 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Optional; + import javax.validation.Constraint; import javax.validation.ConstraintValidator; + import net.helenus.core.Getter; import net.helenus.core.Helenus; import net.helenus.core.reflect.*; @@ -31,255 +33,253 @@ import net.helenus.support.HelenusMappingException; public final class MappingUtil { - @SuppressWarnings("unchecked") - public static final ConstraintValidator[] EMPTY_VALIDATORS = - new ConstraintValidator[0]; + @SuppressWarnings("unchecked") + public static final ConstraintValidator[] EMPTY_VALIDATORS = new ConstraintValidator[0]; - private MappingUtil() {} + private MappingUtil() { + } - public static ConstraintValidator[] getValidators(Method getterMethod) { + public static ConstraintValidator[] getValidators(Method getterMethod) { - List> list = null; + List> list = null; - for (Annotation constraintAnnotation : getterMethod.getDeclaredAnnotations()) { + for (Annotation constraintAnnotation : getterMethod.getDeclaredAnnotations()) { - list = addValidators(constraintAnnotation, list); + list = addValidators(constraintAnnotation, list); - Class annotationType = constraintAnnotation.annotationType(); + Class annotationType = constraintAnnotation.annotationType(); - for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { + for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { - list = addValidators(possibleConstraint, list); - } - } + list = addValidators(possibleConstraint, list); + } + } - if (list == null) { - return EMPTY_VALIDATORS; - } else { - return list.toArray(EMPTY_VALIDATORS); - } - } + if (list == null) { + return EMPTY_VALIDATORS; + } else { + return list.toArray(EMPTY_VALIDATORS); + } + } - private static List> addValidators( - Annotation constraintAnnotation, List> list) { + private static List> addValidators(Annotation constraintAnnotation, + List> list) { - Class annotationType = constraintAnnotation.annotationType(); + Class annotationType = constraintAnnotation.annotationType(); - for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { + for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { - if (possibleConstraint instanceof Constraint) { + if (possibleConstraint instanceof Constraint) { - Constraint constraint = (Constraint) possibleConstraint; + Constraint constraint = (Constraint) possibleConstraint; - for (Class> clazz : constraint.validatedBy()) { + for (Class> clazz : constraint.validatedBy()) { - ConstraintValidator validator = - ReflectionInstantiator.instantiateClass(clazz); + ConstraintValidator validator = ReflectionInstantiator + .instantiateClass(clazz); - ((ConstraintValidator) validator).initialize(constraintAnnotation); + ((ConstraintValidator) validator).initialize(constraintAnnotation); - if (list == null) { - list = new ArrayList>(); - } + if (list == null) { + list = new ArrayList>(); + } - list.add(validator); - } - } - } + list.add(validator); + } + } + } - return list; - } + return list; + } - public static Optional getIndexName(Method getterMethod) { + public static Optional getIndexName(Method getterMethod) { - String indexName = null; - boolean forceQuote = false; + String indexName = null; + boolean forceQuote = false; - Index index = getterMethod.getDeclaredAnnotation(Index.class); + Index index = getterMethod.getDeclaredAnnotation(Index.class); - if (index != null) { - indexName = index.value(); - forceQuote = index.forceQuote(); + if (index != null) { + indexName = index.value(); + forceQuote = index.forceQuote(); - if (indexName == null || indexName.isEmpty()) { - indexName = getDefaultColumnName(getterMethod); - } - } + if (indexName == null || indexName.isEmpty()) { + indexName = getDefaultColumnName(getterMethod); + } + } - return indexName != null - ? Optional.of(new IdentityName(indexName, forceQuote)) - : Optional.empty(); - } + return indexName != null ? Optional.of(new IdentityName(indexName, forceQuote)) : Optional.empty(); + } - public static boolean caseSensitiveIndex(Method getterMethod) { - Index index = getterMethod.getDeclaredAnnotation(Index.class); + public static boolean caseSensitiveIndex(Method getterMethod) { + Index index = getterMethod.getDeclaredAnnotation(Index.class); - if (index != null) { - return index.caseSensitive(); - } + if (index != null) { + return index.caseSensitive(); + } - return false; - } + return false; + } - public static String getPropertyName(Method getter) { - return getter.getName(); - } + public static String getPropertyName(Method getter) { + return getter.getName(); + } - public static String getDefaultColumnName(Method getter) { - return Helenus.settings().getPropertyToColumnConverter().apply(getPropertyName(getter)); - } + public static String getDefaultColumnName(Method getter) { + return Helenus.settings().getPropertyToColumnConverter().apply(getPropertyName(getter)); + } - public static IdentityName getUserDefinedTypeName(Class iface, boolean required) { + public static IdentityName getUserDefinedTypeName(Class iface, boolean required) { - String userTypeName = null; - boolean forceQuote = false; + String userTypeName = null; + boolean forceQuote = false; - UDT userDefinedType = iface.getDeclaredAnnotation(UDT.class); + UDT userDefinedType = iface.getDeclaredAnnotation(UDT.class); - if (userDefinedType != null) { + if (userDefinedType != null) { - userTypeName = userDefinedType.value(); - forceQuote = userDefinedType.forceQuote(); + userTypeName = userDefinedType.value(); + forceQuote = userDefinedType.forceQuote(); - if (userTypeName == null || userTypeName.isEmpty()) { - userTypeName = getDefaultEntityName(iface); - } + if (userTypeName == null || userTypeName.isEmpty()) { + userTypeName = getDefaultEntityName(iface); + } - return new IdentityName(userTypeName, forceQuote); - } + return new IdentityName(userTypeName, forceQuote); + } - if (required) { - throw new HelenusMappingException("entity must have annotation @UserDefinedType " + iface); - } + if (required) { + throw new HelenusMappingException("entity must have annotation @UserDefinedType " + iface); + } - return null; - } + return null; + } - public static boolean isTuple(Class iface) { + public static boolean isTuple(Class iface) { - Tuple tuple = iface.getDeclaredAnnotation(Tuple.class); + Tuple tuple = iface.getDeclaredAnnotation(Tuple.class); - return tuple != null; - } + return tuple != null; + } - public static boolean isUDT(Class iface) { + public static boolean isUDT(Class iface) { - UDT udt = iface.getDeclaredAnnotation(UDT.class); + UDT udt = iface.getDeclaredAnnotation(UDT.class); - return udt != null; - } + return udt != null; + } - public static IdentityName getViewName(Class iface, boolean required) { + public static IdentityName getViewName(Class iface, boolean required) { - String viewName = null; - boolean forceQuote = false; + String viewName = null; + boolean forceQuote = false; - MaterializedView view = iface.getDeclaredAnnotation(MaterializedView.class); + MaterializedView view = iface.getDeclaredAnnotation(MaterializedView.class); - if (view != null) { - viewName = view.value(); - forceQuote = view.forceQuote(); + if (view != null) { + viewName = view.value(); + forceQuote = view.forceQuote(); - } else if (required) { - throw new HelenusMappingException("entity must have annotation @Table " + iface); - } + } else if (required) { + throw new HelenusMappingException("entity must have annotation @Table " + iface); + } - if (viewName == null || viewName.isEmpty()) { - viewName = getDefaultEntityName(iface); - } + if (viewName == null || viewName.isEmpty()) { + viewName = getDefaultEntityName(iface); + } - return new IdentityName(viewName, forceQuote); - } + return new IdentityName(viewName, forceQuote); + } - public static IdentityName getTableName(Class iface, boolean required) { + public static IdentityName getTableName(Class iface, boolean required) { - String tableName = null; - boolean forceQuote = false; + String tableName = null; + boolean forceQuote = false; - Table table = iface.getDeclaredAnnotation(Table.class); + Table table = iface.getDeclaredAnnotation(Table.class); - if (table != null) { - tableName = table.value(); - forceQuote = table.forceQuote(); + if (table != null) { + tableName = table.value(); + forceQuote = table.forceQuote(); - } else if (required) { - throw new HelenusMappingException("entity must have annotation @Table " + iface); - } + } else if (required) { + throw new HelenusMappingException("entity must have annotation @Table " + iface); + } - if (tableName == null || tableName.isEmpty()) { - tableName = getDefaultEntityName(iface); - } + if (tableName == null || tableName.isEmpty()) { + tableName = getDefaultEntityName(iface); + } - return new IdentityName(tableName, forceQuote); - } + return new IdentityName(tableName, forceQuote); + } - public static String getDefaultEntityName(Class iface) { - return Helenus.settings().getPropertyToColumnConverter().apply(iface.getSimpleName()); - } + public static String getDefaultEntityName(Class iface) { + return Helenus.settings().getPropertyToColumnConverter().apply(iface.getSimpleName()); + } - public static Class getMappingInterface(Object pojo) { + public static Class getMappingInterface(Object pojo) { - Class iface = null; + Class iface = null; - if (pojo instanceof Class) { - iface = (Class) pojo; + if (pojo instanceof Class) { + iface = (Class) pojo; - if (!iface.isInterface()) { - throw new HelenusMappingException("expected interface " + iface); - } + if (!iface.isInterface()) { + throw new HelenusMappingException("expected interface " + iface); + } - } else { - Class[] ifaces = pojo.getClass().getInterfaces(); + } else { + Class[] ifaces = pojo.getClass().getInterfaces(); - int len = ifaces.length; - for (int i = 0; i != len; ++i) { + int len = ifaces.length; + for (int i = 0; i != len; ++i) { - iface = ifaces[0]; + iface = ifaces[0]; - if (MapExportable.class.isAssignableFrom(iface)) { - continue; - } + if (MapExportable.class.isAssignableFrom(iface)) { + continue; + } - if (iface.getDeclaredAnnotation(Table.class) != null - || iface.getDeclaredAnnotation(MaterializedView.class) != null - || iface.getDeclaredAnnotation(UDT.class) != null - || iface.getDeclaredAnnotation(Tuple.class) != null) { + if (iface.getDeclaredAnnotation(Table.class) != null + || iface.getDeclaredAnnotation(MaterializedView.class) != null + || iface.getDeclaredAnnotation(UDT.class) != null + || iface.getDeclaredAnnotation(Tuple.class) != null) { - break; - } - } - } + break; + } + } + } - if (iface == null) { - throw new HelenusMappingException("dsl interface not found for " + pojo); - } + if (iface == null) { + throw new HelenusMappingException("dsl interface not found for " + pojo); + } - return iface; - } + return iface; + } - public static HelenusPropertyNode resolveMappingProperty(Getter getter) { + public static HelenusPropertyNode resolveMappingProperty(Getter getter) { - try { - Object childDsl = getter.get(); + try { + Object childDsl = getter.get(); - if (childDsl instanceof DslExportable) { - DslExportable e = (DslExportable) childDsl; - return e.getParentDslHelenusPropertyNode(); - } else if (childDsl instanceof MapDsl) { - MapDsl mapDsl = (MapDsl) childDsl; - return mapDsl.getParent(); - } else if (childDsl instanceof ListDsl) { - ListDsl listDsl = (ListDsl) childDsl; - return listDsl.getParent(); - } else if (childDsl instanceof SetDsl) { - SetDsl setDsl = (SetDsl) childDsl; - return setDsl.getParent(); - } + if (childDsl instanceof DslExportable) { + DslExportable e = (DslExportable) childDsl; + return e.getParentDslHelenusPropertyNode(); + } else if (childDsl instanceof MapDsl) { + MapDsl mapDsl = (MapDsl) childDsl; + return mapDsl.getParent(); + } else if (childDsl instanceof ListDsl) { + ListDsl listDsl = (ListDsl) childDsl; + return listDsl.getParent(); + } else if (childDsl instanceof SetDsl) { + SetDsl setDsl = (SetDsl) childDsl; + return setDsl.getParent(); + } - throw new HelenusMappingException("getter must reference to the dsl object " + getter); + throw new HelenusMappingException("getter must reference to the dsl object " + getter); - } catch (DslPropertyException e) { - return e.getPropertyNode(); - } - } + } catch (DslPropertyException e) { + return e.getPropertyNode(); + } + } } diff --git a/src/main/java/net/helenus/mapping/OrderingDirection.java b/src/main/java/net/helenus/mapping/OrderingDirection.java index 47680d6..2f41023 100644 --- a/src/main/java/net/helenus/mapping/OrderingDirection.java +++ b/src/main/java/net/helenus/mapping/OrderingDirection.java @@ -18,28 +18,28 @@ package net.helenus.mapping; import net.helenus.support.HelenusMappingException; public enum OrderingDirection { - ASC("ASC"), + ASC("ASC"), - DESC("DESC"); + DESC("DESC"); - private final String cql; + private final String cql; - private OrderingDirection(String cql) { - this.cql = cql; - } + private OrderingDirection(String cql) { + this.cql = cql; + } - public String cql() { - return cql; - } + public static OrderingDirection parseString(String name) { - public static OrderingDirection parseString(String name) { + if (ASC.cql.equalsIgnoreCase(name)) { + return ASC; + } else if (DESC.cql.equalsIgnoreCase(name)) { + return DESC; + } - if (ASC.cql.equalsIgnoreCase(name)) { - return ASC; - } else if (DESC.cql.equalsIgnoreCase(name)) { - return DESC; - } + throw new HelenusMappingException("invalid ordering direction name " + name); + } - throw new HelenusMappingException("invalid ordering direction name " + name); - } + public String cql() { + return cql; + } } diff --git a/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java b/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java index ef925ea..825e0dc 100644 --- a/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java +++ b/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java @@ -18,17 +18,16 @@ package net.helenus.mapping; import java.util.Comparator; public enum TypeAndOrdinalColumnComparator implements Comparator { - INSTANCE; + INSTANCE; - public int compare(HelenusProperty thisVal, HelenusProperty anotherVal) { + public int compare(HelenusProperty thisVal, HelenusProperty anotherVal) { - int c = - Integer.compare(thisVal.getColumnType().ordinal(), anotherVal.getColumnType().ordinal()); + int c = Integer.compare(thisVal.getColumnType().ordinal(), anotherVal.getColumnType().ordinal()); - if (c == 0) { - c = Integer.compare(thisVal.getOrdinal(), anotherVal.getOrdinal()); - } + if (c == 0) { + c = Integer.compare(thisVal.getOrdinal(), anotherVal.getOrdinal()); + } - return c; - } + return c; + } } diff --git a/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java b/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java index 4a6228b..c1f72de 100644 --- a/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java +++ b/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java @@ -19,78 +19,93 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; + import net.helenus.mapping.OrderingDirection; /** * ClusteringColumn is the family column in legacy Cassandra API * - *

The purpose of this column is have additional dimension in the table. Both @PartitionKey - * and @ClusteringColumn together are parts of the primary key of the table. The primary difference - * between them is that the first one is using for routing purposes in order to locate a data node - * in the cluster, otherwise the second one is using inside the node to locate peace of data in + *

+ * The purpose of this column is have additional dimension in the table. + * Both @PartitionKey and @ClusteringColumn together are parts of the primary + * key of the table. The primary difference between them is that the first one + * is using for routing purposes in order to locate a data node in the cluster, + * otherwise the second one is using inside the node to locate peace of data in * concrete machine. * - *

ClusteringColumn can be represented as a Key in SortedMap that fully stored in a single node. - * All developers must be careful for selecting fields for clustering columns, because all data - * inside this SortedMap must fit in to one node. + *

+ * ClusteringColumn can be represented as a Key in SortedMap that fully stored + * in a single node. All developers must be careful for selecting fields for + * clustering columns, because all data inside this SortedMap must fit in to one + * node. * - *

ClusteringColumn can have more than one part and the order of parts is important. This order - * defines the way how Cassandra joins the parts and influence of data retrieval operations. Each - * part can have ordering property that defines default ascending or descending order of data. In - * case of two and more parts in select queries developer needs to have consisdent order of all - * parts as they defined in table. + *

+ * ClusteringColumn can have more than one part and the order of parts is + * important. This order defines the way how Cassandra joins the parts and + * influence of data retrieval operations. Each part can have ordering property + * that defines default ascending or descending order of data. In case of two + * and more parts in select queries developer needs to have consisdent order of + * all parts as they defined in table. * - *

For example, first part is ASC ordering, second is also ASC, so Cassandra will sort entries - * like this: a-a a-b b-a b-b In this case we are able run queries: ORDER BY first ASC, second ASC - * ORDER BY first DESC, second DESC WHERE first=? ORDER BY second ASC WHERE first=? ORDER BY second - * DESC WHERE first=? AND second=? + *

+ * For example, first part is ASC ordering, second is also ASC, so Cassandra + * will sort entries like this: a-a a-b b-a b-b In this case we are able run + * queries: ORDER BY first ASC, second ASC ORDER BY first DESC, second DESC + * WHERE first=? ORDER BY second ASC WHERE first=? ORDER BY second DESC WHERE + * first=? AND second=? * - *

But, we can not run queries: ORDER BY first DESC, second ASC ORDER BY first ASC, second DESC - * WHERE second=? ORDER BY first (ASC,DESC) + *

+ * But, we can not run queries: ORDER BY first DESC, second ASC ORDER BY first + * ASC, second DESC WHERE second=? ORDER BY first (ASC,DESC) */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface ClusteringColumn { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * ClusteringColumn parts must be ordered in the @Table. It is the requirement of Cassandra. - * Cassandra joins all parts to the final clustering key that is stored in column family name. - * Additionally all parts can have some ordering (ASC, DESC) that with sequence of parts - * determines key comparison function, so Cassandra storing column family names always in sorted - * order. - * - *

Be default ordinal has 0 value, that's because in most cases @Table have single column for - * ClusteringColumn If you have 2 and more parts of the ClusteringColumn, then you need to use - * ordinal() to define the sequence of the parts - * - * @return number that used to sort clustering columns - */ - int ordinal() default 0; + /** + * ClusteringColumn parts must be ordered in the @Table. It is the requirement + * of Cassandra. Cassandra joins all parts to the final clustering key that is + * stored in column family name. Additionally all parts can have some ordering + * (ASC, DESC) that with sequence of parts determines key comparison function, + * so Cassandra storing column family names always in sorted order. + * + *

+ * Be default ordinal has 0 value, that's because in most cases @Table have + * single column for ClusteringColumn If you have 2 and more parts of the + * ClusteringColumn, then you need to use ordinal() to define the sequence of + * the parts + * + * @return number that used to sort clustering columns + */ + int ordinal() default 0; - /** - * Default order of values in the ClusteringColumn This ordering is using for comparison of the - * clustering column values when Cassandra stores it in the sorted order. - * - *

Default value is the ascending order - * - * @return ascending order or descending order of clustering column values - */ - OrderingDirection ordering() default OrderingDirection.ASC; + /** + * Default order of values in the ClusteringColumn This ordering is using for + * comparison of the clustering column values when Cassandra stores it in the + * sorted order. + * + *

+ * Default value is the ascending order + * + * @return ascending order or descending order of clustering column values + */ + OrderingDirection ordering() default OrderingDirection.ASC; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Column.java b/src/main/java/net/helenus/mapping/annotation/Column.java index ab4b2d4..466f26c 100644 --- a/src/main/java/net/helenus/mapping/annotation/Column.java +++ b/src/main/java/net/helenus/mapping/annotation/Column.java @@ -18,45 +18,51 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; /** - * Column annotation is used to define additional properties of the column in entity mapping - * interfaces: @Table, @UDT, @Tuple + * Column annotation is used to define additional properties of the column in + * entity mapping interfaces: @Table, @UDT, @Tuple * - *

Column annotation can be used to override default name of the column or to setup order of the - * columns in the mapping + *

+ * Column annotation can be used to override default name of the column or to + * setup order of the columns in the mapping * - *

Usually for @Table and @UDT types it is not important to define order of the columns, but - * in @Tuple mapping it is required, because tuple itself represents the sequence of the types with - * particular order in the table's column + *

+ * Usually for @Table and @UDT types it is not important to define order of the + * columns, but in @Tuple mapping it is required, because tuple itself + * represents the sequence of the types with particular order in the table's + * column */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface Column { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * Ordinal will be used for ascending sorting of columns - * - *

Default value is 0, because not all mapping entities require all fields to have unique - * ordinals, only @Tuple mapping entity requires all of them to be unique. - * - * @return number that used to sort columns, usually for @Tuple only - */ - int ordinal() default 0; + /** + * Ordinal will be used for ascending sorting of columns + * + *

+ * Default value is 0, because not all mapping entities require all fields to + * have unique ordinals, only @Tuple mapping entity requires all of them to be + * unique. + * + * @return number that used to sort columns, usually for @Tuple only + */ + int ordinal() default 0; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Constraints.java b/src/main/java/net/helenus/mapping/annotation/Constraints.java index 54110ba..5ed755e 100644 --- a/src/main/java/net/helenus/mapping/annotation/Constraints.java +++ b/src/main/java/net/helenus/mapping/annotation/Constraints.java @@ -16,200 +16,240 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; + import javax.validation.Constraint; + import net.helenus.mapping.validator.*; /** - * Constraint annotations are using for data integrity mostly for @java.lang.String types. The place - * of the annotation is the particular method in model interface. + * Constraint annotations are using for data integrity mostly + * for @java.lang.String types. The place of the annotation is the particular + * method in model interface. * - *

All of them does not have effect on selects and data retrieval operations. + *

+ * All of them does not have effect on selects and data retrieval operations. * - *

Support types: - @NotNull supports any @java.lang.Object type - All annotations - * support @java.lang.String type + *

+ * Support types: - @NotNull supports any @java.lang.Object type - All + * annotations support @java.lang.String type */ public final class Constraints { - private Constraints() {} + private Constraints() { + } - /** - * NotNull annotation is using to check that value is not null before storing it - * - *

Applicable to use in any @java.lang.Object - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = NotNullValidator.class) - public @interface NotNull {} + /** + * NotNull annotation is using to check that value is not null before storing it + * + *

+ * Applicable to use in any @java.lang.Object + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = NotNullValidator.class) + public @interface NotNull { + } - /** - * NotEmpty annotation is using to check that value has text before storing it - * - *

Also checks for the null and it is more strict annotation then @NotNull - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and any array - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = NotEmptyValidator.class) - public @interface NotEmpty {} + /** + * NotEmpty annotation is using to check that value has text before storing it + * + *

+ * Also checks for the null and it is more strict annotation then @NotNull + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and any array + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = NotEmptyValidator.class) + public @interface NotEmpty { + } - /** - * Email annotation is using to check that value has a valid email before storing it - * - *

Can be used only for @CharSequence - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = EmailValidator.class) - public @interface Email {} + /** + * Email annotation is using to check that value has a valid email before + * storing it + * + *

+ * Can be used only for @CharSequence + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = EmailValidator.class) + public @interface Email { + } - /** - * Number annotation is using to check that all letters in value are digits before storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = NumberValidator.class) - public @interface Number {} + /** + * Number annotation is using to check that all letters in value are digits + * before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = NumberValidator.class) + public @interface Number { + } - /** - * Alphabet annotation is using to check that all letters in value are in specific alphabet before - * storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = AlphabetValidator.class) - public @interface Alphabet { + /** + * Alphabet annotation is using to check that all letters in value are in + * specific alphabet before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = AlphabetValidator.class) + public @interface Alphabet { - /** - * Defines alphabet that will be used to check value - * - * @return alphabet characters in the string - */ - String value(); - } + /** + * Defines alphabet that will be used to check value + * + * @return alphabet characters in the string + */ + String value(); + } - /** - * Length annotation is using to ensure that value has exact length before storing it - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and any array - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = LengthValidator.class) - public @interface Length { + /** + * Length annotation is using to ensure that value has exact length before + * storing it + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and any array + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = LengthValidator.class) + public @interface Length { - int value(); - } + int value(); + } - /** - * MaxLength annotation is using to ensure that value has length less or equal to some threshold - * before storing it - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = MaxLengthValidator.class) - public @interface MaxLength { + /** + * MaxLength annotation is using to ensure that value has length less or equal + * to some threshold before storing it + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = MaxLengthValidator.class) + public @interface MaxLength { - int value(); - } + int value(); + } - /** - * MinLength annotation is using to ensure that value has length greater or equal to some - * threshold before storing it - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = MinLengthValidator.class) - public @interface MinLength { + /** + * MinLength annotation is using to ensure that value has length greater or + * equal to some threshold before storing it + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = MinLengthValidator.class) + public @interface MinLength { - int value(); - } + int value(); + } - /** - * LowerCase annotation is using to ensure that value is in lower case before storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = LowerCaseValidator.class) - public @interface LowerCase {} + /** + * LowerCase annotation is using to ensure that value is in lower case before + * storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = LowerCaseValidator.class) + public @interface LowerCase { + } - /** - * UpperCase annotation is using to ensure that value is in upper case before storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = UpperCaseValidator.class) - public @interface UpperCase {} + /** + * UpperCase annotation is using to ensure that value is in upper case before + * storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = UpperCaseValidator.class) + public @interface UpperCase { + } - /** - * Pattern annotation is LowerCase annotation is using to ensure that value is upper case before - * storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = PatternValidator.class) - public @interface Pattern { + /** + * Pattern annotation is LowerCase annotation is using to ensure that value is + * upper case before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = PatternValidator.class) + public @interface Pattern { - /** - * User defined regex expression to check match of the value - * - * @return Java regex pattern - */ - String value(); + /** + * User defined regex expression to check match of the value + * + * @return Java regex pattern + */ + String value(); - /** - * Regex flags composition - * - * @return Java regex flags - */ - int flags(); - } + /** + * Regex flags composition + * + * @return Java regex flags + */ + int flags(); + } } diff --git a/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java b/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java index 6271e8e..33d8bf4 100644 --- a/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java +++ b/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java @@ -3,48 +3,52 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; /** - * CoveringIndex annotation is using under the specific column or method in entity interface - * with @Table annotation. + * CoveringIndex annotation is using under the specific column or method in + * entity interface with @Table annotation. * - *

A corresponding materialized view will be created based on the underline @Table for the - * specific column. + *

+ * A corresponding materialized view will be created based on the + * underline @Table for the specific column. * - *

This is useful when you need to perform IN or SORT/ORDER-BY queries and to do so you'll need - * different materialized table on disk in Cassandra. + *

+ * This is useful when you need to perform IN or SORT/ORDER-BY queries and to do + * so you'll need different materialized table on disk in Cassandra. * - *

For each @Table annotated interface Helenus will create/update/verify Cassandra Materialized - * Views and some indexes if needed on startup. + *

+ * For each @Table annotated interface Helenus will create/update/verify + * Cassandra Materialized Views and some indexes if needed on startup. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface CoveringIndex { - /** - * Defined the name of the index. By default the entity name with column name as suffix. - * - * @return name of the covering index - */ - String name() default ""; + /** + * Defined the name of the index. By default the entity name with column name as + * suffix. + * + * @return name of the covering index + */ + String name() default ""; - /** - * Set of fields in this entity to replicate in the index. - * - * @return array of the string names of the fields. - */ - String[] covering() default ""; + /** + * Set of fields in this entity to replicate in the index. + * + * @return array of the string names of the fields. + */ + String[] covering() default ""; - /** - * Set of fields to use as the partition keys for this projection. - * - * @return array of the string names of the fields. - */ - String[] partitionKeys() default ""; + /** + * Set of fields to use as the partition keys for this projection. + * + * @return array of the string names of the fields. + */ + String[] partitionKeys() default ""; - /** - * Set of fields to use as the clustering columns for this projection. - * - * @return array of the string names of the fields. - */ - String[] clusteringColumns() default ""; + /** + * Set of fields to use as the clustering columns for this projection. + * + * @return array of the string names of the fields. + */ + String[] clusteringColumns() default ""; } diff --git a/src/main/java/net/helenus/mapping/annotation/Index.java b/src/main/java/net/helenus/mapping/annotation/Index.java index b6599df..5222824 100644 --- a/src/main/java/net/helenus/mapping/annotation/Index.java +++ b/src/main/java/net/helenus/mapping/annotation/Index.java @@ -18,45 +18,51 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; /** - * Index annotation is using under the specific column or method in entity interface with @Table - * annotation. + * Index annotation is using under the specific column or method in entity + * interface with @Table annotation. * - *

The corresponding secondary index will be created in the underline @Table for the specific - * column. + *

+ * The corresponding secondary index will be created in the underline @Table for + * the specific column. * - *

Currently Cassandra supports only single column index, so this index works only for single - * column. + *

+ * Currently Cassandra supports only single column index, so this index works + * only for single column. * - *

Make sure that you are using low cardinality columns for this index, that is the requirement - * of the Cassandra. Low cardinality fields examples: gender, country, age, status and etc High - * cardinality fields examples: id, email, timestamp, UUID and etc + *

+ * Make sure that you are using low cardinality columns for this index, that is + * the requirement of the Cassandra. Low cardinality fields examples: gender, + * country, age, status and etc High cardinality fields examples: id, email, + * timestamp, UUID and etc */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface Index { - /** - * Defined the name of the index. By default will be used the column name. - * - * @return name of the index - */ - String value() default ""; + /** + * Defined the name of the index. By default will be used the column name. + * + * @return name of the index + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; - /** - * Create a case-insensitive index using Cassandra 3.x+ support for SASI indexing. - * - * @return true if the index should ignore case when comparing - */ - boolean caseSensitive() default true; + /** + * Create a case-insensitive index using Cassandra 3.x+ support for SASI + * indexing. + * + * @return true if the index should ignore case when comparing + */ + boolean caseSensitive() default true; } diff --git a/src/main/java/net/helenus/mapping/annotation/InheritedTable.java b/src/main/java/net/helenus/mapping/annotation/InheritedTable.java index af1f1dd..a7649bd 100644 --- a/src/main/java/net/helenus/mapping/annotation/InheritedTable.java +++ b/src/main/java/net/helenus/mapping/annotation/InheritedTable.java @@ -20,11 +20,13 @@ import java.lang.annotation.*; /** * Inherited Entity annotation * - *

Inherited Table annotation is used to indicate that the methods should also be mapped + *

+ * Inherited Table annotation is used to indicate that the methods should also + * be mapped */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface InheritedTable { - String value() default ""; + String value() default ""; } diff --git a/src/main/java/net/helenus/mapping/annotation/MaterializedView.java b/src/main/java/net/helenus/mapping/annotation/MaterializedView.java index 112d8ce..6e8468d 100644 --- a/src/main/java/net/helenus/mapping/annotation/MaterializedView.java +++ b/src/main/java/net/helenus/mapping/annotation/MaterializedView.java @@ -20,33 +20,38 @@ import java.lang.annotation.*; /** * Materialized alternate view of another Entity annotation * - *

MaterializedView annotation is used to define different mapping to some other Table interface + *

+ * MaterializedView annotation is used to define different mapping to some other + * Table interface * - *

This is useful when you need to perform IN or SORT/ORDER-BY queries and to do so you'll need - * different materialized table on disk in Cassandra. + *

+ * This is useful when you need to perform IN or SORT/ORDER-BY queries and to do + * so you'll need different materialized table on disk in Cassandra. * - *

For each @Table annotated interface Helenus will create/update/verify Cassandra Materialized - * Views and some indexes if needed on startup. + *

+ * For each @Table annotated interface Helenus will create/update/verify + * Cassandra Materialized Views and some indexes if needed on startup. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface MaterializedView { - /** - * Default value is the SimpleName of the interface normalized to underscore - * - * @return name of the type - */ - String value() default ""; + /** + * Default value is the SimpleName of the interface normalized to underscore + * + * @return name of the type + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/PartitionKey.java b/src/main/java/net/helenus/mapping/annotation/PartitionKey.java index 946d9e4..bca9204 100644 --- a/src/main/java/net/helenus/mapping/annotation/PartitionKey.java +++ b/src/main/java/net/helenus/mapping/annotation/PartitionKey.java @@ -21,48 +21,55 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * PartitionKey annotation is using to define that particular column is the part of partition key in - * the table. + * PartitionKey annotation is using to define that particular column is the part + * of partition key in the table. * - *

Partition Key is the routing key. Cassandra is using it to find the primary data node in the - * cluster that holds data. Cassandra combines all parts of the partition key to byte array and then - * calculates hash function by using good distribution algorithm (by default MurMur3). After that it - * uses hash number as a token in the ring to find a virtual and then a physical data server. + *

+ * Partition Key is the routing key. Cassandra is using it to find the primary + * data node in the cluster that holds data. Cassandra combines all parts of the + * partition key to byte array and then calculates hash function by using good + * distribution algorithm (by default MurMur3). After that it uses hash number + * as a token in the ring to find a virtual and then a physical data server. * - *

For @Table mapping entity it is required to have as minimum one PartitionKey column. For @UDT - * and @Tuple mapping entities @PartitionKey annotation is not using. + *

+ * For @Table mapping entity it is required to have as minimum one PartitionKey + * column. For @UDT and @Tuple mapping entities @PartitionKey annotation is not + * using. */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface PartitionKey { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * PartitionKey parts must be ordered in the @Table. It is the requirement of Cassandra. That is - * how the partition key calculation works, column parts will be joined based on some order and - * final hash/token will be calculated. - * - *

Be default ordinal has 0 value, that's because in most cases @Table have single column - * for @PartitionKey If you have 2 and more parts of the PartitionKey, then you need to use - * ordinal() to define the sequence of the parts - * - * @return number that used to sort columns in PartitionKey - */ - int ordinal() default 0; + /** + * PartitionKey parts must be ordered in the @Table. It is the requirement of + * Cassandra. That is how the partition key calculation works, column parts will + * be joined based on some order and final hash/token will be calculated. + * + *

+ * Be default ordinal has 0 value, that's because in most cases @Table have + * single column for @PartitionKey If you have 2 and more parts of the + * PartitionKey, then you need to use ordinal() to define the sequence of the + * parts + * + * @return number that used to sort columns in PartitionKey + */ + int ordinal() default 0; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/StaticColumn.java b/src/main/java/net/helenus/mapping/annotation/StaticColumn.java index c538560..dde3a2d 100644 --- a/src/main/java/net/helenus/mapping/annotation/StaticColumn.java +++ b/src/main/java/net/helenus/mapping/annotation/StaticColumn.java @@ -23,38 +23,41 @@ import java.lang.annotation.Target; /** * StaticColumn annotation is using to define a static column in Cassandra Table * - *

It does not have effect in @UDT and @Tuple types and in @Table-s that does not - * have @ClusteringColumn-s + *

+ * It does not have effect in @UDT and @Tuple types and in @Table-s that does + * not have @ClusteringColumn-s * - *

In case of using @ClusteringColumn we can repeat some information that is unique for a row. - * For this purpose we can define @StaticColumn annotation, that will create static column in the - * table + *

+ * In case of using @ClusteringColumn we can repeat some information that is + * unique for a row. For this purpose we can define @StaticColumn annotation, + * that will create static column in the table */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface StaticColumn { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * Ordinal will be used for ascending sorting of static columns - * - * @return number that used to sort columns in PartitionKey - */ - int ordinal() default 0; + /** + * Ordinal will be used for ascending sorting of static columns + * + * @return number that used to sort columns in PartitionKey + */ + int ordinal() default 0; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Table.java b/src/main/java/net/helenus/mapping/annotation/Table.java index 0ddd4af..352f6d8 100644 --- a/src/main/java/net/helenus/mapping/annotation/Table.java +++ b/src/main/java/net/helenus/mapping/annotation/Table.java @@ -20,32 +20,36 @@ import java.lang.annotation.*; /** * Entity annotation * - *

Table annotation is used to define Table mapping to some interface + *

+ * Table annotation is used to define Table mapping to some interface * - *

There are three types of Entity mapping annotations: @Table, @UDT, @Tuple + *

+ * There are three types of Entity mapping annotations: @Table, @UDT, @Tuple * - *

For each @Table annotated interface Helenus will create/update/verify Cassandra Table and some - * indexes if needed on startup. + *

+ * For each @Table annotated interface Helenus will create/update/verify + * Cassandra Table and some indexes if needed on startup. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Table { - /** - * Default value is the SimpleName of the interface normalized to underscore - * - * @return name of the UDT type - */ - String value() default ""; + /** + * Default value is the SimpleName of the interface normalized to underscore + * + * @return name of the UDT type + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Transient.java b/src/main/java/net/helenus/mapping/annotation/Transient.java index b988122..d4c67fd 100644 --- a/src/main/java/net/helenus/mapping/annotation/Transient.java +++ b/src/main/java/net/helenus/mapping/annotation/Transient.java @@ -17,8 +17,12 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; -/** Transient annotation is used to mark properties that are need not be mapped to the database. */ +/** + * Transient annotation is used to mark properties that are need not be mapped + * to the database. + */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Transient {} +public @interface Transient { +} diff --git a/src/main/java/net/helenus/mapping/annotation/Tuple.java b/src/main/java/net/helenus/mapping/annotation/Tuple.java index e2da9e1..5f1ca4a 100644 --- a/src/main/java/net/helenus/mapping/annotation/Tuple.java +++ b/src/main/java/net/helenus/mapping/annotation/Tuple.java @@ -20,15 +20,19 @@ import java.lang.annotation.*; /** * Entity annotation * - *

Tuple annotation is used to define Tuple type mapping to some interface + *

+ * Tuple annotation is used to define Tuple type mapping to some interface * - *

There are three types of Entity mapping annotations: @Table, @UDT, @Tuple + *

+ * There are three types of Entity mapping annotations: @Table, @UDT, @Tuple * - *

Tuple is fully embedded type, it is the sequence of the underline types and the order of the - * sub-types is important, therefore all @Column-s must have ordinal() and only @Column annotation - * supported for underline types + *

+ * Tuple is fully embedded type, it is the sequence of the underline types and + * the order of the sub-types is important, therefore all @Column-s must have + * ordinal() and only @Column annotation supported for underline types */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) -public @interface Tuple {} +public @interface Tuple { +} diff --git a/src/main/java/net/helenus/mapping/annotation/Types.java b/src/main/java/net/helenus/mapping/annotation/Types.java index eedb398..682396d 100644 --- a/src/main/java/net/helenus/mapping/annotation/Types.java +++ b/src/main/java/net/helenus/mapping/annotation/Types.java @@ -15,412 +15,511 @@ */ package net.helenus.mapping.annotation; -import com.datastax.driver.core.DataType; import java.lang.annotation.*; +import com.datastax.driver.core.DataType; + /** - * Types annotations are using for clarification of Cassandra data type for particular Java type. + * Types annotations are using for clarification of Cassandra data type for + * particular Java type. * - *

Sometimes it is possible to have for single Java type multiple Cassandra data types: - @String - * can be @DataType.Name.ASCII or @DataType.Name.TEXT or @DataType.Name.VARCHAR - @Long can - * be @DataType.Name.BIGINT or @DataType.Name.COUNTER + *

+ * Sometimes it is possible to have for single Java type multiple Cassandra data + * types: - @String can be @DataType.Name.ASCII or @DataType.Name.TEXT + * or @DataType.Name.VARCHAR - @Long can be @DataType.Name.BIGINT + * or @DataType.Name.COUNTER * - *

All those type annotations simplify mapping between Java types and Cassandra data types. They - * are not required, for each Java type there is a default Cassandra data type in Helenus, but in - * some cases you would like to control mapping to make sure that the right Cassandra data type is - * using. + *

+ * All those type annotations simplify mapping between Java types and Cassandra + * data types. They are not required, for each Java type there is a default + * Cassandra data type in Helenus, but in some cases you would like to control + * mapping to make sure that the right Cassandra data type is using. * - *

For complex types like collections, UDF and Tuple types all those annotations are using to - * clarify the sub-type(s) or class/UDF names. + *

+ * For complex types like collections, UDF and Tuple types all those annotations + * are using to clarify the sub-type(s) or class/UDF names. * - *

Has significant effect on schema operations. + *

+ * Has significant effect on schema operations. */ public final class Types { - private Types() {} + private Types() { + } - /** Says to use @DataType.Name.ASCII data type in schema Java type is @String */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Ascii {} + /** Says to use @DataType.Name.ASCII data type in schema Java type is @String */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Ascii { + } - /** Says to use @DataType.Name.BIGINT data type in schema Java type is @Long */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Bigint {} + /** Says to use @DataType.Name.BIGINT data type in schema Java type is @Long */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Bigint { + } - /** - * Says to use @DataType.Name.BLOB data type in schema Java type is @ByteBuffer or @byte[] Using - * by default - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Blob {} + /** + * Says to use @DataType.Name.BLOB data type in schema Java type is @ByteBuffer + * or @byte[] Using by default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Blob { + } - /** - * Says to use @DataType.Name.LIST data type in schema with specific sub-type Java type is @List - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: prepend, prependAll, setIdx, append, appendAll, - * discard and discardAll in @UpdateOperation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface List { + /** + * Says to use @DataType.Name.LIST data type in schema with specific sub-type + * Java type is @List + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: prepend, prependAll, setIdx, + * append, appendAll, discard and discardAll in @UpdateOperation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface List { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT sub-type in the list, consider @UDTList annotation - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT sub-type in the list, consider @UDTList annotation + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific sub-types Java type is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Map { + /** + * Says to use @DataType.Name.MAP data type in schema with specific sub-types + * Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Map { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT key sub-type in the map, consider @UDTKeyMap or @UDTMap - * annotations - * - * @return data type name of the key - */ - DataType.Name key(); + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT key sub-type in the map, consider @UDTKeyMap + * or @UDTMap annotations + * + * @return data type name of the key + */ + DataType.Name key(); - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT value sub-type in the map, consider @UDTValueMap or @UDTMap - * annotations - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT value sub-type in the map, consider @UDTValueMap + * or @UDTMap annotations + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.COUNTER type in schema Java type is @Long - * - *

For this type there are special operations: increment and decrement in @UpdateOperation. You - * do not need to initialize counter value, it will be done automatically by Cassandra. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Counter {} + /** + * Says to use @DataType.Name.COUNTER type in schema Java type is @Long + * + *

+ * For this type there are special operations: increment and decrement + * in @UpdateOperation. You do not need to initialize counter value, it will be + * done automatically by Cassandra. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Counter { + } - /** - * Says to use @DataType.Name.SET data type in schema with specific sub-type Java type is @Set - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: add, addAll, remove and removeAll - * in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Set { + /** + * Says to use @DataType.Name.SET data type in schema with specific sub-type + * Java type is @Set + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: add, addAll, remove and removeAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Set { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT sub-type in the set, consider @UDTSet annotation - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT sub-type in the set, consider @UDTSet annotation + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.CUSTOM type in schema Java type is @ByteBuffer or @byte[] - * - *

Uses for custom user types that has special implementation. Helenus does not deal with this - * class directly for now, uses only in serialized form. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Custom { + /** + * Says to use @DataType.Name.CUSTOM type in schema Java type is @ByteBuffer + * or @byte[] + * + *

+ * Uses for custom user types that has special implementation. Helenus does not + * deal with this class directly for now, uses only in serialized form. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Custom { - /** - * Class name of the custom user type that is implementation of the type - * - * @return class name of the custom type implementation - */ - String className(); - } + /** + * Class name of the custom user type that is implementation of the type + * + * @return class name of the custom type implementation + */ + String className(); + } - /** Says to use @DataType.Name.TEXT type in schema Java type is @String Using by default */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Text {} + /** + * Says to use @DataType.Name.TEXT type in schema Java type is @String Using by + * default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Text { + } - /** Says to use @DataType.Name.TIMESTAMP type in schema Java type is @Date Using by default */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Timestamp {} + /** + * Says to use @DataType.Name.TIMESTAMP type in schema Java type is @Date Using + * by default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Timestamp { + } - /** Says to use @DataType.Name.TIMEUUID type in schema Java type is @UUID or @Date */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Timeuuid {} + /** + * Says to use @DataType.Name.TIMEUUID type in schema Java type is @UUID + * or @Date + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Timeuuid { + } - /** - * Says to use @DataType.Name.TUPLE type in schema Java type is @TupleValue or model interface - * with @Tuple annotation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - public @interface Tuple { + /** + * Says to use @DataType.Name.TUPLE type in schema Java type is @TupleValue or + * model interface with @Tuple annotation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + public @interface Tuple { - /** - * If Java type is the @TupleValue then this field is required. Any Cassandra Tuple is the - * sequence of Cassandra types. For now Helenus supports only simple data types in tuples - * for @TupleValue Java type - * - *

In case if Java type is the model interface with @Tuple annotation then all methods in - * this interface can have Types annotations that can be complex types as well. - * - * @return data type name sequence - */ - DataType.Name[] value() default {}; - } + /** + * If Java type is the @TupleValue then this field is required. Any Cassandra + * Tuple is the sequence of Cassandra types. For now Helenus supports only + * simple data types in tuples for @TupleValue Java type + * + *

+ * In case if Java type is the model interface with @Tuple annotation then all + * methods in this interface can have Types annotations that can be complex + * types as well. + * + * @return data type name sequence + */ + DataType.Name[] value() default {}; + } - /** - * Says to use @DataType.Name.UDT type in schema Java type is @UDTValue or model interface - * with @UDT annotation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDT { + /** + * Says to use @DataType.Name.UDT type in schema Java type is @UDTValue or model + * interface with @UDT annotation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDT { - /** - * If Java type is the @UDTValue then this field is required. Any Cassandra UDT has name and - * must be created before this use as a Cassandra Type. - * - *

This value is the UDT name of the Cassandra Type that was already created in the schema - * - *

In case of Java type is the model interface with @UDT annotation then this field is not - * using since model interface defines UserDefinedType with specific name - * - * @return UDT name - */ - String value() default ""; + /** + * If Java type is the @UDTValue then this field is required. Any Cassandra UDT + * has name and must be created before this use as a Cassandra Type. + * + *

+ * This value is the UDT name of the Cassandra Type that was already created in + * the schema + * + *

+ * In case of Java type is the model interface with @UDT annotation then this + * field is not using since model interface defines UserDefinedType with + * specific name + * + * @return UDT name + */ + String value() default ""; - /** - * Only used for JavaType @UDTValue - * - *

In case if value() method returns reserved word that can not be used as a name of UDT then - * forceQuote will add additional quotes around this name in all CQL queries. - * - *

Default value is false. - * - * @return true if quotation is needed - */ - boolean forceQuote() default false; - } + /** + * Only used for JavaType @UDTValue + * + *

+ * In case if value() method returns reserved word that can not be used as a + * name of UDT then forceQuote will add additional quotes around this name in + * all CQL queries. + * + *

+ * Default value is false. + * + * @return true if quotation is needed + */ + boolean forceQuote() default false; + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific UDT sub-type as a key and - * simple sub-type as a value Java type is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTKeyMap { + /** + * Says to use @DataType.Name.MAP data type in schema with specific UDT sub-type + * as a key and simple sub-type as a value Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTKeyMap { - /** - * Clarification of using the UDT data type as a key sub-type in the collection. - * - * @return annotation of UDT type - */ - UDT key(); + /** + * Clarification of using the UDT data type as a key sub-type in the collection. + * + * @return annotation of UDT type + */ + UDT key(); - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT value sub-type in the map, consider @UDTMap annotations - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT value sub-type in the map, consider @UDTMap + * annotations + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.LIST data type in schema with specific UDT sub-type Java type - * is @List - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: prepend, prependAll, setIdx, append, appendAll, - * discard and discardAll in @UpdateOperation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTList { + /** + * Says to use @DataType.Name.LIST data type in schema with specific UDT + * sub-type Java type is @List + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: prepend, prependAll, setIdx, + * append, appendAll, discard and discardAll in @UpdateOperation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTList { - /** - * Clarification of using the UDT data type as a sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a sub-type in the collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific UDT sub-types Java type - * is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTMap { + /** + * Says to use @DataType.Name.MAP data type in schema with specific UDT + * sub-types Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTMap { - /** - * Clarification of using the UDT data type as a key sub-type in the collection. - * - * @return annotation of the UDT key - */ - UDT key(); + /** + * Clarification of using the UDT data type as a key sub-type in the collection. + * + * @return annotation of the UDT key + */ + UDT key(); - /** - * Clarification of using the UDT data type as a value sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a value sub-type in the + * collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** - * Says to use @DataType.Name.SET data type in schema with specific UDT sub-type Java type is @Set - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: add, addAll, remove and removeAll - * in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTSet { + /** + * Says to use @DataType.Name.SET data type in schema with specific UDT sub-type + * Java type is @Set + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: add, addAll, remove and removeAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTSet { - /** - * Clarification of using the UDT data type as a sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a sub-type in the collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific simple sub-type as a key and - * UDT sub-type as a value Java type is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTValueMap { + /** + * Says to use @DataType.Name.MAP data type in schema with specific simple + * sub-type as a key and UDT sub-type as a value Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTValueMap { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT key sub-type in the map, consider @UDTMap annotations - * - * @return data type name of the key - */ - DataType.Name key(); + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT key sub-type in the map, consider @UDTMap annotations + * + * @return data type name of the key + */ + DataType.Name key(); - /** - * Clarification of using the UDT data type as a value sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a value sub-type in the + * collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** Says to use @DataType.Name.UUID type in schema Java type is @UUID Using by default */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Uuid {} + /** + * Says to use @DataType.Name.UUID type in schema Java type is @UUID Using by + * default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Uuid { + } - /** Says to use @DataType.Name.VARCHAR type in schema Java type is @String */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Varchar {} + /** Says to use @DataType.Name.VARCHAR type in schema Java type is @String */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Varchar { + } } diff --git a/src/main/java/net/helenus/mapping/annotation/UDT.java b/src/main/java/net/helenus/mapping/annotation/UDT.java index e330221..573688a 100644 --- a/src/main/java/net/helenus/mapping/annotation/UDT.java +++ b/src/main/java/net/helenus/mapping/annotation/UDT.java @@ -31,20 +31,21 @@ import java.lang.annotation.*; @Target({ElementType.TYPE}) public @interface UDT { - /** - * Default value is the SimpleName of the interface normalized to underscore - * - * @return name of the UDT type - */ - String value() default ""; + /** + * Default value is the SimpleName of the interface normalized to underscore + * + * @return name of the UDT type + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java b/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java index 1172dbe..91b3374 100644 --- a/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java +++ b/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java @@ -16,6 +16,7 @@ package net.helenus.mapping.convert; import java.util.Map; + import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.HelenusEntity; @@ -24,48 +25,48 @@ import net.helenus.mapping.value.BeanColumnValueProvider; public abstract class AbstractEntityValueWriter { - abstract void writeColumn(V outValue, Object value, HelenusProperty prop); + final HelenusEntity entity; - final HelenusEntity entity; + public AbstractEntityValueWriter(Class iface) { + this.entity = Helenus.entity(iface); + } - public AbstractEntityValueWriter(Class iface) { - this.entity = Helenus.entity(iface); - } + abstract void writeColumn(V outValue, Object value, HelenusProperty prop); - public void write(V outValue, Object source) { + public void write(V outValue, Object source) { - if (source instanceof MapExportable) { + if (source instanceof MapExportable) { - MapExportable exportable = (MapExportable) source; + MapExportable exportable = (MapExportable) source; - Map propertyToValueMap = exportable.toMap(); + Map propertyToValueMap = exportable.toMap(); - for (Map.Entry entry : propertyToValueMap.entrySet()) { + for (Map.Entry entry : propertyToValueMap.entrySet()) { - Object value = entry.getValue(); + Object value = entry.getValue(); - if (value == null) { - continue; - } + if (value == null) { + continue; + } - HelenusProperty prop = entity.getProperty(entry.getKey()); + HelenusProperty prop = entity.getProperty(entry.getKey()); - if (prop != null) { + if (prop != null) { - writeColumn(outValue, value, prop); - } - } + writeColumn(outValue, value, prop); + } + } - } else { + } else { - for (HelenusProperty prop : entity.getOrderedProperties()) { + for (HelenusProperty prop : entity.getOrderedProperties()) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(source, -1, prop); + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(source, -1, prop); - if (value != null) { - writeColumn(outValue, value, prop); - } - } - } - } + if (value != null) { + writeColumn(outValue, value, prop); + } + } + } + } } diff --git a/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java b/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java index f54b332..21a121b 100644 --- a/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java +++ b/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java @@ -19,15 +19,15 @@ import java.nio.ByteBuffer; import java.util.function.Function; public enum ByteArrayToByteBufferConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public ByteBuffer apply(byte[] t) { + @Override + public ByteBuffer apply(byte[] t) { - if (t == null) { - return null; - } + if (t == null) { + return null; + } - return ByteBuffer.wrap(t); - } + return ByteBuffer.wrap(t); + } } diff --git a/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java b/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java index c8183ab..bf9e130 100644 --- a/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java +++ b/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java @@ -19,15 +19,15 @@ import java.nio.ByteBuffer; import java.util.function.Function; public enum ByteBufferToByteArrayConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public byte[] apply(ByteBuffer t) { + @Override + public byte[] apply(ByteBuffer t) { - if (t == null) { - return null; - } + if (t == null) { + return null; + } - return t.array(); - } + return t.array(); + } } diff --git a/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java b/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java index 6f2ce20..b09d820 100644 --- a/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java +++ b/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java @@ -15,19 +15,20 @@ */ package net.helenus.mapping.convert; -import com.google.common.base.CaseFormat; import java.util.function.Function; +import com.google.common.base.CaseFormat; + public enum CamelCaseToUnderscoreConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public String apply(String source) { + @Override + public String apply(String source) { - if (source == null) { - throw new IllegalArgumentException("empty parameter"); - } + if (source == null) { + throw new IllegalArgumentException("empty parameter"); + } - return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, source); - } + return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, source); + } } diff --git a/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java b/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java index 7db03d9..c4eae86 100644 --- a/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java +++ b/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java @@ -18,15 +18,16 @@ package net.helenus.mapping.convert; import java.util.Date; import java.util.UUID; import java.util.function.Function; + import net.helenus.support.Timeuuid; /** Simple Date to TimeUUID Converter */ public enum DateToTimeuuidConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public UUID apply(Date source) { - long milliseconds = source.getTime(); - return Timeuuid.of(milliseconds); - } + @Override + public UUID apply(Date source) { + long milliseconds = source.getTime(); + return Timeuuid.of(milliseconds); + } } diff --git a/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java b/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java index 15e7d04..7020f7e 100644 --- a/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java +++ b/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java @@ -19,10 +19,10 @@ import java.util.function.Function; /** Enum to String Converter */ public enum EnumToStringConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public String apply(Enum source) { - return source.name(); - } + @Override + public String apply(Enum source) { + return source.name(); + } } diff --git a/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java b/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java index 8100679..07b4419 100644 --- a/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java +++ b/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java @@ -17,6 +17,7 @@ package net.helenus.mapping.convert; import java.util.Map; import java.util.function.Function; + import net.helenus.core.Helenus; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.value.ColumnValueProvider; @@ -24,23 +25,23 @@ import net.helenus.mapping.value.ValueProviderMap; public class ProxyValueReader implements Function { - private final Class iface; - private final HelenusEntity entity; - private final ColumnValueProvider valueProvider; + private final Class iface; + private final HelenusEntity entity; + private final ColumnValueProvider valueProvider; - public ProxyValueReader(Class iface, ColumnValueProvider valueProvider) { - this.iface = iface; - this.entity = Helenus.entity(iface); - this.valueProvider = valueProvider; - } + public ProxyValueReader(Class iface, ColumnValueProvider valueProvider) { + this.iface = iface; + this.entity = Helenus.entity(iface); + this.valueProvider = valueProvider; + } - @Override - public Object apply(T source) { - if (source != null) { - Map map = new ValueProviderMap(source, valueProvider, entity); + @Override + public Object apply(T source) { + if (source != null) { + Map map = new ValueProviderMap(source, valueProvider, entity); - return Helenus.map(iface, map); - } - return null; - } + return Helenus.map(iface, map); + } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java b/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java index ec632f5..41358ab 100644 --- a/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java +++ b/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java @@ -19,14 +19,14 @@ import java.util.function.Function; public class StringToEnumConverter implements Function { - private final Class enumClass; + private final Class enumClass; - public StringToEnumConverter(Class enumClass) { - this.enumClass = (Class) enumClass; - } + public StringToEnumConverter(Class enumClass) { + this.enumClass = (Class) enumClass; + } - @Override - public Enum apply(String source) { - return Enum.valueOf(enumClass, source); - } + @Override + public Enum apply(String source) { + return Enum.valueOf(enumClass, source); + } } diff --git a/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java b/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java index 352e019..51ee3df 100644 --- a/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java +++ b/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java @@ -18,13 +18,14 @@ package net.helenus.mapping.convert; import java.util.Date; import java.util.UUID; import java.util.function.Function; + import net.helenus.support.Timeuuid; public enum TimeuuidToDateConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public Date apply(UUID source) { - return new Date(Timeuuid.getTimestampMillis(source)); - } + @Override + public Date apply(UUID source) { + return new Date(Timeuuid.getTimestampMillis(source)); + } } diff --git a/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java b/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java index b197d5c..4ab4ebb 100644 --- a/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java +++ b/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java @@ -15,44 +15,45 @@ */ package net.helenus.mapping.convert; -import com.datastax.driver.core.TupleType; -import com.datastax.driver.core.TupleValue; import java.nio.ByteBuffer; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.value.TupleColumnValuePreparer; -public class TupleValueWriter extends AbstractEntityValueWriter - implements Function { +public class TupleValueWriter extends AbstractEntityValueWriter implements Function { - private final TupleType tupleType; - private final TupleColumnValuePreparer valuePreparer; + private final TupleType tupleType; + private final TupleColumnValuePreparer valuePreparer; - public TupleValueWriter(Class iface, TupleType tupleType, SessionRepository repository) { - super(iface); + public TupleValueWriter(Class iface, TupleType tupleType, SessionRepository repository) { + super(iface); - this.tupleType = tupleType; - this.valuePreparer = new TupleColumnValuePreparer(tupleType, repository); - } + this.tupleType = tupleType; + this.valuePreparer = new TupleColumnValuePreparer(tupleType, repository); + } - @Override - void writeColumn(TupleValue udtValue, Object value, HelenusProperty prop) { + @Override + void writeColumn(TupleValue udtValue, Object value, HelenusProperty prop) { - ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); + ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); - if (bytes != null) { - udtValue.setBytesUnsafe(prop.getOrdinal(), bytes); - } - } + if (bytes != null) { + udtValue.setBytesUnsafe(prop.getOrdinal(), bytes); + } + } - @Override - public TupleValue apply(Object source) { - if (source != null) { - TupleValue outValue = tupleType.newValue(); - write(outValue, source); - return outValue; - } - return null; - } + @Override + public TupleValue apply(Object source) { + if (source != null) { + TupleValue outValue = tupleType.newValue(); + write(outValue, source); + return outValue; + } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/convert/TypedConverter.java b/src/main/java/net/helenus/mapping/convert/TypedConverter.java index 52642d2..d9242ce 100644 --- a/src/main/java/net/helenus/mapping/convert/TypedConverter.java +++ b/src/main/java/net/helenus/mapping/convert/TypedConverter.java @@ -16,50 +16,50 @@ package net.helenus.mapping.convert; import java.util.function.Function; + import net.helenus.support.HelenusMappingException; public class TypedConverter implements Function { - private final Class inputType; - private final Class outputType; - private final Function delegate; + private final Class inputType; + private final Class outputType; + private final Function delegate; - public TypedConverter(Class inputType, Class outputType, Function delegate) { - this.inputType = inputType; - this.outputType = outputType; - this.delegate = delegate; - } + public TypedConverter(Class inputType, Class outputType, Function delegate) { + this.inputType = inputType; + this.outputType = outputType; + this.delegate = delegate; + } - public static TypedConverter create( - Class inputType, Class outputType, Function delegate) { - return new TypedConverter(inputType, outputType, delegate); - } + public static TypedConverter create(Class inputType, Class outputType, Function delegate) { + return new TypedConverter(inputType, outputType, delegate); + } - @Override - public Object apply(Object inputUnknown) { + @Override + public Object apply(Object inputUnknown) { - if (inputUnknown == null) { - return null; - } + if (inputUnknown == null) { + return null; + } - if (!inputType.isAssignableFrom(inputUnknown.getClass())) { - throw new HelenusMappingException( - "expected " + inputType + " type for input parameter " + inputUnknown.getClass()); - } + if (!inputType.isAssignableFrom(inputUnknown.getClass())) { + throw new HelenusMappingException( + "expected " + inputType + " type for input parameter " + inputUnknown.getClass()); + } - I input = (I) inputUnknown; + I input = (I) inputUnknown; - O outputUnknown = delegate.apply(input); + O outputUnknown = delegate.apply(input); - if (outputUnknown == null) { - return null; - } + if (outputUnknown == null) { + return null; + } - if (!outputType.isAssignableFrom(outputUnknown.getClass())) { - throw new HelenusMappingException( - "expected " + outputType + " type for output result " + outputUnknown.getClass()); - } + if (!outputType.isAssignableFrom(outputUnknown.getClass())) { + throw new HelenusMappingException( + "expected " + outputType + " type for output result " + outputUnknown.getClass()); + } - return outputUnknown; - } + return outputUnknown; + } } diff --git a/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java b/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java index 8156470..75d2c9e 100644 --- a/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java +++ b/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java @@ -15,44 +15,45 @@ */ package net.helenus.mapping.convert; -import com.datastax.driver.core.UDTValue; -import com.datastax.driver.core.UserType; import java.nio.ByteBuffer; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.value.UDTColumnValuePreparer; -public class UDTValueWriter extends AbstractEntityValueWriter - implements Function { +public class UDTValueWriter extends AbstractEntityValueWriter implements Function { - final UserType userType; - final UDTColumnValuePreparer valuePreparer; + final UserType userType; + final UDTColumnValuePreparer valuePreparer; - public UDTValueWriter(Class iface, UserType userType, SessionRepository repository) { - super(iface); + public UDTValueWriter(Class iface, UserType userType, SessionRepository repository) { + super(iface); - this.userType = userType; - this.valuePreparer = new UDTColumnValuePreparer(userType, repository); - } + this.userType = userType; + this.valuePreparer = new UDTColumnValuePreparer(userType, repository); + } - @Override - void writeColumn(UDTValue udtValue, Object value, HelenusProperty prop) { + @Override + void writeColumn(UDTValue udtValue, Object value, HelenusProperty prop) { - ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); + ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); - if (bytes != null) { - udtValue.setBytesUnsafe(prop.getColumnName().getName(), bytes); - } - } + if (bytes != null) { + udtValue.setBytesUnsafe(prop.getColumnName().getName(), bytes); + } + } - @Override - public UDTValue apply(Object source) { - if (source != null) { - UDTValue outValue = userType.newValue(); - write(outValue, source); - return outValue; - } - return null; - } + @Override + public UDTValue apply(Object source) { + if (source != null) { + UDTValue outValue = userType.newValue(); + write(outValue, source); + return outValue; + } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java index ded9f55..0717c04 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java @@ -15,17 +15,17 @@ */ package net.helenus.mapping.convert.tuple; +import java.util.function.Function; + import com.datastax.driver.core.TupleType; import com.datastax.driver.core.TupleValue; -import java.util.function.Function; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; -public final class EntityToTupleValueConverter extends TupleValueWriter - implements Function { +public final class EntityToTupleValueConverter extends TupleValueWriter implements Function { - public EntityToTupleValueConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - super(iface, tupleType, repository); - } + public EntityToTupleValueConverter(Class iface, TupleType tupleType, SessionRepository repository) { + super(iface, tupleType, repository); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java index f8f1c81..9b4ee51 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class MapToTupleKeyMapConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public MapToTupleKeyMapConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public MapToTupleKeyMapConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java index d99a7a1..821855f 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java @@ -15,30 +15,28 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class MapToTupleMapConverter implements Function { - final TupleValueWriter keyWriter; - final TupleValueWriter valueWriter; + final TupleValueWriter keyWriter; + final TupleValueWriter valueWriter; - public MapToTupleMapConverter( - Class keyClass, - TupleType keyType, - Class valueClass, - TupleType valueType, - SessionRepository repository) { - this.keyWriter = new TupleValueWriter(keyClass, keyType, repository); - this.valueWriter = new TupleValueWriter(valueClass, valueType, repository); - } + public MapToTupleMapConverter(Class keyClass, TupleType keyType, Class valueClass, TupleType valueType, + SessionRepository repository) { + this.keyWriter = new TupleValueWriter(keyClass, keyType, repository); + this.valueWriter = new TupleValueWriter(valueClass, valueType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyWriter, valueWriter); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyWriter, valueWriter); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java index 33901f5..4186487 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class MapToTupleValueMapConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public MapToTupleValueMapConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public MapToTupleValueMapConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java index db88523..6b1e0ed 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class SetToTupleSetConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public SetToTupleSetConverter(Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public SetToTupleSetConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java index 2f6605b..5142dc5 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleKeyMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleKeyMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleKeyMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java index 73a42b4..4fae478 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleListToListConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleListToListConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleListToListConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java index 50c6a44..dc3e2b3 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,19 +27,16 @@ import net.helenus.support.Transformers; public final class TupleMapToMapConverter implements Function { - final ProxyValueReader keyReader; - final ProxyValueReader valueReader; + final ProxyValueReader keyReader; + final ProxyValueReader valueReader; - public TupleMapToMapConverter( - Class keyClass, Class valueClass, SessionRepository repository) { - this.keyReader = - new ProxyValueReader(keyClass, new TupleColumnValueProvider(repository)); - this.valueReader = - new ProxyValueReader(valueClass, new TupleColumnValueProvider(repository)); - } + public TupleMapToMapConverter(Class keyClass, Class valueClass, SessionRepository repository) { + this.keyReader = new ProxyValueReader(keyClass, new TupleColumnValueProvider(repository)); + this.valueReader = new ProxyValueReader(valueClass, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyReader, valueReader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyReader, valueReader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java index 125e93a..5a9c8b5 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleSetToSetConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleSetToSetConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleSetToSetConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java index 95ccff3..2816c9c 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleValueMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleValueMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleValueMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java index 43d1d1f..7e5b5f3 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java @@ -15,16 +15,19 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; public final class TupleValueToEntityConverter extends ProxyValueReader - implements Function { + implements + Function { - public TupleValueToEntityConverter(Class iface, SessionRepository repository) { - super(iface, new TupleColumnValueProvider(repository)); - } + public TupleValueToEntityConverter(Class iface, SessionRepository repository) { + super(iface, new TupleColumnValueProvider(repository)); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java b/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java index 56f9932..58b9c9a 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java @@ -16,13 +16,13 @@ package net.helenus.mapping.convert.udt; import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; public final class EntityToUDTValueConverter extends UDTValueWriter { - public EntityToUDTValueConverter( - Class iface, UserType userType, SessionRepository repository) { - super(iface, userType, repository); - } + public EntityToUDTValueConverter(Class iface, UserType userType, SessionRepository repository) { + super(iface, userType, repository); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java b/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java index 4d3e318..66c3e15 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class ListToUDTListConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public ListToUDTListConverter(Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public ListToUDTListConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java index 63a51a2..64c228c 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class MapToUDTKeyMapConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public MapToUDTKeyMapConverter(Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public MapToUDTKeyMapConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java index a888647..e40bc0e 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java @@ -15,30 +15,28 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class MapToUDTMapConverter implements Function { - final UDTValueWriter keyWriter; - final UDTValueWriter valueWriter; + final UDTValueWriter keyWriter; + final UDTValueWriter valueWriter; - public MapToUDTMapConverter( - Class keyClass, - UserType keyType, - Class valueClass, - UserType valueType, - SessionRepository repository) { - this.keyWriter = new UDTValueWriter(keyClass, keyType, repository); - this.valueWriter = new UDTValueWriter(valueClass, valueType, repository); - } + public MapToUDTMapConverter(Class keyClass, UserType keyType, Class valueClass, UserType valueType, + SessionRepository repository) { + this.keyWriter = new UDTValueWriter(keyClass, keyType, repository); + this.valueWriter = new UDTValueWriter(valueClass, valueType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyWriter, valueWriter); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyWriter, valueWriter); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java index 9ca2936..1c4f1ff 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class MapToUDTValueMapConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public MapToUDTValueMapConverter( - Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public MapToUDTValueMapConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java b/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java index 9de5185..d2f8a23 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class SetToUDTSetConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public SetToUDTSetConverter(Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public SetToUDTSetConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java index 7744fc0..a3e1775 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTKeyMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTKeyMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTKeyMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java index 078a7aa..f711ce2 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTListToListConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTListToListConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTListToListConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java index 4ae3de5..e314bb3 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,19 +27,16 @@ import net.helenus.support.Transformers; public final class UDTMapToMapConverter implements Function { - final ProxyValueReader keyReader; - final ProxyValueReader valueReader; + final ProxyValueReader keyReader; + final ProxyValueReader valueReader; - public UDTMapToMapConverter( - Class keyClass, Class valueClass, SessionRepository repository) { - this.keyReader = - new ProxyValueReader(keyClass, new UDTColumnValueProvider(repository)); - this.valueReader = - new ProxyValueReader(valueClass, new UDTColumnValueProvider(repository)); - } + public UDTMapToMapConverter(Class keyClass, Class valueClass, SessionRepository repository) { + this.keyReader = new ProxyValueReader(keyClass, new UDTColumnValueProvider(repository)); + this.valueReader = new ProxyValueReader(valueClass, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyReader, valueReader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyReader, valueReader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java index 0adae72..3f5c267 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTSetToSetConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTSetToSetConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTSetToSetConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java index 8bb4f27..8772f5c 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTValueMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTValueMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTValueMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java index 6e7e082..a48024a 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java @@ -15,16 +15,17 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; -public final class UDTValueToEntityConverter extends ProxyValueReader - implements Function { +public final class UDTValueToEntityConverter extends ProxyValueReader implements Function { - public UDTValueToEntityConverter(Class iface, SessionRepository repository) { - super(iface, new UDTColumnValueProvider(repository)); - } + public UDTValueToEntityConverter(Class iface, SessionRepository repository) { + super(iface, new UDTColumnValueProvider(repository)); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java b/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java index a882398..090d202 100644 --- a/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java @@ -2,7 +2,7 @@ package net.helenus.mapping.javatype; public abstract class AbstractCollectionJavaType extends AbstractJavaType { - public static boolean isCollectionType() { - return true; - } + public static boolean isCollectionType() { + return true; + } } diff --git a/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java b/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java index abd7e21..6a9e441 100644 --- a/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java @@ -15,13 +15,15 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -33,107 +35,106 @@ import net.helenus.support.HelenusMappingException; public abstract class AbstractJavaType { - public static boolean isCollectionType() { - return false; - } + public static boolean isCollectionType() { + return false; + } - public abstract Class getJavaClass(); + static IdentityName resolveUDT(Types.UDT annotation) { + return IdentityName.of(annotation.value(), annotation.forceQuote()); + } - public boolean isApplicable(Class javaClass) { - return false; - } + static DataType resolveSimpleType(Method getter, DataType.Name typeName) { + DataType dataType = SimpleJavaTypes.getDataTypeByName(typeName); + if (dataType == null) { + throw new HelenusMappingException( + "only primitive types are allowed inside collections for the property " + getter); + } + return dataType; + } - public abstract AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata); + static void ensureTypeArguments(Method getter, int args, int expected) { + if (args != expected) { + throw new HelenusMappingException( + "expected " + expected + " of typed arguments for the property " + getter); + } + } - public Optional> getPrimitiveJavaClass() { - return Optional.empty(); - } + static Either autodetectParameterType(Method getter, Type type, Metadata metadata) { - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { - return Optional.empty(); - } + DataType dataType = null; - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { - return Optional.empty(); - } + if (type instanceof Class) { - static IdentityName resolveUDT(Types.UDT annotation) { - return IdentityName.of(annotation.value(), annotation.forceQuote()); - } + Class javaType = (Class) type; + dataType = SimpleJavaTypes.getDataTypeByJavaClass(javaType); - static DataType resolveSimpleType(Method getter, DataType.Name typeName) { - DataType dataType = SimpleJavaTypes.getDataTypeByName(typeName); - if (dataType == null) { - throw new HelenusMappingException( - "only primitive types are allowed inside collections for the property " + getter); - } - return dataType; - } + if (dataType != null) { + return Either.left(dataType); + } - static void ensureTypeArguments(Method getter, int args, int expected) { - if (args != expected) { - throw new HelenusMappingException( - "expected " + expected + " of typed arguments for the property " + getter); - } - } + if (MappingUtil.isTuple(javaType)) { + dataType = TupleValueJavaType.toTupleType(javaType, metadata); + return Either.left(dataType); + } - static class DataTypeInfo { - final DataType dataType; - final Class typeArgument; + IdentityName udtName = MappingUtil.getUserDefinedTypeName(javaType, false); - DataTypeInfo(DataType dataType) { - this.dataType = dataType; - this.typeArgument = null; - } + if (udtName != null) { + return Either.right(udtName); + } + } - DataTypeInfo(DataType dataType, Class typeArgument) { - this.dataType = dataType; - this.typeArgument = typeArgument; - } - } + throw new HelenusMappingException( + "unknown parameter type " + type + " in the collection for the property " + getter); + } - static Either autodetectParameterType( - Method getter, Type type, Metadata metadata) { + static Type[] getTypeParameters(Type genericJavaType) { - DataType dataType = null; + if (genericJavaType instanceof ParameterizedType) { - if (type instanceof Class) { + ParameterizedType type = (ParameterizedType) genericJavaType; - Class javaType = (Class) type; - dataType = SimpleJavaTypes.getDataTypeByJavaClass(javaType); + return type.getActualTypeArguments(); + } - if (dataType != null) { - return Either.left(dataType); - } + return new Type[]{}; + } - if (MappingUtil.isTuple(javaType)) { - dataType = TupleValueJavaType.toTupleType(javaType, metadata); - return Either.left(dataType); - } + public abstract Class getJavaClass(); - IdentityName udtName = MappingUtil.getUserDefinedTypeName(javaType, false); + public boolean isApplicable(Class javaClass) { + return false; + } - if (udtName != null) { - return Either.right(udtName); - } - } + public abstract AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata); - throw new HelenusMappingException( - "unknown parameter type " + type + " in the collection for the property " + getter); - } + public Optional> getPrimitiveJavaClass() { + return Optional.empty(); + } - static Type[] getTypeParameters(Type genericJavaType) { + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { + return Optional.empty(); + } - if (genericJavaType instanceof ParameterizedType) { + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { + return Optional.empty(); + } - ParameterizedType type = (ParameterizedType) genericJavaType; + static class DataTypeInfo { + final DataType dataType; + final Class typeArgument; - return type.getActualTypeArguments(); - } + DataTypeInfo(DataType dataType) { + this.dataType = dataType; + this.typeArgument = null; + } - return new Type[] {}; - } + DataTypeInfo(DataType dataType, Class typeArgument) { + this.dataType = dataType; + this.typeArgument = typeArgument; + } + } } diff --git a/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java b/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java index 02ab5af..c566547 100644 --- a/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java @@ -15,13 +15,15 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.nio.ByteBuffer; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; @@ -33,43 +35,41 @@ import net.helenus.mapping.type.DTDataType; public final class ByteArrayJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return byte[].class; - } + @Override + public Class getJavaClass() { + return byte[].class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { - return new DTDataType(columnType, DataType.blob()); - } + if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { + return new DTDataType(columnType, DataType.blob()); + } - Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); + Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); - if (null != custom) { - return new DTDataType(columnType, DataType.custom(custom.className())); - } + if (null != custom) { + return new DTDataType(columnType, DataType.custom(custom.className())); + } - return new DTDataType(columnType, DataType.blob()); - } + return new DTDataType(columnType, DataType.blob()); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - return Optional.of( - TypedConverter.create( - ByteBuffer.class, byte[].class, ByteBufferToByteArrayConverter.INSTANCE)); - } + return Optional + .of(TypedConverter.create(ByteBuffer.class, byte[].class, ByteBufferToByteArrayConverter.INSTANCE)); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - return Optional.of( - TypedConverter.create( - byte[].class, ByteBuffer.class, ByteArrayToByteBufferConverter.INSTANCE)); - } + return Optional + .of(TypedConverter.create(byte[].class, ByteBuffer.class, ByteArrayToByteBufferConverter.INSTANCE)); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java b/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java index c363a4f..b60e1db 100644 --- a/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java @@ -15,11 +15,13 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.nio.ByteBuffer; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -27,25 +29,25 @@ import net.helenus.mapping.type.DTDataType; public final class ByteBufferJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return ByteBuffer.class; - } + @Override + public Class getJavaClass() { + return ByteBuffer.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { - return new DTDataType(columnType, DataType.blob()); - } + if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { + return new DTDataType(columnType, DataType.blob()); + } - Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); + Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); - if (null != custom) { - return new DTDataType(columnType, DataType.custom(custom.className())); - } + if (null != custom) { + return new DTDataType(columnType, DataType.custom(custom.className())); + } - return new DTDataType(columnType, DataType.blob()); - } + return new DTDataType(columnType, DataType.blob()); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/DateJavaType.java b/src/main/java/net/helenus/mapping/javatype/DateJavaType.java index 2a97f30..133853d 100644 --- a/src/main/java/net/helenus/mapping/javatype/DateJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/DateJavaType.java @@ -15,14 +15,16 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Date; import java.util.Optional; import java.util.UUID; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; @@ -34,51 +36,49 @@ import net.helenus.mapping.type.DTDataType; public final class DateJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Date.class; - } + @Override + public Class getJavaClass() { + return Date.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Timestamp.class)) { - return new DTDataType(columnType, DataType.timestamp()); - } + if (null != getter.getDeclaredAnnotation(Types.Timestamp.class)) { + return new DTDataType(columnType, DataType.timestamp()); + } - if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { - return new DTDataType(columnType, DataType.timeuuid()); - } + if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { + return new DTDataType(columnType, DataType.timeuuid()); + } - return new DTDataType(columnType, DataType.timestamp()); - } + return new DTDataType(columnType, DataType.timestamp()); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - DataType dt = ((DTDataType) dataType).getDataType(); + DataType dt = ((DTDataType) dataType).getDataType(); - if (dt.getName() == DataType.Name.TIMEUUID) { - return Optional.of( - TypedConverter.create(UUID.class, Date.class, TimeuuidToDateConverter.INSTANCE)); - } + if (dt.getName() == DataType.Name.TIMEUUID) { + return Optional.of(TypedConverter.create(UUID.class, Date.class, TimeuuidToDateConverter.INSTANCE)); + } - return Optional.empty(); - } + return Optional.empty(); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - DataType dt = ((DTDataType) dataType).getDataType(); + DataType dt = ((DTDataType) dataType).getDataType(); - if (dt.getName() == DataType.Name.TIMEUUID) { - return Optional.of( - TypedConverter.create(Date.class, UUID.class, DateToTimeuuidConverter.INSTANCE)); - } + if (dt.getName() == DataType.Name.TIMEUUID) { + return Optional.of(TypedConverter.create(Date.class, UUID.class, DateToTimeuuidConverter.INSTANCE)); + } - return Optional.empty(); - } + return Optional.empty(); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java b/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java index b205a6d..a4b8dad 100644 --- a/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.convert.EnumToStringConverter; @@ -31,33 +33,31 @@ import net.helenus.mapping.type.DTDataType; public final class EnumJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Enum.class; - } + @Override + public Class getJavaClass() { + return Enum.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.ascii(), (Class) genericJavaType); - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.ascii(), (Class) genericJavaType); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - DTDataType dt = (DTDataType) dataType; + DTDataType dt = (DTDataType) dataType; - return Optional.of( - TypedConverter.create( - String.class, Enum.class, new StringToEnumConverter(dt.getJavaClass()))); - } + return Optional + .of(TypedConverter.create(String.class, Enum.class, new StringToEnumConverter(dt.getJavaClass()))); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - return Optional.of( - TypedConverter.create(Enum.class, String.class, EnumToStringConverter.INSTANCE)); - } + return Optional.of(TypedConverter.create(Enum.class, String.class, EnumToStringConverter.INSTANCE)); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/ListJavaType.java b/src/main/java/net/helenus/mapping/javatype/ListJavaType.java index 8e1f937..e4f4a53 100644 --- a/src/main/java/net/helenus/mapping/javatype/ListJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/ListJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.*; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.List; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.*; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -37,112 +39,110 @@ import net.helenus.support.HelenusMappingException; public final class ListJavaType extends AbstractCollectionJavaType { - @Override - public Class getJavaClass() { - return List.class; - } + @Override + public Class getJavaClass() { + return List.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - Types.List clist = getter.getDeclaredAnnotation(Types.List.class); - if (clist != null) { - return new DTDataType(columnType, DataType.list(resolveSimpleType(getter, clist.value()))); - } + Types.List clist = getter.getDeclaredAnnotation(Types.List.class); + if (clist != null) { + return new DTDataType(columnType, DataType.list(resolveSimpleType(getter, clist.value()))); + } - Types.UDTList udtList = getter.getDeclaredAnnotation(Types.UDTList.class); - if (udtList != null) { - return new UDTListDataType(columnType, resolveUDT(udtList.value()), UDTValue.class); - } + Types.UDTList udtList = getter.getDeclaredAnnotation(Types.UDTList.class); + if (udtList != null) { + return new UDTListDataType(columnType, resolveUDT(udtList.value()), UDTValue.class); + } - Type[] args = getTypeParameters(genericJavaType); - ensureTypeArguments(getter, args.length, 1); + Type[] args = getTypeParameters(genericJavaType); + ensureTypeArguments(getter, args.length, 1); - Either parameterType = - autodetectParameterType(getter, args[0], metadata); + Either parameterType = autodetectParameterType(getter, args[0], metadata); - if (parameterType.isLeft()) { - return DTDataType.list(columnType, parameterType.getLeft(), args[0]); - } else { - return new UDTListDataType(columnType, parameterType.getRight(), (Class) args[0]); - } - } + if (parameterType.isLeft()) { + return DTDataType.list(columnType, parameterType.getLeft(), args[0]); + } else { + return new UDTListDataType(columnType, parameterType.getRight(), (Class) args[0]); + } + } - @Override - public Optional> resolveReadConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of(new TupleListToListConverter(tupleClass, repository)); - } - } else if (abstractDataType instanceof UDTListDataType) { + return Optional.of(new TupleListToListConverter(tupleClass, repository)); + } + } else if (abstractDataType instanceof UDTListDataType) { - UDTListDataType dt = (UDTListDataType) abstractDataType; + UDTListDataType dt = (UDTListDataType) abstractDataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of(new UDTListToListConverter(javaClass, repository)); - } + return Optional.of(new UDTListToListConverter(javaClass, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of( - new ListToTupleListConverter(tupleClass, (TupleType) elementType, repository)); - } + return Optional.of(new ListToTupleListConverter(tupleClass, (TupleType) elementType, repository)); + } - } else if (abstractDataType instanceof UDTListDataType) { + } else if (abstractDataType instanceof UDTListDataType) { - UDTListDataType dt = (UDTListDataType) abstractDataType; + UDTListDataType dt = (UDTListDataType) abstractDataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - UserType userType = repository.findUserType(dt.getUdtName().getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + dt.getUdtName() + " with type " + javaClass); - } + UserType userType = repository.findUserType(dt.getUdtName().getName()); + if (userType == null) { + throw new HelenusMappingException( + "UserType not found for " + dt.getUdtName() + " with type " + javaClass); + } - return Optional.of(new ListToUDTListConverter(javaClass, userType, repository)); - } + return Optional.of(new ListToUDTListConverter(javaClass, userType, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/LongJavaType.java b/src/main/java/net/helenus/mapping/javatype/LongJavaType.java index b4d1b0d..0ace985 100644 --- a/src/main/java/net/helenus/mapping/javatype/LongJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/LongJavaType.java @@ -15,11 +15,13 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -27,28 +29,28 @@ import net.helenus.mapping.type.DTDataType; public final class LongJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Long.class; - } + @Override + public Class getJavaClass() { + return Long.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(long.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(long.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Counter.class)) { - return new DTDataType(columnType, DataType.counter()); - } + if (null != getter.getDeclaredAnnotation(Types.Counter.class)) { + return new DTDataType(columnType, DataType.counter()); + } - if (null != getter.getDeclaredAnnotation(Types.Bigint.class)) { - return new DTDataType(columnType, DataType.bigint()); - } + if (null != getter.getDeclaredAnnotation(Types.Bigint.class)) { + return new DTDataType(columnType, DataType.bigint()); + } - return new DTDataType(columnType, DataType.bigint()); - } + return new DTDataType(columnType, DataType.bigint()); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/MapJavaType.java b/src/main/java/net/helenus/mapping/javatype/MapJavaType.java index 2a5d187..e4c37ba 100644 --- a/src/main/java/net/helenus/mapping/javatype/MapJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/MapJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.*; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Map; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.*; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -33,322 +35,285 @@ import net.helenus.support.HelenusMappingException; public final class MapJavaType extends AbstractCollectionJavaType { - @Override - public Class getJavaClass() { - return Map.class; - } - - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - - Types.Map cmap = getter.getDeclaredAnnotation(Types.Map.class); - if (cmap != null) { - return new DTDataType( - columnType, - DataType.map( - resolveSimpleType(getter, cmap.key()), resolveSimpleType(getter, cmap.value()))); - } - - Types.UDTKeyMap udtKeyMap = getter.getDeclaredAnnotation(Types.UDTKeyMap.class); - if (udtKeyMap != null) { - return new UDTKeyMapDataType( - columnType, - resolveUDT(udtKeyMap.key()), - UDTValue.class, - resolveSimpleType(getter, udtKeyMap.value())); - } - - Types.UDTValueMap udtValueMap = getter.getDeclaredAnnotation(Types.UDTValueMap.class); - if (udtValueMap != null) { - return new UDTValueMapDataType( - columnType, - resolveSimpleType(getter, udtValueMap.key()), - resolveUDT(udtValueMap.value()), - UDTValue.class); - } + @Override + public Class getJavaClass() { + return Map.class; + } - Types.UDTMap udtMap = getter.getDeclaredAnnotation(Types.UDTMap.class); - if (udtMap != null) { - return new UDTMapDataType( - columnType, - resolveUDT(udtMap.key()), - UDTValue.class, - resolveUDT(udtMap.value()), - UDTValue.class); - } - - Type[] args = getTypeParameters(genericJavaType); - ensureTypeArguments(getter, args.length, 2); - - Either key = autodetectParameterType(getter, args[0], metadata); - Either value = autodetectParameterType(getter, args[1], metadata); + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (key.isLeft()) { + Types.Map cmap = getter.getDeclaredAnnotation(Types.Map.class); + if (cmap != null) { + return new DTDataType(columnType, + DataType.map(resolveSimpleType(getter, cmap.key()), resolveSimpleType(getter, cmap.value()))); + } - if (value.isLeft()) { - return DTDataType.map(columnType, key.getLeft(), args[0], value.getLeft(), args[1]); - } else { - return new UDTValueMapDataType( - columnType, key.getLeft(), value.getRight(), (Class) args[1]); - } - } else { + Types.UDTKeyMap udtKeyMap = getter.getDeclaredAnnotation(Types.UDTKeyMap.class); + if (udtKeyMap != null) { + return new UDTKeyMapDataType(columnType, resolveUDT(udtKeyMap.key()), UDTValue.class, + resolveSimpleType(getter, udtKeyMap.value())); + } - if (value.isLeft()) { - return new UDTKeyMapDataType( - columnType, key.getRight(), (Class) args[0], value.getLeft()); - } else { - return new UDTMapDataType( - columnType, key.getRight(), (Class) args[0], value.getRight(), (Class) args[1]); - } - } - } + Types.UDTValueMap udtValueMap = getter.getDeclaredAnnotation(Types.UDTValueMap.class); + if (udtValueMap != null) { + return new UDTValueMapDataType(columnType, resolveSimpleType(getter, udtValueMap.key()), + resolveUDT(udtValueMap.value()), UDTValue.class); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + Types.UDTMap udtMap = getter.getDeclaredAnnotation(Types.UDTMap.class); + if (udtMap != null) { + return new UDTMapDataType(columnType, resolveUDT(udtMap.key()), UDTValue.class, resolveUDT(udtMap.value()), + UDTValue.class); + } - if (abstractDataType instanceof DTDataType) { - return resolveDTReadConverter((DTDataType) abstractDataType, repository); - } else if (abstractDataType instanceof UDTKeyMapDataType) { + Type[] args = getTypeParameters(genericJavaType); + ensureTypeArguments(getter, args.length, 2); - UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; + Either key = autodetectParameterType(getter, args[0], metadata); + Either value = autodetectParameterType(getter, args[1], metadata); - Class keyClass = (Class) dt.getUdtKeyClass(); + if (key.isLeft()) { - if (UDTValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + if (value.isLeft()) { + return DTDataType.map(columnType, key.getLeft(), args[0], value.getLeft(), args[1]); + } else { + return new UDTValueMapDataType(columnType, key.getLeft(), value.getRight(), (Class) args[1]); + } + } else { - return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); + if (value.isLeft()) { + return new UDTKeyMapDataType(columnType, key.getRight(), (Class) args[0], value.getLeft()); + } else { + return new UDTMapDataType(columnType, key.getRight(), (Class) args[0], value.getRight(), + (Class) args[1]); + } + } + } - } else if (abstractDataType instanceof UDTValueMapDataType) { + @Override + public Optional> resolveReadConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; + if (abstractDataType instanceof DTDataType) { + return resolveDTReadConverter((DTDataType) abstractDataType, repository); + } else if (abstractDataType instanceof UDTKeyMapDataType) { - Class valueClass = (Class) dt.getUdtValueClass(); + UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + Class keyClass = (Class) dt.getUdtKeyClass(); - return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); + if (UDTValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - } else if (abstractDataType instanceof UDTMapDataType) { + return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); - UDTMapDataType dt = (UDTMapDataType) abstractDataType; + } else if (abstractDataType instanceof UDTValueMapDataType) { - Class keyClass = (Class) dt.getUdtKeyClass(); - Class valueClass = (Class) dt.getUdtValueClass(); + UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(keyClass)) { + Class valueClass = (Class) dt.getUdtValueClass(); - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { - return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); - } - } else if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); - } + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } - return Optional.of(new UDTMapToMapConverter(keyClass, valueClass, repository)); - } + return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); - return Optional.empty(); - } + } else if (abstractDataType instanceof UDTMapDataType) { - private Optional> resolveDTReadConverter( - DTDataType dt, SessionRepository repository) { + UDTMapDataType dt = (UDTMapDataType) abstractDataType; - DataType keyDataType = dt.getDataType().getTypeArguments().get(0); - DataType valueDataType = dt.getDataType().getTypeArguments().get(1); + Class keyClass = (Class) dt.getUdtKeyClass(); + Class valueClass = (Class) dt.getUdtValueClass(); - if (keyDataType instanceof TupleType) { + if (UDTValue.class.isAssignableFrom(keyClass)) { - if (valueDataType instanceof TupleType) { + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { + return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); + } + } else if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); + } - Class keyClass = dt.getTypeArguments()[0]; - Class valueClass = dt.getTypeArguments()[1]; + return Optional.of(new UDTMapToMapConverter(keyClass, valueClass, repository)); + } - if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { - return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); - } + private Optional> resolveDTReadConverter(DTDataType dt, SessionRepository repository) { - } else if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); - } + DataType keyDataType = dt.getDataType().getTypeArguments().get(0); + DataType valueDataType = dt.getDataType().getTypeArguments().get(1); - return Optional.of(new TupleMapToMapConverter(keyClass, valueClass, repository)); + if (keyDataType instanceof TupleType) { - } else { - Class keyClass = dt.getTypeArguments()[0]; + if (valueDataType instanceof TupleType) { - if (TupleValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + Class keyClass = dt.getTypeArguments()[0]; + Class valueClass = dt.getTypeArguments()[1]; - return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); - } - } else if (valueDataType instanceof TupleType) { + if (TupleValue.class.isAssignableFrom(keyClass)) { - Class valueClass = dt.getTypeArguments()[0]; + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { + return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + } else if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); + } - return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); - } + return Optional.of(new TupleMapToMapConverter(keyClass, valueClass, repository)); - return Optional.empty(); - } + } else { + Class keyClass = dt.getTypeArguments()[0]; - @Override - public Optional> resolveWriteConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - if (abstractDataType instanceof DTDataType) { - return resolveDTWriteConverter((DTDataType) abstractDataType, repository); - } else if (abstractDataType instanceof UDTKeyMapDataType) { + return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); + } + } else if (valueDataType instanceof TupleType) { - UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; + Class valueClass = dt.getTypeArguments()[0]; - Class keyClass = (Class) dt.getUdtKeyClass(); + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } - if (UDTValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); + } - return Optional.of( - new MapToUDTKeyMapConverter( - keyClass, getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); + return Optional.empty(); + } - } else if (abstractDataType instanceof UDTValueMapDataType) { + @Override + public Optional> resolveWriteConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; + if (abstractDataType instanceof DTDataType) { + return resolveDTWriteConverter((DTDataType) abstractDataType, repository); + } else if (abstractDataType instanceof UDTKeyMapDataType) { - Class valueClass = (Class) dt.getUdtValueClass(); + UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + Class keyClass = (Class) dt.getUdtKeyClass(); - return Optional.of( - new MapToUDTValueMapConverter( - valueClass, getUserType(dt.getUdtValueName(), valueClass, repository), repository)); + if (UDTValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - } else if (abstractDataType instanceof UDTMapDataType) { + return Optional.of(new MapToUDTKeyMapConverter(keyClass, + getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); - UDTMapDataType dt = (UDTMapDataType) abstractDataType; + } else if (abstractDataType instanceof UDTValueMapDataType) { - Class keyClass = (Class) dt.getUdtKeyClass(); - Class valueClass = (Class) dt.getUdtValueClass(); + UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(keyClass)) { + Class valueClass = (Class) dt.getUdtValueClass(); - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } - return Optional.of( - new MapToUDTValueMapConverter( - valueClass, - getUserType(dt.getUdtValueName(), valueClass, repository), - repository)); - } - } else if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.of(new MapToUDTValueMapConverter(valueClass, + getUserType(dt.getUdtValueName(), valueClass, repository), repository)); - return Optional.of( - new MapToUDTKeyMapConverter( - keyClass, getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); - } + } else if (abstractDataType instanceof UDTMapDataType) { - return Optional.of( - new MapToUDTMapConverter( - keyClass, - getUserType(dt.getUdtKeyName(), keyClass, repository), - valueClass, - getUserType(dt.getUdtValueName(), valueClass, repository), - repository)); - } + UDTMapDataType dt = (UDTMapDataType) abstractDataType; - return Optional.empty(); - } + Class keyClass = (Class) dt.getUdtKeyClass(); + Class valueClass = (Class) dt.getUdtValueClass(); - private Optional> resolveDTWriteConverter( - DTDataType dt, SessionRepository repository) { + if (UDTValue.class.isAssignableFrom(keyClass)) { - DataType keyDataType = dt.getDataType().getTypeArguments().get(0); - DataType valueDataType = dt.getDataType().getTypeArguments().get(1); + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { - if (keyDataType instanceof TupleType) { + return Optional.of(new MapToUDTValueMapConverter(valueClass, + getUserType(dt.getUdtValueName(), valueClass, repository), repository)); + } + } else if (UDTValue.class.isAssignableFrom(valueClass)) { - if (valueDataType instanceof TupleType) { + return Optional.of(new MapToUDTKeyMapConverter(keyClass, + getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); + } - Class keyClass = dt.getTypeArguments()[0]; - Class valueClass = dt.getTypeArguments()[1]; + return Optional.of(new MapToUDTMapConverter(keyClass, getUserType(dt.getUdtKeyName(), keyClass, repository), + valueClass, getUserType(dt.getUdtValueName(), valueClass, repository), repository)); + } - if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { - return Optional.of( - new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); - } + private Optional> resolveDTWriteConverter(DTDataType dt, SessionRepository repository) { - } else if (TupleValue.class.isAssignableFrom(valueClass)) { + DataType keyDataType = dt.getDataType().getTypeArguments().get(0); + DataType valueDataType = dt.getDataType().getTypeArguments().get(1); - return Optional.of( - new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); - } + if (keyDataType instanceof TupleType) { - return Optional.of( - new MapToTupleMapConverter( - keyClass, - (TupleType) keyDataType, - valueClass, - (TupleType) valueDataType, - repository)); + if (valueDataType instanceof TupleType) { - } else { + Class keyClass = dt.getTypeArguments()[0]; + Class valueClass = dt.getTypeArguments()[1]; - Class keyClass = dt.getTypeArguments()[0]; + if (TupleValue.class.isAssignableFrom(keyClass)) { - if (TupleValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { + return Optional + .of(new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); + } - return Optional.of( - new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); - } - } else if (valueDataType instanceof TupleType) { + } else if (TupleValue.class.isAssignableFrom(valueClass)) { - Class valueClass = dt.getTypeArguments()[0]; + return Optional.of(new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + return Optional.of(new MapToTupleMapConverter(keyClass, (TupleType) keyDataType, valueClass, + (TupleType) valueDataType, repository)); - return Optional.of( - new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); - } + } else { - return Optional.empty(); - } + Class keyClass = dt.getTypeArguments()[0]; - private UserType getUserType( - IdentityName name, Class javaClass, SessionRepository repository) { - UserType userType = repository.findUserType(name.getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + name + " with type " + javaClass); - } - return userType; - } + if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } + + return Optional.of(new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); + } + } else if (valueDataType instanceof TupleType) { + + Class valueClass = dt.getTypeArguments()[0]; + + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } + + return Optional.of(new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); + } + + return Optional.empty(); + } + + private UserType getUserType(IdentityName name, Class javaClass, SessionRepository repository) { + UserType userType = repository.findUserType(name.getName()); + if (userType == null) { + throw new HelenusMappingException("UserType not found for " + name + " with type " + javaClass); + } + return userType; + } } diff --git a/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java b/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java index 3884425..224eb1f 100644 --- a/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java +++ b/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java @@ -15,15 +15,17 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; -import com.google.common.collect.ImmutableMap; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.util.Optional; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; +import com.google.common.collect.ImmutableMap; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.type.AbstractDataType; import net.helenus.mapping.type.DTDataType; @@ -31,189 +33,189 @@ import net.helenus.support.HelenusMappingException; public final class MappingJavaTypes { - private static final EnumJavaType ENUM_JAVA_TYPE = new EnumJavaType(); - private static final UDTValueJavaType UDT_VALUE_JAVA_TYPE = new UDTValueJavaType(); - private static final TupleValueJavaType TUPLE_VALUE_JAVA_TYPE = new TupleValueJavaType(); + private static final EnumJavaType ENUM_JAVA_TYPE = new EnumJavaType(); + private static final UDTValueJavaType UDT_VALUE_JAVA_TYPE = new UDTValueJavaType(); + private static final TupleValueJavaType TUPLE_VALUE_JAVA_TYPE = new TupleValueJavaType(); - private static final ImmutableMap, AbstractJavaType> knownTypes; + private static final ImmutableMap, AbstractJavaType> knownTypes; - static { - ImmutableMap.Builder, AbstractJavaType> builder = ImmutableMap.builder(); + static { + ImmutableMap.Builder, AbstractJavaType> builder = ImmutableMap.builder(); - add(builder, new BooleanJavaType()); - add(builder, new BigDecimalJavaType()); - add(builder, new BigIntegerJavaType()); - add(builder, new DoubleJavaType()); - add(builder, new FloatJavaType()); - add(builder, new IntegerJavaType()); - add(builder, new InetAddressJavaType()); + add(builder, new BooleanJavaType()); + add(builder, new BigDecimalJavaType()); + add(builder, new BigIntegerJavaType()); + add(builder, new DoubleJavaType()); + add(builder, new FloatJavaType()); + add(builder, new IntegerJavaType()); + add(builder, new InetAddressJavaType()); - add(builder, new ByteBufferJavaType()); - add(builder, new ByteArrayJavaType()); - add(builder, new DateJavaType()); - add(builder, new UUIDJavaType()); - add(builder, new LongJavaType()); - add(builder, new StringJavaType()); - add(builder, ENUM_JAVA_TYPE); - add(builder, new ListJavaType()); - add(builder, new SetJavaType()); - add(builder, new MapJavaType()); - add(builder, TUPLE_VALUE_JAVA_TYPE); - add(builder, UDT_VALUE_JAVA_TYPE); + add(builder, new ByteBufferJavaType()); + add(builder, new ByteArrayJavaType()); + add(builder, new DateJavaType()); + add(builder, new UUIDJavaType()); + add(builder, new LongJavaType()); + add(builder, new StringJavaType()); + add(builder, ENUM_JAVA_TYPE); + add(builder, new ListJavaType()); + add(builder, new SetJavaType()); + add(builder, new MapJavaType()); + add(builder, TUPLE_VALUE_JAVA_TYPE); + add(builder, UDT_VALUE_JAVA_TYPE); - knownTypes = builder.build(); - } + knownTypes = builder.build(); + } - private static void add( - ImmutableMap.Builder, AbstractJavaType> builder, AbstractJavaType jt) { + private MappingJavaTypes() { + } - builder.put(jt.getJavaClass(), jt); + private static void add(ImmutableMap.Builder, AbstractJavaType> builder, AbstractJavaType jt) { - Optional> primitiveJavaClass = jt.getPrimitiveJavaClass(); - if (primitiveJavaClass.isPresent()) { - builder.put(primitiveJavaClass.get(), jt); - } - } + builder.put(jt.getJavaClass(), jt); - private MappingJavaTypes() {} + Optional> primitiveJavaClass = jt.getPrimitiveJavaClass(); + if (primitiveJavaClass.isPresent()) { + builder.put(primitiveJavaClass.get(), jt); + } + } - public static AbstractJavaType resolveJavaType(Class javaClass) { + public static AbstractJavaType resolveJavaType(Class javaClass) { - AbstractJavaType ajt = knownTypes.get(javaClass); - if (ajt != null) { - return ajt; - } + AbstractJavaType ajt = knownTypes.get(javaClass); + if (ajt != null) { + return ajt; + } - if (Enum.class.isAssignableFrom(javaClass)) { - return ENUM_JAVA_TYPE; - } + if (Enum.class.isAssignableFrom(javaClass)) { + return ENUM_JAVA_TYPE; + } - if (TUPLE_VALUE_JAVA_TYPE.isApplicable(javaClass)) { - return TUPLE_VALUE_JAVA_TYPE; - } + if (TUPLE_VALUE_JAVA_TYPE.isApplicable(javaClass)) { + return TUPLE_VALUE_JAVA_TYPE; + } - if (UDT_VALUE_JAVA_TYPE.isApplicable(javaClass)) { - return UDT_VALUE_JAVA_TYPE; - } + if (UDT_VALUE_JAVA_TYPE.isApplicable(javaClass)) { + return UDT_VALUE_JAVA_TYPE; + } - throw new HelenusMappingException("unknown java type " + javaClass); - } + throw new HelenusMappingException("unknown java type " + javaClass); + } - public static final class BooleanJavaType extends AbstractJavaType { + public static final class BooleanJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Boolean.class; - } + @Override + public Class getJavaClass() { + return Boolean.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(boolean.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(boolean.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cboolean()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cboolean()); + } + } - public static final class BigDecimalJavaType extends AbstractJavaType { + public static final class BigDecimalJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return BigDecimal.class; - } + @Override + public Class getJavaClass() { + return BigDecimal.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.decimal()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.decimal()); + } + } - public static final class BigIntegerJavaType extends AbstractJavaType { + public static final class BigIntegerJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return BigInteger.class; - } + @Override + public Class getJavaClass() { + return BigInteger.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.varint()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.varint()); + } + } - public static final class DoubleJavaType extends AbstractJavaType { + public static final class DoubleJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Double.class; - } + @Override + public Class getJavaClass() { + return Double.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(double.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(double.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cdouble()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cdouble()); + } + } - public static final class FloatJavaType extends AbstractJavaType { + public static final class FloatJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Float.class; - } + @Override + public Class getJavaClass() { + return Float.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(float.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(float.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cfloat()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cfloat()); + } + } - public static final class IntegerJavaType extends AbstractJavaType { + public static final class IntegerJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Integer.class; - } + @Override + public Class getJavaClass() { + return Integer.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(int.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(int.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cint()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cint()); + } + } - public static final class InetAddressJavaType extends AbstractJavaType { + public static final class InetAddressJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return InetAddress.class; - } + @Override + public Class getJavaClass() { + return InetAddress.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.inet()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.inet()); + } + } } diff --git a/src/main/java/net/helenus/mapping/javatype/SetJavaType.java b/src/main/java/net/helenus/mapping/javatype/SetJavaType.java index 818d862..7d07ad3 100644 --- a/src/main/java/net/helenus/mapping/javatype/SetJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/SetJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.*; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.*; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -37,112 +39,110 @@ import net.helenus.support.HelenusMappingException; public final class SetJavaType extends AbstractCollectionJavaType { - @Override - public Class getJavaClass() { - return Set.class; - } + @Override + public Class getJavaClass() { + return Set.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - Types.Set cset = getter.getDeclaredAnnotation(Types.Set.class); - if (cset != null) { - return new DTDataType(columnType, DataType.set(resolveSimpleType(getter, cset.value()))); - } + Types.Set cset = getter.getDeclaredAnnotation(Types.Set.class); + if (cset != null) { + return new DTDataType(columnType, DataType.set(resolveSimpleType(getter, cset.value()))); + } - Types.UDTSet udtSet = getter.getDeclaredAnnotation(Types.UDTSet.class); - if (udtSet != null) { - return new UDTSetDataType(columnType, resolveUDT(udtSet.value()), UDTValue.class); - } + Types.UDTSet udtSet = getter.getDeclaredAnnotation(Types.UDTSet.class); + if (udtSet != null) { + return new UDTSetDataType(columnType, resolveUDT(udtSet.value()), UDTValue.class); + } - Type[] args = getTypeParameters(genericJavaType); - ensureTypeArguments(getter, args.length, 1); + Type[] args = getTypeParameters(genericJavaType); + ensureTypeArguments(getter, args.length, 1); - Either parameterType = - autodetectParameterType(getter, args[0], metadata); + Either parameterType = autodetectParameterType(getter, args[0], metadata); - if (parameterType.isLeft()) { - return DTDataType.set(columnType, parameterType.getLeft(), args[0]); - } else { - return new UDTSetDataType(columnType, parameterType.getRight(), (Class) args[0]); - } - } + if (parameterType.isLeft()) { + return DTDataType.set(columnType, parameterType.getLeft(), args[0]); + } else { + return new UDTSetDataType(columnType, parameterType.getRight(), (Class) args[0]); + } + } - @Override - public Optional> resolveReadConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of(new TupleSetToSetConverter(tupleClass, repository)); - } - } else if (abstractDataType instanceof UDTSetDataType) { + return Optional.of(new TupleSetToSetConverter(tupleClass, repository)); + } + } else if (abstractDataType instanceof UDTSetDataType) { - UDTSetDataType dt = (UDTSetDataType) abstractDataType; + UDTSetDataType dt = (UDTSetDataType) abstractDataType; - Class udtClass = (Class) dt.getTypeArguments()[0]; + Class udtClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(udtClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(udtClass)) { + return Optional.empty(); + } - return Optional.of(new UDTSetToSetConverter(udtClass, repository)); - } + return Optional.of(new UDTSetToSetConverter(udtClass, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of( - new SetToTupleSetConverter(tupleClass, (TupleType) elementType, repository)); - } + return Optional.of(new SetToTupleSetConverter(tupleClass, (TupleType) elementType, repository)); + } - } else if (abstractDataType instanceof UDTSetDataType) { + } else if (abstractDataType instanceof UDTSetDataType) { - UDTSetDataType dt = (UDTSetDataType) abstractDataType; + UDTSetDataType dt = (UDTSetDataType) abstractDataType; - Class udtClass = (Class) dt.getTypeArguments()[0]; + Class udtClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(udtClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(udtClass)) { + return Optional.empty(); + } - UserType userType = repository.findUserType(dt.getUdtName().getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + dt.getUdtName() + " with type " + udtClass); - } + UserType userType = repository.findUserType(dt.getUdtName().getName()); + if (userType == null) { + throw new HelenusMappingException( + "UserType not found for " + dt.getUdtName() + " with type " + udtClass); + } - return Optional.of(new SetToUDTSetConverter(udtClass, userType, repository)); - } + return Optional.of(new SetToUDTSetConverter(udtClass, userType, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java b/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java index 2484f24..9d2324b 100644 --- a/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java +++ b/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java @@ -15,53 +15,50 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.CodecRegistry; -import com.datastax.driver.core.DataType; import java.time.LocalTime; import java.util.HashMap; import java.util.Map; +import com.datastax.driver.core.CodecRegistry; +import com.datastax.driver.core.DataType; + public final class SimpleJavaTypes { - private static final Map, DataType> javaClassToDataTypeMap = - new HashMap, DataType>(); + private static final Map, DataType> javaClassToDataTypeMap = new HashMap, DataType>(); - private static final Map nameToDataTypeMap = - new HashMap(); + private static final Map nameToDataTypeMap = new HashMap(); - static { - for (DataType dataType : DataType.allPrimitiveTypes()) { + static { + for (DataType dataType : DataType.allPrimitiveTypes()) { - nameToDataTypeMap.put(dataType.getName(), dataType); + nameToDataTypeMap.put(dataType.getName(), dataType); - if (dataType.equals(DataType.counter()) - || dataType.equals(DataType.ascii()) - || dataType.equals(DataType.timeuuid()) - || dataType.equals(DataType.time())) { - continue; - } + if (dataType.equals(DataType.counter()) || dataType.equals(DataType.ascii()) + || dataType.equals(DataType.timeuuid()) || dataType.equals(DataType.time())) { + continue; + } - Class javaClass = - CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getRawType(); + Class javaClass = CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getRawType(); - DataType dt = javaClassToDataTypeMap.putIfAbsent(javaClass, dataType); - if (dt != null) { - throw new IllegalStateException( - "java type " + javaClass + " is has two datatypes " + dt + " and " + dataType); - } - } + DataType dt = javaClassToDataTypeMap.putIfAbsent(javaClass, dataType); + if (dt != null) { + throw new IllegalStateException( + "java type " + javaClass + " is has two datatypes " + dt + " and " + dataType); + } + } - javaClassToDataTypeMap.put(String.class, DataType.text()); - javaClassToDataTypeMap.put(LocalTime.class, DataType.time()); - } + javaClassToDataTypeMap.put(String.class, DataType.text()); + javaClassToDataTypeMap.put(LocalTime.class, DataType.time()); + } - private SimpleJavaTypes() {} + private SimpleJavaTypes() { + } - public static DataType getDataTypeByName(DataType.Name name) { - return nameToDataTypeMap.get(name); - } + public static DataType getDataTypeByName(DataType.Name name) { + return nameToDataTypeMap.get(name); + } - public static DataType getDataTypeByJavaClass(Class javaType) { - return javaClassToDataTypeMap.get(javaType); - } + public static DataType getDataTypeByJavaClass(Class javaType) { + return javaClassToDataTypeMap.get(javaType); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/StringJavaType.java b/src/main/java/net/helenus/mapping/javatype/StringJavaType.java index 333e857..d4e9253 100644 --- a/src/main/java/net/helenus/mapping/javatype/StringJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/StringJavaType.java @@ -15,10 +15,12 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -26,27 +28,27 @@ import net.helenus.mapping.type.DTDataType; public final class StringJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return String.class; - } + @Override + public Class getJavaClass() { + return String.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Ascii.class)) { - return new DTDataType(columnType, DataType.ascii()); - } + if (null != getter.getDeclaredAnnotation(Types.Ascii.class)) { + return new DTDataType(columnType, DataType.ascii()); + } - if (null != getter.getDeclaredAnnotation(Types.Text.class)) { - return new DTDataType(columnType, DataType.text()); - } + if (null != getter.getDeclaredAnnotation(Types.Text.class)) { + return new DTDataType(columnType, DataType.text()); + } - if (null != getter.getDeclaredAnnotation(Types.Varchar.class)) { - return new DTDataType(columnType, DataType.varchar()); - } + if (null != getter.getDeclaredAnnotation(Types.Varchar.class)) { + return new DTDataType(columnType, DataType.varchar()); + } - return new DTDataType(columnType, DataType.text()); - } + return new DTDataType(columnType, DataType.text()); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java b/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java index 47e2be3..9374ed8 100644 --- a/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java @@ -15,16 +15,18 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; -import com.datastax.driver.core.TupleType; -import com.datastax.driver.core.TupleValue; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.List; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.TupleType; +import com.datastax.driver.core.TupleValue; + import net.helenus.core.Helenus; import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; @@ -41,112 +43,94 @@ import net.helenus.support.HelenusMappingException; public final class TupleValueJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return TupleValue.class; - } + public static TupleType toTupleType(Class javaType, Metadata metadata) { + HelenusEntity tupleEntity = Helenus.entity(javaType, metadata); - @Override - public boolean isApplicable(Class javaClass) { - return MappingUtil.isTuple(javaClass); - } + List tupleTypes = tupleEntity.getOrderedProperties().stream().map(p -> p.getDataType()) + .filter(d -> d instanceof DTDataType).map(d -> (DTDataType) d).map(d -> d.getDataType()) + .collect(Collectors.toList()); - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + if (tupleTypes.size() < tupleEntity.getOrderedProperties().size()) { - Class javaType = (Class) genericJavaType; + List wrongColumns = tupleEntity.getOrderedProperties().stream() + .filter(p -> !(p.getDataType() instanceof DTDataType)).map(p -> p.getColumnName()) + .collect(Collectors.toList()); - if (TupleValue.class.isAssignableFrom(javaType)) { + throw new HelenusMappingException( + "non simple types in tuple " + tupleEntity.getMappingInterface() + " in columns: " + wrongColumns); + } - Types.Tuple tuple = getter.getDeclaredAnnotation(Types.Tuple.class); - if (tuple == null) { - throw new HelenusMappingException( - "tuple must be annotated by @Tuple annotation in " + getter); - } + return metadata.newTupleType(tupleTypes.toArray(new DataType[tupleTypes.size()])); + } - DataType.Name[] tupleArguments = tuple.value(); - int len = tupleArguments.length; - DataType[] arguments = new DataType[len]; + @Override + public Class getJavaClass() { + return TupleValue.class; + } - for (int i = 0; i != len; ++i) { - arguments[i] = resolveSimpleType(getter, tupleArguments[i]); - } + @Override + public boolean isApplicable(Class javaClass) { + return MappingUtil.isTuple(javaClass); + } - TupleType tupleType = metadata.newTupleType(arguments); - return new DTDataType(columnType, tupleType, javaType); + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - } else { - return new DTDataType(columnType, toTupleType(javaType, metadata), javaType); - } - } + Class javaType = (Class) genericJavaType; - public static TupleType toTupleType(Class javaType, Metadata metadata) { - HelenusEntity tupleEntity = Helenus.entity(javaType, metadata); + if (TupleValue.class.isAssignableFrom(javaType)) { - List tupleTypes = - tupleEntity - .getOrderedProperties() - .stream() - .map(p -> p.getDataType()) - .filter(d -> d instanceof DTDataType) - .map(d -> (DTDataType) d) - .map(d -> d.getDataType()) - .collect(Collectors.toList()); + Types.Tuple tuple = getter.getDeclaredAnnotation(Types.Tuple.class); + if (tuple == null) { + throw new HelenusMappingException("tuple must be annotated by @Tuple annotation in " + getter); + } - if (tupleTypes.size() < tupleEntity.getOrderedProperties().size()) { + DataType.Name[] tupleArguments = tuple.value(); + int len = tupleArguments.length; + DataType[] arguments = new DataType[len]; - List wrongColumns = - tupleEntity - .getOrderedProperties() - .stream() - .filter(p -> !(p.getDataType() instanceof DTDataType)) - .map(p -> p.getColumnName()) - .collect(Collectors.toList()); + for (int i = 0; i != len; ++i) { + arguments[i] = resolveSimpleType(getter, tupleArguments[i]); + } - throw new HelenusMappingException( - "non simple types in tuple " - + tupleEntity.getMappingInterface() - + " in columns: " - + wrongColumns); - } + TupleType tupleType = metadata.newTupleType(arguments); + return new DTDataType(columnType, tupleType, javaType); - return metadata.newTupleType(tupleTypes.toArray(new DataType[tupleTypes.size()])); - } + } else { + return new DTDataType(columnType, toTupleType(javaType, metadata), javaType); + } + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - DTDataType dt = (DTDataType) dataType; + DTDataType dt = (DTDataType) dataType; - Class javaClass = (Class) dt.getJavaClass(); + Class javaClass = (Class) dt.getJavaClass(); - if (TupleValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of( - TypedConverter.create( - TupleValue.class, javaClass, new TupleValueToEntityConverter(javaClass, repository))); - } + return Optional.of(TypedConverter.create(TupleValue.class, javaClass, + new TupleValueToEntityConverter(javaClass, repository))); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - DTDataType dt = (DTDataType) dataType; + DTDataType dt = (DTDataType) dataType; - Class javaClass = (Class) dt.getJavaClass(); + Class javaClass = (Class) dt.getJavaClass(); - if (TupleValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of( - TypedConverter.create( - javaClass, - TupleValue.class, - new EntityToTupleValueConverter(javaClass, (TupleType) dt.getDataType(), repository))); - } + return Optional.of(TypedConverter.create(javaClass, TupleValue.class, + new EntityToTupleValueConverter(javaClass, (TupleType) dt.getDataType(), repository))); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java b/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java index 240bfbd..7c6246c 100644 --- a/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java @@ -15,13 +15,15 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.Metadata; -import com.datastax.driver.core.UDTValue; -import com.datastax.driver.core.UserType; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.UDTValue; +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -36,82 +38,77 @@ import net.helenus.support.HelenusMappingException; public final class UDTValueJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return UDTValue.class; - } + @Override + public Class getJavaClass() { + return UDTValue.class; + } - @Override - public boolean isApplicable(Class javaClass) { - return MappingUtil.isUDT(javaClass); - } + @Override + public boolean isApplicable(Class javaClass) { + return MappingUtil.isUDT(javaClass); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - Class javaType = (Class) genericJavaType; + Class javaType = (Class) genericJavaType; - IdentityName udtName = null; + IdentityName udtName = null; - if (UDTValue.class.isAssignableFrom(javaType)) { + if (UDTValue.class.isAssignableFrom(javaType)) { - Types.UDT userTypeName = getter.getDeclaredAnnotation(Types.UDT.class); - if (userTypeName == null) { - throw new HelenusMappingException("absent UserTypeName annotation for " + getter); - } + Types.UDT userTypeName = getter.getDeclaredAnnotation(Types.UDT.class); + if (userTypeName == null) { + throw new HelenusMappingException("absent UserTypeName annotation for " + getter); + } - udtName = new IdentityName(userTypeName.value(), userTypeName.forceQuote()); - } else { - udtName = MappingUtil.getUserDefinedTypeName(javaType, false); - } + udtName = new IdentityName(userTypeName.value(), userTypeName.forceQuote()); + } else { + udtName = MappingUtil.getUserDefinedTypeName(javaType, false); + } - if (udtName != null) { - return new UDTDataType(columnType, udtName, javaType); - } + if (udtName != null) { + return new UDTDataType(columnType, udtName, javaType); + } - throw new HelenusMappingException("unknown type " + javaType + " in " + getter); - } + throw new HelenusMappingException("unknown type " + javaType + " in " + getter); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - UDTDataType dt = (UDTDataType) dataType; + UDTDataType dt = (UDTDataType) dataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of( - TypedConverter.create( - UDTValue.class, javaClass, new UDTValueToEntityConverter(javaClass, repository))); - } + return Optional.of( + TypedConverter.create(UDTValue.class, javaClass, new UDTValueToEntityConverter(javaClass, repository))); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - UDTDataType dt = (UDTDataType) dataType; + UDTDataType dt = (UDTDataType) dataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - UserType userType = repository.findUserType(dt.getUdtName().getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + dt.getUdtName() + " with type " + javaClass); - } + UserType userType = repository.findUserType(dt.getUdtName().getName()); + if (userType == null) { + throw new HelenusMappingException("UserType not found for " + dt.getUdtName() + " with type " + javaClass); + } - return Optional.of( - TypedConverter.create( - javaClass, - UDTValue.class, - new EntityToUDTValueConverter(javaClass, userType, repository))); - } + return Optional.of(TypedConverter.create(javaClass, UDTValue.class, + new EntityToUDTValueConverter(javaClass, userType, repository))); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java b/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java index d3c712b..52aca62 100644 --- a/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java @@ -15,11 +15,13 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.UUID; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -27,23 +29,23 @@ import net.helenus.mapping.type.DTDataType; public final class UUIDJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return UUID.class; - } + @Override + public Class getJavaClass() { + return UUID.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Uuid.class)) { - return new DTDataType(columnType, DataType.uuid()); - } + if (null != getter.getDeclaredAnnotation(Types.Uuid.class)) { + return new DTDataType(columnType, DataType.uuid()); + } - if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { - return new DTDataType(columnType, DataType.timeuuid()); - } + if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { + return new DTDataType(columnType, DataType.timeuuid()); + } - return new DTDataType(columnType, DataType.uuid()); - } + return new DTDataType(columnType, DataType.uuid()); + } } diff --git a/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java b/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java index 7e76d92..ef8b9a1 100644 --- a/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java +++ b/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java @@ -4,11 +4,11 @@ import net.helenus.mapping.ColumnType; public abstract class AbstractCollectionDataType extends AbstractDataType { - public AbstractCollectionDataType(ColumnType columnType) { - super(columnType); - } + public AbstractCollectionDataType(ColumnType columnType) { + super(columnType); + } - public boolean isCollectionType() { - return true; - } + public boolean isCollectionType() { + return true; + } } diff --git a/src/main/java/net/helenus/mapping/type/AbstractDataType.java b/src/main/java/net/helenus/mapping/type/AbstractDataType.java index cc65d68..7115b57 100644 --- a/src/main/java/net/helenus/mapping/type/AbstractDataType.java +++ b/src/main/java/net/helenus/mapping/type/AbstractDataType.java @@ -19,43 +19,44 @@ import com.datastax.driver.core.schemabuilder.Alter; import com.datastax.driver.core.schemabuilder.Create; import com.datastax.driver.core.schemabuilder.CreateType; import com.datastax.driver.core.schemabuilder.SchemaStatement; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public abstract class AbstractDataType { - public abstract void addColumn(Create create, IdentityName columnName); + final ColumnType columnType; - public abstract void addColumn(CreateType create, IdentityName columnName); + public AbstractDataType(ColumnType columnType) { + this.columnType = columnType; + } - public abstract SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnInformation); + public abstract void addColumn(Create create, IdentityName columnName); - public abstract Class[] getTypeArguments(); + public abstract void addColumn(CreateType create, IdentityName columnName); - final ColumnType columnType; + public abstract SchemaStatement alterColumn(Alter alter, IdentityName columnName, + OptionalColumnMetadata columnInformation); - public AbstractDataType(ColumnType columnType) { - this.columnType = columnType; - } + public abstract Class[] getTypeArguments(); - public ColumnType getColumnType() { - return columnType; - } + public ColumnType getColumnType() { + return columnType; + } - void ensureSimpleColumn(IdentityName columnName) { - if (columnType != ColumnType.COLUMN) { - throwWrongColumnType(columnName); - } - } + void ensureSimpleColumn(IdentityName columnName) { + if (columnType != ColumnType.COLUMN) { + throwWrongColumnType(columnName); + } + } - void throwWrongColumnType(IdentityName columnName) { - throw new HelenusMappingException( - "wrong column type " + columnType + " for UserDefinedType in columnName " + columnName); - } + void throwWrongColumnType(IdentityName columnName) { + throw new HelenusMappingException( + "wrong column type " + columnType + " for UserDefinedType in columnName " + columnName); + } - public boolean isCollectionType() { - return false; - } + public boolean isCollectionType() { + return false; + } } diff --git a/src/main/java/net/helenus/mapping/type/DTDataType.java b/src/main/java/net/helenus/mapping/type/DTDataType.java index e61d171..d4d2e05 100644 --- a/src/main/java/net/helenus/mapping/type/DTDataType.java +++ b/src/main/java/net/helenus/mapping/type/DTDataType.java @@ -15,6 +15,8 @@ */ package net.helenus.mapping.type; +import java.lang.reflect.Type; + import com.datastax.driver.core.CodecRegistry; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TupleType; @@ -22,185 +24,166 @@ import com.datastax.driver.core.schemabuilder.Alter; import com.datastax.driver.core.schemabuilder.Create; import com.datastax.driver.core.schemabuilder.CreateType; import com.datastax.driver.core.schemabuilder.SchemaStatement; -import java.lang.reflect.Type; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class DTDataType extends AbstractDataType { - private static final Class[] EMPTY_CLASSES = new Class[] {}; + private static final Class[] EMPTY_CLASSES = new Class[]{}; - private final DataType dataType; - private final Class javaClass; - private final Class[] typeArguments; - private final boolean isCollectionType; + private final DataType dataType; + private final Class javaClass; + private final Class[] typeArguments; + private final boolean isCollectionType; - public DTDataType(ColumnType columnType, DataType dataType) { - this( - columnType, - dataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getClass(), - EMPTY_CLASSES); - } + public DTDataType(ColumnType columnType, DataType dataType) { + this(columnType, dataType, CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getClass(), + EMPTY_CLASSES); + } - public DTDataType(ColumnType columnType, DataType dataType, Class javaClass) { - this(columnType, dataType, javaClass, EMPTY_CLASSES); - } + public DTDataType(ColumnType columnType, DataType dataType, Class javaClass) { + this(columnType, dataType, javaClass, EMPTY_CLASSES); + } - public DTDataType( - ColumnType columnType, DataType dataType, Class javaClass, Class[] typeArguments) { - super(columnType); - this.dataType = dataType; - this.javaClass = javaClass; - this.typeArguments = typeArguments; - this.isCollectionType = dataType.isCollection(); - } + public DTDataType(ColumnType columnType, DataType dataType, Class javaClass, Class[] typeArguments) { + super(columnType); + this.dataType = dataType; + this.javaClass = javaClass; + this.typeArguments = typeArguments; + this.isCollectionType = dataType.isCollection(); + } - public static DTDataType list( - ColumnType columnType, DataType argumentDataType, Type argumentType) { + public static DTDataType list(ColumnType columnType, DataType argumentDataType, Type argumentType) { - DataType listDataType = DataType.list(argumentDataType); + DataType listDataType = DataType.list(argumentDataType); - if (argumentDataType instanceof TupleType) { - return new DTDataType( - columnType, - listDataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(listDataType).getClass(), - new Class[] {(Class) argumentType}); - } else { - return new DTDataType(columnType, listDataType); - } - } + if (argumentDataType instanceof TupleType) { + return new DTDataType(columnType, listDataType, + CodecRegistry.DEFAULT_INSTANCE.codecFor(listDataType).getClass(), + new Class[]{(Class) argumentType}); + } else { + return new DTDataType(columnType, listDataType); + } + } - public static DTDataType set( - ColumnType columnType, DataType argumentDataType, Type argumentType) { + public static DTDataType set(ColumnType columnType, DataType argumentDataType, Type argumentType) { - DataType setDataType = DataType.set(argumentDataType); + DataType setDataType = DataType.set(argumentDataType); - if (argumentDataType instanceof TupleType) { - return new DTDataType( - columnType, - setDataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(setDataType).getClass(), - new Class[] {(Class) argumentType}); - } else { - return new DTDataType(columnType, setDataType); - } - } + if (argumentDataType instanceof TupleType) { + return new DTDataType(columnType, setDataType, + CodecRegistry.DEFAULT_INSTANCE.codecFor(setDataType).getClass(), + new Class[]{(Class) argumentType}); + } else { + return new DTDataType(columnType, setDataType); + } + } - public static DTDataType map( - ColumnType columnType, - DataType keyDataType, - Type keyType, - DataType valueDataType, - Type valueType) { + public static DTDataType map(ColumnType columnType, DataType keyDataType, Type keyType, DataType valueDataType, + Type valueType) { - DataType mapDataType = DataType.map(keyDataType, valueDataType); + DataType mapDataType = DataType.map(keyDataType, valueDataType); - Class[] typeArguments = EMPTY_CLASSES; + Class[] typeArguments = EMPTY_CLASSES; - if (keyDataType instanceof TupleType) { - if (valueDataType instanceof TupleType) { - typeArguments = new Class[] {(Class) keyType, (Class) valueType}; - } else { - typeArguments = new Class[] {(Class) keyType}; - } - } else if (valueDataType instanceof TupleType) { - typeArguments = new Class[] {(Class) valueType}; - } + if (keyDataType instanceof TupleType) { + if (valueDataType instanceof TupleType) { + typeArguments = new Class[]{(Class) keyType, (Class) valueType}; + } else { + typeArguments = new Class[]{(Class) keyType}; + } + } else if (valueDataType instanceof TupleType) { + typeArguments = new Class[]{(Class) valueType}; + } - return new DTDataType( - columnType, - mapDataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(mapDataType).getClass(), - typeArguments); - } + return new DTDataType(columnType, mapDataType, CodecRegistry.DEFAULT_INSTANCE.codecFor(mapDataType).getClass(), + typeArguments); + } - public DataType getDataType() { - return dataType; - } + public DataType getDataType() { + return dataType; + } - public Class getJavaClass() { - return javaClass; - } + public Class getJavaClass() { + return javaClass; + } - @Override - public Class[] getTypeArguments() { - return typeArguments; - } + @Override + public Class[] getTypeArguments() { + return typeArguments; + } - @Override - public void addColumn(Create create, IdentityName columnName) { + @Override + public void addColumn(Create create, IdentityName columnName) { - switch (columnType) { - case PARTITION_KEY: - create.addPartitionKey(columnName.toCql(), dataType); - break; + switch (columnType) { + case PARTITION_KEY : + create.addPartitionKey(columnName.toCql(), dataType); + break; - case CLUSTERING_COLUMN: - create.addClusteringColumn(columnName.toCql(), dataType); - break; + case CLUSTERING_COLUMN : + create.addClusteringColumn(columnName.toCql(), dataType); + break; - case STATIC_COLUMN: - create.addStaticColumn(columnName.toCql(), dataType); - break; + case STATIC_COLUMN : + create.addStaticColumn(columnName.toCql(), dataType); + break; - case COLUMN: - create.addColumn(columnName.toCql(), dataType); - break; + case COLUMN : + create.addColumn(columnName.toCql(), dataType); + break; - default: - throwWrongColumnType(columnName); - } - } + default : + throwWrongColumnType(columnName); + } + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { + @Override + public void addColumn(CreateType create, IdentityName columnName) { - if (columnType != ColumnType.COLUMN) { - throwWrongColumnType(columnName); - } + if (columnType != ColumnType.COLUMN) { + throwWrongColumnType(columnName); + } - create.addColumn(columnName.toCql(), dataType); - } + create.addColumn(columnName.toCql(), dataType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata != null) { + if (columnMetadata != null) { - if (!dataType.equals(columnMetadata.getType())) { - ensureSimpleColumn(columnName); + if (!dataType.equals(columnMetadata.getType())) { + ensureSimpleColumn(columnName); - return alter.alterColumn(columnName.toCql()).type(dataType); - } + return alter.alterColumn(columnName.toCql()).type(dataType); + } - } else { + } else { - switch (columnType) { - case STATIC_COLUMN: - return alter.addStaticColumn(columnName.toCql()).type(dataType); + switch (columnType) { + case STATIC_COLUMN : + return alter.addStaticColumn(columnName.toCql()).type(dataType); - case COLUMN: - return alter.addColumn(columnName.toCql()).type(dataType); + case COLUMN : + return alter.addColumn(columnName.toCql()).type(dataType); - default: - throw new HelenusMappingException( - "unable to alter " + columnType + " column " + columnName); - } - } + default : + throw new HelenusMappingException("unable to alter " + columnType + " column " + columnName); + } + } - return null; - } + return null; + } - public boolean isCollectionType() { - return isCollectionType; - } + public boolean isCollectionType() { + return isCollectionType; + } - @Override - public String toString() { - return dataType.toString(); - } + @Override + public String toString() { + return dataType.toString(); + } } diff --git a/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java b/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java index a364c48..a7fb9d4 100644 --- a/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java +++ b/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.type; -import com.datastax.driver.core.TupleType; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class ListToTupleListConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public ListToTupleListConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public ListToTupleListConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java b/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java index f6d240c..0589c76 100644 --- a/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java +++ b/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java @@ -19,7 +19,7 @@ import com.datastax.driver.core.DataType; public interface OptionalColumnMetadata { - String getName(); + String getName(); - DataType getType(); + DataType getType(); } diff --git a/src/main/java/net/helenus/mapping/type/UDTDataType.java b/src/main/java/net/helenus/mapping/type/UDTDataType.java index 281529c..d24e9a3 100644 --- a/src/main/java/net/helenus/mapping/type/UDTDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTDataType.java @@ -18,100 +18,100 @@ package net.helenus.mapping.type; import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; public final class UDTDataType extends AbstractDataType { - private final IdentityName udtName; - private final Class udtClass; + private final IdentityName udtName; + private final Class udtClass; - public UDTDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { - super(columnType); - this.udtName = udtName; - this.udtClass = udtClass; - } + public UDTDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { + super(columnType); + this.udtName = udtName; + this.udtClass = udtClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtClass}; + } - public IdentityName getUdtName() { - return udtName; - } + public IdentityName getUdtName() { + return udtName; + } - @Override - public void addColumn(Create create, IdentityName columnName) { + @Override + public void addColumn(Create create, IdentityName columnName) { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - switch (columnType) { - case PARTITION_KEY: - create.addUDTPartitionKey(columnName.toCql(), udtType); - break; + switch (columnType) { + case PARTITION_KEY : + create.addUDTPartitionKey(columnName.toCql(), udtType); + break; - case CLUSTERING_COLUMN: - create.addUDTClusteringColumn(columnName.toCql(), udtType); - break; + case CLUSTERING_COLUMN : + create.addUDTClusteringColumn(columnName.toCql(), udtType); + break; - case STATIC_COLUMN: - create.addUDTStaticColumn(columnName.toCql(), udtType); - break; + case STATIC_COLUMN : + create.addUDTStaticColumn(columnName.toCql(), udtType); + break; - case COLUMN: - create.addUDTColumn(columnName.toCql(), udtType); - break; + case COLUMN : + create.addUDTColumn(columnName.toCql(), udtType); + break; - default: - throwWrongColumnType(columnName); - } - } + default : + throwWrongColumnType(columnName); + } + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTColumn(columnName.toCql(), udtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - ensureSimpleColumn(columnName); + ensureSimpleColumn(columnName); - if (columnMetadata != null) { + if (columnMetadata != null) { - DataType metadataType = columnMetadata.getType(); - if (metadataType.getName() == DataType.Name.UDT && metadataType instanceof UserType) { + DataType metadataType = columnMetadata.getType(); + if (metadataType.getName() == DataType.Name.UDT && metadataType instanceof UserType) { - UserType metadataUserType = (UserType) metadataType; + UserType metadataUserType = (UserType) metadataType; - if (!udtName.getName().equals(metadataUserType.getTypeName())) { + if (!udtName.getName().equals(metadataUserType.getTypeName())) { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - return alter.alterColumn(columnName.toCql()).udtType(udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + return alter.alterColumn(columnName.toCql()).udtType(udtType); + } - } else { + } else { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - return alter.alterColumn(columnName.toCql()).udtType(udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + return alter.alterColumn(columnName.toCql()).udtType(udtType); + } - } else { + } else { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - return alter.addColumn(columnName.toCql()).udtType(udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + return alter.addColumn(columnName.toCql()).udtType(udtType); + } - return null; - } + return null; + } - @Override - public String toString() { - return "UDT<" + udtName + ">"; - } + @Override + public String toString() { + return "UDT<" + udtName + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java b/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java index e04685c..25c0939 100644 --- a/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java @@ -15,97 +15,97 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTKeyMapDataType extends AbstractCollectionDataType { - private final IdentityName keyType; - private final Class udtKeyClass; - private final DataType valueType; + private final IdentityName keyType; + private final Class udtKeyClass; + private final DataType valueType; - public UDTKeyMapDataType( - ColumnType columnType, IdentityName keyType, Class udtKeyClass, DataType valueType) { - super(columnType); - this.keyType = keyType; - this.udtKeyClass = udtKeyClass; - this.valueType = valueType; - } + public UDTKeyMapDataType(ColumnType columnType, IdentityName keyType, Class udtKeyClass, DataType valueType) { + super(columnType); + this.keyType = keyType; + this.udtKeyClass = udtKeyClass; + this.valueType = valueType; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtKeyClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtKeyClass}; + } - public IdentityName getUdtKeyName() { - return keyType; - } + public IdentityName getUdtKeyName() { + return keyType; + } - public Class getUdtKeyClass() { - return udtKeyClass; - } + public Class getUdtKeyClass() { + return udtKeyClass; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.MAP) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.MAP) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 2 || !args.get(1).equals(valueType)) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 2 || !args.get(1).equals(valueType)) { + return notSupportedOperation("alter", columnName); + } - DataType keyDataType = args.get(0); - if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType keyDataType = args.get(0); + if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtKeyType = (UserType) keyDataType; + UserType udtKeyType = (UserType) keyDataType; - if (!keyType.getName().equals(udtKeyType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!keyType.getName().equals(udtKeyType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTKeyMap<" + keyType + "," + valueType + ">"; - } + @Override + public String toString() { + return "UDTKeyMap<" + keyType + "," + valueType + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTListDataType.java b/src/main/java/net/helenus/mapping/type/UDTListDataType.java index 21b2956..2a08410 100644 --- a/src/main/java/net/helenus/mapping/type/UDTListDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTListDataType.java @@ -15,93 +15,91 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTListDataType extends AbstractCollectionDataType { - private final IdentityName udtName; - private final Class udtClass; + private final IdentityName udtName; + private final Class udtClass; - public UDTListDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { - super(columnType); - this.udtName = udtName; - this.udtClass = udtClass; - } + public UDTListDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { + super(columnType); + this.udtName = udtName; + this.udtClass = udtClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtClass}; + } - public IdentityName getUdtName() { - return udtName; - } + public IdentityName getUdtName() { + return udtName; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTListColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTListColumn(columnName.toCql(), udtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTListColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTListColumn(columnName.toCql(), udtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.LIST) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.LIST) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 1) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 1) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(0); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(0); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!udtName.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!udtName.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op - + " UDTList column is not supported by Cassandra Driver for column '" - + columnName - + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTList column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTList<" + udtName + ">"; - } + @Override + public String toString() { + return "UDTList<" + udtName + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTMapDataType.java b/src/main/java/net/helenus/mapping/type/UDTMapDataType.java index d672fa9..960cfab 100644 --- a/src/main/java/net/helenus/mapping/type/UDTMapDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTMapDataType.java @@ -15,124 +15,121 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTMapDataType extends AbstractCollectionDataType { - private final IdentityName keyType; - private final Class udtKeyClass; - private final IdentityName valueType; - private final Class udtValueClass; + private final IdentityName keyType; + private final Class udtKeyClass; + private final IdentityName valueType; + private final Class udtValueClass; - public UDTMapDataType( - ColumnType columnType, - IdentityName keyType, - Class udtKeyClass, - IdentityName valueType, - Class udtValueClass) { - super(columnType); - this.keyType = keyType; - this.udtKeyClass = udtKeyClass; - this.valueType = valueType; - this.udtValueClass = udtValueClass; - } + public UDTMapDataType(ColumnType columnType, IdentityName keyType, Class udtKeyClass, IdentityName valueType, + Class udtValueClass) { + super(columnType); + this.keyType = keyType; + this.udtKeyClass = udtKeyClass; + this.valueType = valueType; + this.udtValueClass = udtValueClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtKeyClass, udtValueClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtKeyClass, udtValueClass}; + } - public IdentityName getUdtKeyName() { - return keyType; - } + public IdentityName getUdtKeyName() { + return keyType; + } - public Class getUdtKeyClass() { - return udtKeyClass; - } + public Class getUdtKeyClass() { + return udtKeyClass; + } - public IdentityName getUdtValueName() { - return valueType; - } + public IdentityName getUdtValueName() { + return valueType; + } - public Class getUdtValueClass() { - return udtValueClass; - } + public Class getUdtValueClass() { + return udtValueClass; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.MAP) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.MAP) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 2) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 2) { + return notSupportedOperation("alter", columnName); + } - DataType keyDataType = args.get(0); - if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType keyDataType = args.get(0); + if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtKeyType = (UserType) keyDataType; + UserType udtKeyType = (UserType) keyDataType; - if (!keyType.getName().equals(udtKeyType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!keyType.getName().equals(udtKeyType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(1); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(1); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!valueType.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!valueType.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTMap<" + keyType + "," + valueType + ">"; - } + @Override + public String toString() { + return "UDTMap<" + keyType + "," + valueType + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTSetDataType.java b/src/main/java/net/helenus/mapping/type/UDTSetDataType.java index 72ffcb0..c22965f 100644 --- a/src/main/java/net/helenus/mapping/type/UDTSetDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTSetDataType.java @@ -15,90 +15,91 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTSetDataType extends AbstractCollectionDataType { - private final IdentityName udtName; - private final Class udtClass; + private final IdentityName udtName; + private final Class udtClass; - public UDTSetDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { - super(columnType); - this.udtName = udtName; - this.udtClass = udtClass; - } + public UDTSetDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { + super(columnType); + this.udtName = udtName; + this.udtClass = udtClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtClass}; + } - public IdentityName getUdtName() { - return udtName; - } + public IdentityName getUdtName() { + return udtName; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTSetColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTSetColumn(columnName.toCql(), udtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTSetColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTSetColumn(columnName.toCql(), udtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.SET) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.SET) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 1) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 1) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(0); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(0); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!udtName.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!udtName.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTSet column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTSet column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTSet<" + udtName + ">"; - } + @Override + public String toString() { + return "UDTSet<" + udtName + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java b/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java index 48683c2..140f84b 100644 --- a/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java @@ -15,97 +15,98 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTValueMapDataType extends AbstractCollectionDataType { - private final DataType keyType; - private final IdentityName valueType; - private final Class udtValueClass; + private final DataType keyType; + private final IdentityName valueType; + private final Class udtValueClass; - public UDTValueMapDataType( - ColumnType columnType, DataType keyType, IdentityName valueType, Class udtValueClass) { - super(columnType); - this.keyType = keyType; - this.valueType = valueType; - this.udtValueClass = udtValueClass; - } + public UDTValueMapDataType(ColumnType columnType, DataType keyType, IdentityName valueType, + Class udtValueClass) { + super(columnType); + this.keyType = keyType; + this.valueType = valueType; + this.udtValueClass = udtValueClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtValueClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtValueClass}; + } - public IdentityName getUdtValueName() { - return valueType; - } + public IdentityName getUdtValueName() { + return valueType; + } - public Class getUdtValueClass() { - return udtValueClass; - } + public Class getUdtValueClass() { + return udtValueClass; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); - } + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); - } + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.MAP) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.MAP) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 2 || !args.get(0).equals(keyType)) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 2 || !args.get(0).equals(keyType)) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(1); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(1); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!valueType.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!valueType.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTValueMap<" + keyType + "," + valueType + ">"; - } + @Override + public String toString() { + return "UDTValueMap<" + keyType + "," + valueType + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java b/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java index 07d67db..a69f447 100644 --- a/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java +++ b/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java @@ -16,38 +16,39 @@ package net.helenus.mapping.validator; import java.util.Arrays; + import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class AlphabetValidator - implements ConstraintValidator { +public final class AlphabetValidator implements ConstraintValidator { - char[] alphabet; + char[] alphabet; - @Override - public void initialize(Constraints.Alphabet constraintAnnotation) { - alphabet = constraintAnnotation.value().toCharArray(); - Arrays.sort(alphabet); - } + @Override + public void initialize(Constraints.Alphabet constraintAnnotation) { + alphabet = constraintAnnotation.value().toCharArray(); + Arrays.sort(alphabet); + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - final int len = value.length(); - for (int i = 0; i != len; ++i) { + final int len = value.length(); + for (int i = 0; i != len; ++i) { - char ch = value.charAt(i); + char ch = value.charAt(i); - if (Arrays.binarySearch(alphabet, ch) < 0) { - return false; - } - } + if (Arrays.binarySearch(alphabet, ch) < 0) { + return false; + } + } - return true; - } + return true; + } } diff --git a/src/main/java/net/helenus/mapping/validator/EmailValidator.java b/src/main/java/net/helenus/mapping/validator/EmailValidator.java index 9cfbdc0..a00d7f8 100644 --- a/src/main/java/net/helenus/mapping/validator/EmailValidator.java +++ b/src/main/java/net/helenus/mapping/validator/EmailValidator.java @@ -17,33 +17,35 @@ package net.helenus.mapping.validator; import java.net.IDN; import java.util.regex.Pattern; + import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints.Email; public final class EmailValidator implements ConstraintValidator { - static final String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]"; - static final String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*"; - static final String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]"; + static final String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]"; + static final String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*"; + static final String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]"; - static final String PATTERN = - "^" + ATOM + "+(\\." + ATOM + "+)*@" + DOMAIN + "|" + IP_DOMAIN + ")$"; + static final String PATTERN = "^" + ATOM + "+(\\." + ATOM + "+)*@" + DOMAIN + "|" + IP_DOMAIN + ")$"; - private static final Pattern pattern = Pattern.compile(PATTERN, Pattern.CASE_INSENSITIVE); + private static final Pattern pattern = Pattern.compile(PATTERN, Pattern.CASE_INSENSITIVE); - @Override - public void initialize(Email constraintAnnotation) {} + @Override + public void initialize(Email constraintAnnotation) { + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - String asciiString = IDN.toASCII(value.toString()); + String asciiString = IDN.toASCII(value.toString()); - return pattern.matcher(asciiString).matches(); - } + return pattern.matcher(asciiString).matches(); + } } diff --git a/src/main/java/net/helenus/mapping/validator/LengthValidator.java b/src/main/java/net/helenus/mapping/validator/LengthValidator.java index 1b18bcd..dc58b69 100644 --- a/src/main/java/net/helenus/mapping/validator/LengthValidator.java +++ b/src/main/java/net/helenus/mapping/validator/LengthValidator.java @@ -17,26 +17,27 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints.Length; public final class LengthValidator implements ConstraintValidator, SizeConstraint { - int length; + int length; - @Override - public void initialize(Length constraintAnnotation) { - this.length = constraintAnnotation.value(); - } + @Override + public void initialize(Length constraintAnnotation) { + this.length = constraintAnnotation.value(); + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null || size.length == 0) { - return true; - } + if (size == null || size.length == 0) { + return true; + } - return size[0] == length; - } + return size[0] == length; + } } diff --git a/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java b/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java index a05f30f..e5ee50c 100644 --- a/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java +++ b/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java @@ -17,38 +17,39 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class LowerCaseValidator - implements ConstraintValidator { +public final class LowerCaseValidator implements ConstraintValidator { - @Override - public void initialize(Constraints.LowerCase constraintAnnotation) {} + private static boolean isUpperCaseLetter(char ch) { + return ch >= 'A' && ch <= 'Z'; + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public void initialize(Constraints.LowerCase constraintAnnotation) { + } - if (value == null) { - return true; - } + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - final int len = value.length(); - for (int i = 0; i != len; ++i) { - char c = value.charAt(i); - if (c <= 0x7F) { - if (isUpperCaseLetter(c)) { - return false; - } - } - if (c != Character.toLowerCase(c)) { - return false; - } - } + if (value == null) { + return true; + } - return true; - } + final int len = value.length(); + for (int i = 0; i != len; ++i) { + char c = value.charAt(i); + if (c <= 0x7F) { + if (isUpperCaseLetter(c)) { + return false; + } + } + if (c != Character.toLowerCase(c)) { + return false; + } + } - private static boolean isUpperCaseLetter(char ch) { - return ch >= 'A' && ch <= 'Z'; - } + return true; + } } diff --git a/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java b/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java index 31fec70..c30e159 100644 --- a/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java +++ b/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java @@ -17,27 +17,27 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class MaxLengthValidator - implements ConstraintValidator, SizeConstraint { +public final class MaxLengthValidator implements ConstraintValidator, SizeConstraint { - int maxLength; + int maxLength; - @Override - public void initialize(Constraints.MaxLength constraintAnnotation) { - this.maxLength = constraintAnnotation.value(); - } + @Override + public void initialize(Constraints.MaxLength constraintAnnotation) { + this.maxLength = constraintAnnotation.value(); + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null || size.length == 0) { - return true; - } + if (size == null || size.length == 0) { + return true; + } - return size[0] <= maxLength; - } + return size[0] <= maxLength; + } } diff --git a/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java b/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java index f2f3f50..74116df 100644 --- a/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java +++ b/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java @@ -17,27 +17,27 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class MinLengthValidator - implements ConstraintValidator, SizeConstraint { +public final class MinLengthValidator implements ConstraintValidator, SizeConstraint { - int minLength; + int minLength; - @Override - public void initialize(Constraints.MinLength constraintAnnotation) { - this.minLength = constraintAnnotation.value(); - } + @Override + public void initialize(Constraints.MinLength constraintAnnotation) { + this.minLength = constraintAnnotation.value(); + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null || size.length == 0) { - return true; - } + if (size == null || size.length == 0) { + return true; + } - return size[0] >= minLength; - } + return size[0] >= minLength; + } } diff --git a/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java b/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java index a378b61..9c7e03e 100644 --- a/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java +++ b/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java @@ -17,28 +17,29 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; import net.helenus.mapping.annotation.Constraints.NotEmpty; -public final class NotEmptyValidator - implements ConstraintValidator, SizeConstraint { +public final class NotEmptyValidator implements ConstraintValidator, SizeConstraint { - @Override - public void initialize(NotEmpty constraintAnnotation) {} + @Override + public void initialize(NotEmpty constraintAnnotation) { + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null) { - return false; - } + if (size == null) { + return false; + } - if (size.length == 0) { - return true; - } + if (size.length == 0) { + return true; + } - return size[0] > 0; - } + return size[0] > 0; + } } diff --git a/src/main/java/net/helenus/mapping/validator/NotNullValidator.java b/src/main/java/net/helenus/mapping/validator/NotNullValidator.java index 5fc6820..7191e53 100644 --- a/src/main/java/net/helenus/mapping/validator/NotNullValidator.java +++ b/src/main/java/net/helenus/mapping/validator/NotNullValidator.java @@ -17,16 +17,18 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; import net.helenus.mapping.annotation.Constraints.NotNull; public final class NotNullValidator implements ConstraintValidator { - @Override - public void initialize(NotNull constraintAnnotation) {} + @Override + public void initialize(NotNull constraintAnnotation) { + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { - return value != null; - } + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + return value != null; + } } diff --git a/src/main/java/net/helenus/mapping/validator/NumberValidator.java b/src/main/java/net/helenus/mapping/validator/NumberValidator.java index aba6cb5..9a5b06d 100644 --- a/src/main/java/net/helenus/mapping/validator/NumberValidator.java +++ b/src/main/java/net/helenus/mapping/validator/NumberValidator.java @@ -17,34 +17,36 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; public class NumberValidator implements ConstraintValidator { - @Override - public void initialize(Constraints.Number constraintAnnotation) {} + private static boolean isNumber(char ch) { + return ch >= '0' && ch <= '9'; + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public void initialize(Constraints.Number constraintAnnotation) { + } - if (value == null) { - return true; - } + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - final int len = value.length(); - for (int i = 0; i != len; ++i) { + if (value == null) { + return true; + } - char ch = value.charAt(i); + final int len = value.length(); + for (int i = 0; i != len; ++i) { - if (!isNumber(ch)) { - return false; - } - } + char ch = value.charAt(i); - return true; - } + if (!isNumber(ch)) { + return false; + } + } - private static boolean isNumber(char ch) { - return ch >= '0' && ch <= '9'; - } + return true; + } } diff --git a/src/main/java/net/helenus/mapping/validator/PatternValidator.java b/src/main/java/net/helenus/mapping/validator/PatternValidator.java index 5603179..ac768ca 100644 --- a/src/main/java/net/helenus/mapping/validator/PatternValidator.java +++ b/src/main/java/net/helenus/mapping/validator/PatternValidator.java @@ -16,27 +16,28 @@ package net.helenus.mapping.validator; import java.util.regex.Pattern; + import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class PatternValidator - implements ConstraintValidator { +public final class PatternValidator implements ConstraintValidator { - private Pattern pattern; + private Pattern pattern; - @Override - public void initialize(Constraints.Pattern constraintAnnotation) { - pattern = Pattern.compile(constraintAnnotation.value(), constraintAnnotation.flags()); - } + @Override + public void initialize(Constraints.Pattern constraintAnnotation) { + pattern = Pattern.compile(constraintAnnotation.value(), constraintAnnotation.flags()); + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - return pattern.matcher(value).matches(); - } + return pattern.matcher(value).matches(); + } } diff --git a/src/main/java/net/helenus/mapping/validator/SizeConstraint.java b/src/main/java/net/helenus/mapping/validator/SizeConstraint.java index e6ff107..a17f72e 100644 --- a/src/main/java/net/helenus/mapping/validator/SizeConstraint.java +++ b/src/main/java/net/helenus/mapping/validator/SizeConstraint.java @@ -22,38 +22,38 @@ import java.util.Map; public interface SizeConstraint { - static final int[] EMPTY = new int[0]; + static final int[] EMPTY = new int[0]; - default int[] getSize(Object value) { + default int[] getSize(Object value) { - if (value == null) { - return null; - } + if (value == null) { + return null; + } - if (value.getClass().isArray()) { - return new int[] {Array.getLength(value)}; - } + if (value.getClass().isArray()) { + return new int[]{Array.getLength(value)}; + } - if (value instanceof CharSequence) { - CharSequence seq = (CharSequence) value; - return new int[] {seq.length()}; - } + if (value instanceof CharSequence) { + CharSequence seq = (CharSequence) value; + return new int[]{seq.length()}; + } - if (value instanceof ByteBuffer) { - ByteBuffer bb = (ByteBuffer) value; - return new int[] {bb.position()}; - } + if (value instanceof ByteBuffer) { + ByteBuffer bb = (ByteBuffer) value; + return new int[]{bb.position()}; + } - if (value instanceof Collection) { - Collection col = (Collection) value; - return new int[] {col.size()}; - } + if (value instanceof Collection) { + Collection col = (Collection) value; + return new int[]{col.size()}; + } - if (value instanceof Map) { - Map map = (Map) value; - return new int[] {map.size()}; - } + if (value instanceof Map) { + Map map = (Map) value; + return new int[]{map.size()}; + } - return EMPTY; - } + return EMPTY; + } } diff --git a/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java b/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java index 58abff5..e04c6a5 100644 --- a/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java +++ b/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java @@ -17,38 +17,39 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class UpperCaseValidator - implements ConstraintValidator { +public final class UpperCaseValidator implements ConstraintValidator { - @Override - public void initialize(Constraints.UpperCase constraintAnnotation) {} + private static boolean isLowerCaseLetter(char ch) { + return ch >= 'a' && ch <= 'z'; + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public void initialize(Constraints.UpperCase constraintAnnotation) { + } - if (value == null) { - return true; - } + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - final int len = value.length(); - for (int i = 0; i != len; ++i) { - char c = value.charAt(i); - if (c <= 0x7F) { - if (isLowerCaseLetter(c)) { - return false; - } - } - if (c != Character.toUpperCase(c)) { - return false; - } - } + if (value == null) { + return true; + } - return true; - } + final int len = value.length(); + for (int i = 0; i != len; ++i) { + char c = value.charAt(i); + if (c <= 0x7F) { + if (isLowerCaseLetter(c)) { + return false; + } + } + if (c != Character.toUpperCase(c)) { + return false; + } + } - private static boolean isLowerCaseLetter(char ch) { - return ch >= 'a' && ch <= 'z'; - } + return true; + } } diff --git a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java index a87fd15..ae18793 100644 --- a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java @@ -17,31 +17,32 @@ package net.helenus.mapping.value; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; public enum BeanColumnValueProvider implements ColumnValueProvider { - INSTANCE; + INSTANCE; - @Override - public V getColumnValue(Object bean, int columnIndexUnused, HelenusProperty property) { + @Override + public V getColumnValue(Object bean, int columnIndexUnused, HelenusProperty property, boolean immutable) { - Method getter = property.getGetterMethod(); + Method getter = property.getGetterMethod(); - Object value = null; - try { - value = getter.invoke(bean, new Object[] {}); - } catch (InvocationTargetException e) { - if (e.getCause() != null) { - throw new HelenusException("getter threw an exception", e.getCause()); - } - } catch (ReflectiveOperationException e) { - throw new HelenusMappingException("fail to call getter " + getter, e); - } catch (IllegalArgumentException e) { - throw new HelenusMappingException("invalid getter " + getter, e); - } + Object value = null; + try { + value = getter.invoke(bean, new Object[]{}); + } catch (InvocationTargetException e) { + if (e.getCause() != null) { + throw new HelenusException("getter threw an exception", e.getCause()); + } + } catch (ReflectiveOperationException e) { + throw new HelenusMappingException("fail to call getter " + getter, e); + } catch (IllegalArgumentException e) { + throw new HelenusMappingException("invalid getter " + getter, e); + } - return (V) value; - } + return (V) value; + } } diff --git a/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java index 294f63b..d4e0e5e 100644 --- a/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java @@ -18,13 +18,14 @@ package net.helenus.mapping.value; import com.datastax.driver.core.CodecRegistry; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TypeCodec; + import net.helenus.mapping.HelenusProperty; public interface ColumnValuePreparer { - Object prepareColumnValue(Object source, HelenusProperty prop); + Object prepareColumnValue(Object source, HelenusProperty prop); - default TypeCodec codecFor(DataType type) { - return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); - } + default TypeCodec codecFor(DataType type) { + return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); + } } diff --git a/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java index ece28a8..447acbd 100644 --- a/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java @@ -18,13 +18,18 @@ package net.helenus.mapping.value; import com.datastax.driver.core.CodecRegistry; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TypeCodec; + import net.helenus.mapping.HelenusProperty; public interface ColumnValueProvider { - V getColumnValue(Object source, int columnIndex, HelenusProperty property); + V getColumnValue(Object source, int columnIndex, HelenusProperty property, boolean immutable); - default TypeCodec codecFor(DataType type) { - return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); - } + default V getColumnValue(Object source, int columnIndex, HelenusProperty property) { + return getColumnValue(source, columnIndex, property, false); + } + + default TypeCodec codecFor(DataType type) { + return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); + } } diff --git a/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java index 305ec38..33c5db7 100644 --- a/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java @@ -15,109 +15,121 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.*; import java.nio.ByteBuffer; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ProtocolVersion; +import com.datastax.driver.core.Row; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class RowColumnValueProvider implements ColumnValueProvider { - private final SessionRepository repository; + private final SessionRepository repository; - public RowColumnValueProvider(SessionRepository repository) { - this.repository = repository; - } + public RowColumnValueProvider(SessionRepository repository) { + this.repository = repository; + } - @Override - public V getColumnValue(Object sourceObj, int columnIndex, HelenusProperty property) { + @Override + public V getColumnValue(Object sourceObj, int columnIndex, HelenusProperty property, boolean immutable) { - Row source = (Row) sourceObj; + Row source = (Row) sourceObj; - Object value = null; - if (columnIndex != -1) { - value = readValueByIndex(source, columnIndex); - } else { - value = readValueByName(source, property.getColumnName().getName()); - } + Object value = null; + if (columnIndex != -1) { + value = readValueByIndex(source, columnIndex, immutable); + } else { + value = readValueByName(source, property.getColumnName().getName(), immutable); + } - if (value != null) { + if (value != null) { - Optional> converter = property.getReadConverter(repository); + Optional> converter = property.getReadConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return (V) value; - } + return (V) value; + } - private Object readValueByIndex(Row source, int columnIndex) { + private Object readValueByIndex(Row source, int columnIndex, boolean immutable) { - if (source.isNull(columnIndex)) { - return null; - } + if (source.isNull(columnIndex)) { + return null; + } - ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); + ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); - DataType columnType = columnDefinitions.getType(columnIndex); + DataType columnType = columnDefinitions.getType(columnIndex); - if (columnType.isCollection()) { + if (columnType.isCollection()) { - List typeArguments = columnType.getTypeArguments(); + List typeArguments = columnType.getTypeArguments(); - switch (columnType.getName()) { - case SET: - return source.getSet(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); - case MAP: - return source.getMap( - columnIndex, - codecFor(typeArguments.get(0)).getJavaType(), - codecFor(typeArguments.get(1)).getJavaType()); - case LIST: - return source.getList(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); - } - } + switch (columnType.getName()) { + case SET : + Set set = source.getSet(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableSet.copyOf(set) : set; + case MAP : + Map map = source.getMap(columnIndex, codecFor(typeArguments.get(0)).getJavaType(), + codecFor(typeArguments.get(1)).getJavaType()); + return immutable ? ImmutableMap.copyOf(map) : map; + case LIST : + List list = source.getList(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableList.copyOf(list) : list; + } + } - ByteBuffer bytes = source.getBytesUnsafe(columnIndex); - Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + ByteBuffer bytes = source.getBytesUnsafe(columnIndex); + Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - return value; - } + return value; + } - private Object readValueByName(Row source, String columnName) { + private Object readValueByName(Row source, String columnName, boolean immutable) { - if (source.isNull(columnName)) { - return null; - } + if (source.isNull(columnName)) { + return null; + } - ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); + ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); - DataType columnType = columnDefinitions.getType(columnName); + DataType columnType = columnDefinitions.getType(columnName); - if (columnType.isCollection()) { + if (columnType.isCollection()) { - List typeArguments = columnType.getTypeArguments(); + List typeArguments = columnType.getTypeArguments(); - switch (columnType.getName()) { - case SET: - return source.getSet(columnName, codecFor(typeArguments.get(0)).getJavaType()); - case MAP: - return source.getMap( - columnName, - codecFor(typeArguments.get(0)).getJavaType(), - codecFor(typeArguments.get(1)).getJavaType()); - case LIST: - return source.getList(columnName, codecFor(typeArguments.get(0)).getJavaType()); - } - } + switch (columnType.getName()) { + case SET : + Set set = source.getSet(columnName, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableSet.copyOf(set) : set; + case MAP : + Map map = source.getMap(columnName, codecFor(typeArguments.get(0)).getJavaType(), + codecFor(typeArguments.get(1)).getJavaType()); + return immutable ? ImmutableMap.copyOf(map) : map; + case LIST : + List list = source.getList(columnName, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableList.copyOf(list) : list; + } + } - ByteBuffer bytes = source.getBytesUnsafe(columnName); - Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + ByteBuffer bytes = source.getBytesUnsafe(columnName); + Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - return value; - } + return value; + } } diff --git a/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java index 447431f..1e32b8b 100644 --- a/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java @@ -15,41 +15,44 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.querybuilder.BindMarker; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.querybuilder.BindMarker; + import net.helenus.core.HelenusValidator; import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class StatementColumnValuePreparer implements ColumnValuePreparer { - private final SessionRepository repository; + private final SessionRepository repository; - public StatementColumnValuePreparer(SessionRepository repository) { - this.repository = repository; - } + public StatementColumnValuePreparer(SessionRepository repository) { + this.repository = repository; + } - @Override - public Object prepareColumnValue(Object value, HelenusProperty prop) { + @Override + public Object prepareColumnValue(Object value, HelenusProperty prop) { - if (value == null) return null; + if (value == null) + return null; - if (value instanceof BindMarker) { - return value; - } + if (value instanceof BindMarker) { + return value; + } - HelenusValidator.INSTANCE.validate(prop, value); + HelenusValidator.INSTANCE.validate(prop, value); - if (value != null) { + if (value != null) { - Optional> converter = prop.getWriteConverter(repository); + Optional> converter = prop.getWriteConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return value; - } + return value; + } } diff --git a/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java index 35b13aa..552b425 100644 --- a/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java @@ -15,48 +15,52 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.*; -import com.datastax.driver.core.querybuilder.BindMarker; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ProtocolVersion; +import com.datastax.driver.core.TupleType; +import com.datastax.driver.core.querybuilder.BindMarker; + import net.helenus.core.HelenusValidator; import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class TupleColumnValuePreparer implements ColumnValuePreparer { - private final TupleType tupleType; - private final SessionRepository repository; + private final TupleType tupleType; + private final SessionRepository repository; - public TupleColumnValuePreparer(TupleType tupleType, SessionRepository repository) { - this.tupleType = tupleType; - this.repository = repository; - } + public TupleColumnValuePreparer(TupleType tupleType, SessionRepository repository) { + this.tupleType = tupleType; + this.repository = repository; + } - @Override - public Object prepareColumnValue(Object value, HelenusProperty prop) { + @Override + public Object prepareColumnValue(Object value, HelenusProperty prop) { - if (value instanceof BindMarker) { - return value; - } + if (value instanceof BindMarker) { + return value; + } - HelenusValidator.INSTANCE.validate(prop, value); + HelenusValidator.INSTANCE.validate(prop, value); - if (value != null) { + if (value != null) { - Optional> converter = prop.getWriteConverter(repository); + Optional> converter = prop.getWriteConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } - int columnIndex = prop.getOrdinal(); + int columnIndex = prop.getOrdinal(); - DataType dataType = tupleType.getComponentTypes().get(columnIndex); + DataType dataType = tupleType.getComponentTypes().get(columnIndex); - return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); - } + return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); + } - return null; - } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java index c6e8e2e..d005884 100644 --- a/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java @@ -15,50 +15,52 @@ */ package net.helenus.mapping.value; +import java.nio.ByteBuffer; +import java.util.Optional; +import java.util.function.Function; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.ProtocolVersion; import com.datastax.driver.core.TupleType; import com.datastax.driver.core.TupleValue; -import java.nio.ByteBuffer; -import java.util.Optional; -import java.util.function.Function; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class TupleColumnValueProvider implements ColumnValueProvider { - private final SessionRepository repository; + private final SessionRepository repository; - public TupleColumnValueProvider(SessionRepository repository) { - this.repository = repository; - } + public TupleColumnValueProvider(SessionRepository repository) { + this.repository = repository; + } - @Override - public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property) { + @Override + public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { - int columnIndex = property.getOrdinal(); + int columnIndex = property.getOrdinal(); - TupleValue source = (TupleValue) sourceObj; + TupleValue source = (TupleValue) sourceObj; - ByteBuffer bytes = source.getBytesUnsafe(columnIndex); - if (bytes == null) { - return null; - } + ByteBuffer bytes = source.getBytesUnsafe(columnIndex); + if (bytes == null) { + return null; + } - TupleType tupleType = source.getType(); - DataType fieldType = tupleType.getComponentTypes().get(columnIndex); + TupleType tupleType = source.getType(); + DataType fieldType = tupleType.getComponentTypes().get(columnIndex); - Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - if (value != null) { + if (value != null) { - Optional> converter = property.getReadConverter(repository); + Optional> converter = property.getReadConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return (V) value; - } + return (V) value; + } } diff --git a/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java index ce177a6..1ff5b2c 100644 --- a/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java @@ -15,46 +15,50 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.*; -import com.datastax.driver.core.querybuilder.BindMarker; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ProtocolVersion; +import com.datastax.driver.core.UserType; +import com.datastax.driver.core.querybuilder.BindMarker; + import net.helenus.core.HelenusValidator; import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class UDTColumnValuePreparer implements ColumnValuePreparer { - private final UserType userType; - private final SessionRepository repository; + private final UserType userType; + private final SessionRepository repository; - public UDTColumnValuePreparer(UserType userType, SessionRepository repository) { - this.userType = userType; - this.repository = repository; - } + public UDTColumnValuePreparer(UserType userType, SessionRepository repository) { + this.userType = userType; + this.repository = repository; + } - @Override - public Object prepareColumnValue(Object value, HelenusProperty prop) { + @Override + public Object prepareColumnValue(Object value, HelenusProperty prop) { - if (value instanceof BindMarker) { - return value; - } + if (value instanceof BindMarker) { + return value; + } - HelenusValidator.INSTANCE.validate(prop, value); + HelenusValidator.INSTANCE.validate(prop, value); - if (value != null) { + if (value != null) { - Optional> converter = prop.getWriteConverter(repository); + Optional> converter = prop.getWriteConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } - DataType dataType = userType.getFieldType(prop.getColumnName().getName()); + DataType dataType = userType.getFieldType(prop.getColumnName().getName()); - return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); - } + return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); + } - return null; - } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java index 5b617b0..13474d3 100644 --- a/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java @@ -15,51 +15,53 @@ */ package net.helenus.mapping.value; +import java.nio.ByteBuffer; +import java.util.Optional; +import java.util.function.Function; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.ProtocolVersion; import com.datastax.driver.core.UDTValue; import com.datastax.driver.core.UserType; -import java.nio.ByteBuffer; -import java.util.Optional; -import java.util.function.Function; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class UDTColumnValueProvider implements ColumnValueProvider { - private final SessionRepository repository; + private final SessionRepository repository; - public UDTColumnValueProvider(SessionRepository repository) { - this.repository = repository; - } + public UDTColumnValueProvider(SessionRepository repository) { + this.repository = repository; + } - @Override - @SuppressWarnings("unchecked") - public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property) { + @Override + @SuppressWarnings("unchecked") + public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { - UDTValue source = (UDTValue) sourceObj; + UDTValue source = (UDTValue) sourceObj; - UserType userType = source.getType(); + UserType userType = source.getType(); - String name = property.getColumnName().getName(); + String name = property.getColumnName().getName(); - ByteBuffer bytes = source.getBytesUnsafe(name); - if (bytes == null) { - return null; - } + ByteBuffer bytes = source.getBytesUnsafe(name); + if (bytes == null) { + return null; + } - DataType fieldType = userType.getFieldType(name); - Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + DataType fieldType = userType.getFieldType(name); + Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - if (value != null) { + if (value != null) { - Optional> converter = property.getReadConverter(repository); + Optional> converter = property.getReadConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return (V) value; - } + return (V) value; + } } diff --git a/src/main/java/net/helenus/mapping/value/ValueProviderMap.java b/src/main/java/net/helenus/mapping/value/ValueProviderMap.java index bd04eb2..562acca 100644 --- a/src/main/java/net/helenus/mapping/value/ValueProviderMap.java +++ b/src/main/java/net/helenus/mapping/value/ValueProviderMap.java @@ -19,111 +19,126 @@ import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; + +import net.helenus.core.reflect.Drafted; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusMappingException; public final class ValueProviderMap implements Map { - private final Object source; - private final ColumnValueProvider valueProvider; - private final HelenusEntity entity; + private final Object source; + private final ColumnValueProvider valueProvider; + private final HelenusEntity entity; + private final boolean immutable; - public ValueProviderMap(Object source, ColumnValueProvider valueProvider, HelenusEntity entity) { - this.source = source; - this.valueProvider = valueProvider; - this.entity = entity; - } + public ValueProviderMap(Object source, ColumnValueProvider valueProvider, HelenusEntity entity) { + this.source = source; + this.valueProvider = valueProvider; + this.entity = entity; + this.immutable = entity.getMappingInterface().isAssignableFrom(Drafted.class); + } - @Override - public Object get(Object key) { - if (key instanceof String) { - String name = (String) key; - HelenusProperty prop = entity.getProperty(name); - if (prop != null) { - return valueProvider.getColumnValue(source, -1, prop); - } - } - return null; - } + @Override + public Object get(Object key) { + if (key instanceof String) { + String name = (String) key; + HelenusProperty prop = entity.getProperty(name); + if (prop != null) { + return valueProvider.getColumnValue(source, -1, prop, immutable); + } + } + return null; + } - @Override - public Set keySet() { - return entity - .getOrderedProperties() - .stream() - .map(p -> p.getPropertyName()) - .collect(Collectors.toSet()); - } + @Override + public Set keySet() { + return entity.getOrderedProperties().stream().map(p -> p.getPropertyName()).collect(Collectors.toSet()); + } - @Override - public int size() { - return entity.getOrderedProperties().size(); - } + @Override + public int size() { + return entity.getOrderedProperties().size(); + } - @Override - public boolean isEmpty() { - return entity.getOrderedProperties().size() > 0; - } + @Override + public boolean isEmpty() { + return entity.getOrderedProperties().size() > 0; + } - @Override - public boolean containsKey(Object key) { - if (key instanceof Object) { - String s = (String) key; - return keySet().contains(s); - } - return false; - } + @Override + public boolean containsKey(Object key) { + if (key instanceof Object) { + String s = (String) key; + return keySet().contains(s); + } + return false; + } - @Override - public boolean containsValue(Object value) { - throwShouldNeverCall("containsValue()"); - return false; - } + @Override + public boolean containsValue(Object value) { + throwShouldNeverCall("containsValue()"); + return false; + } - @Override - public Object put(String key, Object value) { - throwShouldNeverCall("put()"); - return null; - } + @Override + public Object put(String key, Object value) { + throwShouldNeverCall("put()"); + return null; + } - @Override - public Object remove(Object key) { - throwShouldNeverCall("remove()"); - return null; - } + @Override + public Object remove(Object key) { + throwShouldNeverCall("remove()"); + return null; + } - @Override - public void putAll(Map m) { - throwShouldNeverCall("putAll()"); - } + @Override + public void putAll(Map m) { + throwShouldNeverCall("putAll()"); + } - @Override - public void clear() { - throwShouldNeverCall("clear()"); - } + @Override + public void clear() { + throwShouldNeverCall("clear()"); + } - @Override - public Collection values() { - throwShouldNeverCall("values()"); - return null; - } + @Override + public Collection values() { + throwShouldNeverCall("values()"); + return null; + } - @Override - public Set> entrySet() { - throwShouldNeverCall("entrySet()"); - return null; - } + @Override + public Set> entrySet() { + throwShouldNeverCall("entrySet()"); + return null; + } - private void throwShouldNeverCall(String methodName) { - throw new HelenusMappingException( - String.format( - "the method {} should never be called on an instance of a Helenus ValueProviderMap", - methodName)); - } + private void throwShouldNeverCall(String methodName) { + throw new HelenusMappingException(String.format( + "the method {} should never be called on an instance of a Helenus ValueProviderMap", methodName)); + } - @Override - public String toString() { - return source.toString(); - } + @Override + public String toString() { + return source.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || (!o.getClass().isAssignableFrom(Map.class) && getClass() != o.getClass())) + return false; + + Map that = (Map) o; + if (this.size() != that.size()) + return false; + for (String key : this.keySet()) + if (!this.get(key).equals(that.get(key))) + return false; + + return true; + } } diff --git a/src/main/java/net/helenus/support/CqlUtil.java b/src/main/java/net/helenus/support/CqlUtil.java index 5598af4..7de2dad 100644 --- a/src/main/java/net/helenus/support/CqlUtil.java +++ b/src/main/java/net/helenus/support/CqlUtil.java @@ -17,17 +17,18 @@ package net.helenus.support; public final class CqlUtil { - private CqlUtil() {} + private CqlUtil() { + } - public static String forceQuote(String identity) { + public static String forceQuote(String identity) { - if (identity == null) { - return null; - } + if (identity == null) { + return null; + } - if (identity.startsWith("\"")) { - return identity; - } - return "\"" + identity + "\""; - } + if (identity.startsWith("\"")) { + return identity; + } + return "\"" + identity + "\""; + } } diff --git a/src/main/java/net/helenus/support/DslPropertyException.java b/src/main/java/net/helenus/support/DslPropertyException.java index 91cce07..a62a831 100644 --- a/src/main/java/net/helenus/support/DslPropertyException.java +++ b/src/main/java/net/helenus/support/DslPropertyException.java @@ -19,16 +19,16 @@ import net.helenus.core.reflect.HelenusPropertyNode; public final class DslPropertyException extends HelenusException { - private static final long serialVersionUID = -2745598205929757758L; + private static final long serialVersionUID = -2745598205929757758L; - private final HelenusPropertyNode propertyNode; + private final HelenusPropertyNode propertyNode; - public DslPropertyException(HelenusPropertyNode propertyNode) { - super("DSL PropertyNode Exception"); - this.propertyNode = propertyNode; - } + public DslPropertyException(HelenusPropertyNode propertyNode) { + super("DSL PropertyNode Exception"); + this.propertyNode = propertyNode; + } - public HelenusPropertyNode getPropertyNode() { - return propertyNode; - } + public HelenusPropertyNode getPropertyNode() { + return propertyNode; + } } diff --git a/src/main/java/net/helenus/support/Either.java b/src/main/java/net/helenus/support/Either.java index 88d3dfc..ae87cd2 100644 --- a/src/main/java/net/helenus/support/Either.java +++ b/src/main/java/net/helenus/support/Either.java @@ -19,62 +19,62 @@ import java.util.function.Function; public final class Either { - private final L left; - private final R right; + private final L left; + private final R right; - private Either(L left, R right) { - this.left = left; - this.right = right; - } + private Either(L left, R right) { + this.left = left; + this.right = right; + } - public boolean isLeft() { - return left != null; - } + public static Either left(L left) { + return new Either(left, null); + } - public L getLeft() { - return left; - } + public static Either right(R right) { + return new Either(null, right); + } - public boolean isRight() { - return right != null; - } + public boolean isLeft() { + return left != null; + } - public R getRight() { - return right; - } + public L getLeft() { + return left; + } - public static Either left(L left) { - return new Either(left, null); - } + public boolean isRight() { + return right != null; + } - public static Either right(R right) { - return new Either(null, right); - } + public R getRight() { + return right; + } - public EitherCase getCase() { - if (left != null) { - return EitherCase.LEFT; - } else if (right != null) { - return EitherCase.RIGHT; - } - throw new IllegalStateException("unexpected state"); - } + public EitherCase getCase() { + if (left != null) { + return EitherCase.LEFT; + } else if (right != null) { + return EitherCase.RIGHT; + } + throw new IllegalStateException("unexpected state"); + } - public T fold(Function leftFunction, Function rightFunction) { - switch (getCase()) { - case LEFT: - return leftFunction.apply(left); - case RIGHT: - return rightFunction.apply(right); - } - throw new IllegalStateException("unexpected state"); - } + public T fold(Function leftFunction, Function rightFunction) { + switch (getCase()) { + case LEFT : + return leftFunction.apply(left); + case RIGHT : + return rightFunction.apply(right); + } + throw new IllegalStateException("unexpected state"); + } - @Override - public String toString() { - if (left != null) { - return "[" + left + ",]"; - } - return "[," + right + "]"; - } + @Override + public String toString() { + if (left != null) { + return "[" + left + ",]"; + } + return "[," + right + "]"; + } } diff --git a/src/main/java/net/helenus/support/EitherCase.java b/src/main/java/net/helenus/support/EitherCase.java index 19db08c..9ca0db1 100644 --- a/src/main/java/net/helenus/support/EitherCase.java +++ b/src/main/java/net/helenus/support/EitherCase.java @@ -16,6 +16,5 @@ package net.helenus.support; public enum EitherCase { - LEFT, - RIGHT; + LEFT, RIGHT; } diff --git a/src/main/java/net/helenus/support/Fun.java b/src/main/java/net/helenus/support/Fun.java index 722cca4..aa3c896 100644 --- a/src/main/java/net/helenus/support/Fun.java +++ b/src/main/java/net/helenus/support/Fun.java @@ -19,219 +19,193 @@ import java.util.Arrays; public final class Fun { - private Fun() {} + private Fun() { + } - public static final class ArrayTuple { + public static final class ArrayTuple { - public final Object[] _a; + public final Object[] _a; - public ArrayTuple(Object[] a) { - this._a = a; - } + public ArrayTuple(Object[] a) { + this._a = a; + } - public static ArrayTuple of(Object[] a) { - return new ArrayTuple(a); - } + public static ArrayTuple of(Object[] a) { + return new ArrayTuple(a); + } - @Override - public String toString() { - return "ArrayTuple " + Arrays.toString(_a); - } - } + @Override + public String toString() { + return "ArrayTuple " + Arrays.toString(_a); + } + } - public static final class Tuple1 { + public static final class Tuple1 { - public final A _1; + public final A _1; - public Tuple1(A v1) { - this._1 = v1; - } + public Tuple1(A v1) { + this._1 = v1; + } - public static Tuple1 of(A _1) { - return new Tuple1(_1); - } + public static Tuple1 of(A _1) { + return new Tuple1(_1); + } - @Override - public String toString() { - return "Tuple1 [_1=" + _1 + "]"; - } - } + @Override + public String toString() { + return "Tuple1 [_1=" + _1 + "]"; + } + } - public static final class Tuple2 { + public static final class Tuple2 { - public final A _1; - public final B _2; + public final A _1; + public final B _2; - public Tuple2(A v1, B v2) { - this._1 = v1; - this._2 = v2; - } + public Tuple2(A v1, B v2) { + this._1 = v1; + this._2 = v2; + } - public static Tuple2 of(A _1, B _2) { - return new Tuple2(_1, _2); - } + public static Tuple2 of(A _1, B _2) { + return new Tuple2(_1, _2); + } - @Override - public String toString() { - return "Tuple2 [_1=" + _1 + ", _2=" + _2 + "]"; - } - } + @Override + public String toString() { + return "Tuple2 [_1=" + _1 + ", _2=" + _2 + "]"; + } + } - public static final class Tuple3 { + public static final class Tuple3 { - public final A _1; - public final B _2; - public final C _3; + public final A _1; + public final B _2; + public final C _3; - public Tuple3(A v1, B v2, C v3) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - } + public Tuple3(A v1, B v2, C v3) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + } - public static Tuple3 of(A _1, B _2, C _3) { - return new Tuple3(_1, _2, _3); - } + public static Tuple3 of(A _1, B _2, C _3) { + return new Tuple3(_1, _2, _3); + } - @Override - public String toString() { - return "Tuple3 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + "]"; - } - } + @Override + public String toString() { + return "Tuple3 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + "]"; + } + } - public static final class Tuple4 { + public static final class Tuple4 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; + public final A _1; + public final B _2; + public final C _3; + public final D _4; - public Tuple4(A v1, B v2, C v3, D v4) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - } + public Tuple4(A v1, B v2, C v3, D v4) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + } - public static Tuple4 of(A _1, B _2, C _3, D _4) { - return new Tuple4(_1, _2, _3, _4); - } + public static Tuple4 of(A _1, B _2, C _3, D _4) { + return new Tuple4(_1, _2, _3, _4); + } - @Override - public String toString() { - return "Tuple4 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + "]"; - } - } + @Override + public String toString() { + return "Tuple4 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + "]"; + } + } - public static final class Tuple5 { + public static final class Tuple5 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; - public final E _5; + public final A _1; + public final B _2; + public final C _3; + public final D _4; + public final E _5; - public Tuple5(A v1, B v2, C v3, D v4, E v5) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - this._5 = v5; - } + public Tuple5(A v1, B v2, C v3, D v4, E v5) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + this._5 = v5; + } - public static Tuple5 of(A _1, B _2, C _3, D _4, E _5) { - return new Tuple5(_1, _2, _3, _4, _5); - } + public static Tuple5 of(A _1, B _2, C _3, D _4, E _5) { + return new Tuple5(_1, _2, _3, _4, _5); + } - @Override - public String toString() { - return "Tuple5 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + "]"; - } - } + @Override + public String toString() { + return "Tuple5 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + "]"; + } + } - public static final class Tuple6 { + public static final class Tuple6 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; - public final E _5; - public final F _6; + public final A _1; + public final B _2; + public final C _3; + public final D _4; + public final E _5; + public final F _6; - public Tuple6(A v1, B v2, C v3, D v4, E v5, F v6) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - this._5 = v5; - this._6 = v6; - } + public Tuple6(A v1, B v2, C v3, D v4, E v5, F v6) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + this._5 = v5; + this._6 = v6; + } - public static Tuple6 of( - A _1, B _2, C _3, D _4, E _5, F _6) { - return new Tuple6(_1, _2, _3, _4, _5, _6); - } + public static Tuple6 of(A _1, B _2, C _3, D _4, E _5, F _6) { + return new Tuple6(_1, _2, _3, _4, _5, _6); + } - @Override - public String toString() { - return "Tuple6 [_1=" - + _1 - + ", _2=" - + _2 - + ", _3=" - + _3 - + ", _4=" - + _4 - + ", _5=" - + _5 - + ", _6=" - + _6 - + "]"; - } - } + @Override + public String toString() { + return "Tuple6 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + ", _6=" + _6 + "]"; + } + } - public static final class Tuple7 { + public static final class Tuple7 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; - public final E _5; - public final F _6; - public final G _7; + public final A _1; + public final B _2; + public final C _3; + public final D _4; + public final E _5; + public final F _6; + public final G _7; - public Tuple7(A v1, B v2, C v3, D v4, E v5, F v6, G v7) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - this._5 = v5; - this._6 = v6; - this._7 = v7; - } + public Tuple7(A v1, B v2, C v3, D v4, E v5, F v6, G v7) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + this._5 = v5; + this._6 = v6; + this._7 = v7; + } - public static Tuple7 of( - A _1, B _2, C _3, D _4, E _5, F _6, G _7) { - return new Tuple7(_1, _2, _3, _4, _5, _6, _7); - } + public static Tuple7 of(A _1, B _2, C _3, D _4, E _5, F _6, G _7) { + return new Tuple7(_1, _2, _3, _4, _5, _6, _7); + } - @Override - public String toString() { - return "Tuple7 [_1=" - + _1 - + ", _2=" - + _2 - + ", _3=" - + _3 - + ", _4=" - + _4 - + ", _5=" - + _5 - + ", _6=" - + _6 - + ", _7=" - + _7 - + "]"; - } - } + @Override + public String toString() { + return "Tuple7 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + ", _6=" + _6 + + ", _7=" + _7 + "]"; + } + } } diff --git a/src/main/java/net/helenus/support/HelenusException.java b/src/main/java/net/helenus/support/HelenusException.java index 9fb613e..2777e8e 100644 --- a/src/main/java/net/helenus/support/HelenusException.java +++ b/src/main/java/net/helenus/support/HelenusException.java @@ -17,17 +17,17 @@ package net.helenus.support; public class HelenusException extends RuntimeException { - private static final long serialVersionUID = 7711799134283942588L; + private static final long serialVersionUID = 7711799134283942588L; - public HelenusException(String msg) { - super(msg); - } + public HelenusException(String msg) { + super(msg); + } - public HelenusException(Throwable t) { - super(t); - } + public HelenusException(Throwable t) { + super(t); + } - public HelenusException(String msg, Throwable t) { - super(msg, t); - } + public HelenusException(String msg, Throwable t) { + super(msg, t); + } } diff --git a/src/main/java/net/helenus/support/HelenusMappingException.java b/src/main/java/net/helenus/support/HelenusMappingException.java index 92d80e2..2284775 100644 --- a/src/main/java/net/helenus/support/HelenusMappingException.java +++ b/src/main/java/net/helenus/support/HelenusMappingException.java @@ -17,17 +17,17 @@ package net.helenus.support; public class HelenusMappingException extends HelenusException { - private static final long serialVersionUID = -4730562130753392363L; + private static final long serialVersionUID = -4730562130753392363L; - public HelenusMappingException(String msg) { - super(msg); - } + public HelenusMappingException(String msg) { + super(msg); + } - public HelenusMappingException(Throwable t) { - super(t); - } + public HelenusMappingException(Throwable t) { + super(t); + } - public HelenusMappingException(String msg, Throwable t) { - super(msg, t); - } + public HelenusMappingException(String msg, Throwable t) { + super(msg, t); + } } diff --git a/src/main/java/net/helenus/support/Immutables.java b/src/main/java/net/helenus/support/Immutables.java index d008b42..841d80a 100644 --- a/src/main/java/net/helenus/support/Immutables.java +++ b/src/main/java/net/helenus/support/Immutables.java @@ -19,349 +19,348 @@ import java.util.*; public final class Immutables { - private Immutables() {} - - public static Set setOf(T value) { - return new SingleEntrySet(value); - } - - public static List listOf(T value) { - return new SingleEntryList(value); - } - - public static Map mapOf(K key, V value) { - return new SingleEntryMap(key, value); - } - - static class SingleEntryIterator implements Iterator { - - T entry; - boolean processed = false; - - SingleEntryIterator(T entry) { - this.entry = entry; - } - - @Override - public boolean hasNext() { - return !processed; - } - - @Override - public T next() { - processed = true; - return entry; - } - } - - static class SingleEntryListIterator extends SingleEntryIterator - implements ListIterator { - - SingleEntryListIterator(T entry) { - super(entry); - } - - @Override - public boolean hasPrevious() { - return processed; - } - - @Override - public T previous() { - processed = false; - return entry; - } - - @Override - public int nextIndex() { - return processed ? 1 : 0; - } - - @Override - public int previousIndex() { - return processed ? 0 : -1; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public void set(T e) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(T e) { - throw new UnsupportedOperationException(); - } - } - - static class SingleEntryCollection implements Collection { - - final T entry; - - SingleEntryCollection(T entry) { - this.entry = entry; - } - - @Override - public int size() { - return 1; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object o) { - if (entry == null) { - return o == null; - } - return entry.equals(o); - } - - @Override - public Iterator iterator() { - return new SingleEntryIterator(entry); - } - - @Override - public Object[] toArray() { - return new Object[] {entry}; - } - - @Override - public V[] toArray(V[] a) { - if (a.length != 1) { - a = Arrays.copyOf(a, 1); - } - a[0] = (V) entry; - return a; - } - - @Override - public boolean add(T e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsAll(Collection c) { - int size = c.size(); - if (size != 1) { - return false; - } - for (Object o : c) { - return contains(o); - } - return false; - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - } - - static final class SingleEntrySet extends SingleEntryCollection implements Set { - - SingleEntrySet(T entry) { - super(entry); - } - } - - static final class SingleEntryList extends SingleEntryCollection implements List { - - SingleEntryList(T entry) { - super(entry); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public T get(int index) { - if (index == 0) { - return entry; - } - throw new IndexOutOfBoundsException(); - } - - @Override - public T set(int index, T element) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(int index, T element) { - throw new UnsupportedOperationException(); - } - - @Override - public T remove(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public int indexOf(Object o) { - return contains(o) ? 0 : -1; - } - - @Override - public int lastIndexOf(Object o) { - return contains(o) ? 0 : -1; - } - - @Override - public ListIterator listIterator() { - return new SingleEntryListIterator(entry); - } - - @Override - public ListIterator listIterator(int index) { - if (index != 0) { - throw new IndexOutOfBoundsException(); - } - return listIterator(); - } - - @Override - public List subList(int fromIndex, int toIndex) { - if (fromIndex == 0) { - if (toIndex == 0) { - return Collections.emptyList(); - } else if (toIndex == 1) { - return this; - } else { - throw new IndexOutOfBoundsException(); - } - } else if (fromIndex == 1 && toIndex == 1) { - return Collections.emptyList(); - } else { - throw new IndexOutOfBoundsException(); - } - } - } - - static final class SingleEntryMap implements Map { - - final K key; - final V value; - - SingleEntryMap(K key, V value) { - this.key = key; - this.value = value; - } - - @Override - public int size() { - return 1; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean containsKey(Object key) { - if (this.key == null) { - return key == null; - } - return this.key.equals(key); - } - - @Override - public boolean containsValue(Object value) { - if (this.value == null) { - return value == null; - } - return this.value.equals(value); - } - - @Override - public V get(Object key) { - if (this.key == null) { - return key == null ? this.value : null; - } - return this.key.equals(key) ? this.value : null; - } - - @Override - public V put(K key, V value) { - throw new UnsupportedOperationException(); - } - - @Override - public V remove(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public void putAll(Map m) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public Set keySet() { - return new SingleEntrySet(this.key); - } - - @Override - public Collection values() { - return new SingleEntrySet(this.value); - } - - @Override - public Set> entrySet() { - return new SingleEntrySet>( - new Map.Entry() { - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return value; - } - - @Override - public V setValue(V value) { - throw new UnsupportedOperationException(); - } - }); - } - } + private Immutables() { + } + + public static Set setOf(T value) { + return new SingleEntrySet(value); + } + + public static List listOf(T value) { + return new SingleEntryList(value); + } + + public static Map mapOf(K key, V value) { + return new SingleEntryMap(key, value); + } + + static class SingleEntryIterator implements Iterator { + + T entry; + boolean processed = false; + + SingleEntryIterator(T entry) { + this.entry = entry; + } + + @Override + public boolean hasNext() { + return !processed; + } + + @Override + public T next() { + processed = true; + return entry; + } + } + + static class SingleEntryListIterator extends SingleEntryIterator implements ListIterator { + + SingleEntryListIterator(T entry) { + super(entry); + } + + @Override + public boolean hasPrevious() { + return processed; + } + + @Override + public T previous() { + processed = false; + return entry; + } + + @Override + public int nextIndex() { + return processed ? 1 : 0; + } + + @Override + public int previousIndex() { + return processed ? 0 : -1; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void set(T e) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(T e) { + throw new UnsupportedOperationException(); + } + } + + static class SingleEntryCollection implements Collection { + + final T entry; + + SingleEntryCollection(T entry) { + this.entry = entry; + } + + @Override + public int size() { + return 1; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + if (entry == null) { + return o == null; + } + return entry.equals(o); + } + + @Override + public Iterator iterator() { + return new SingleEntryIterator(entry); + } + + @Override + public Object[] toArray() { + return new Object[]{entry}; + } + + @Override + public V[] toArray(V[] a) { + if (a.length != 1) { + a = Arrays.copyOf(a, 1); + } + a[0] = (V) entry; + return a; + } + + @Override + public boolean add(T e) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsAll(Collection c) { + int size = c.size(); + if (size != 1) { + return false; + } + for (Object o : c) { + return contains(o); + } + return false; + } + + @Override + public boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + } + + static final class SingleEntrySet extends SingleEntryCollection implements Set { + + SingleEntrySet(T entry) { + super(entry); + } + } + + static final class SingleEntryList extends SingleEntryCollection implements List { + + SingleEntryList(T entry) { + super(entry); + } + + @Override + public boolean addAll(int index, Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public T get(int index) { + if (index == 0) { + return entry; + } + throw new IndexOutOfBoundsException(); + } + + @Override + public T set(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public T remove(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public int indexOf(Object o) { + return contains(o) ? 0 : -1; + } + + @Override + public int lastIndexOf(Object o) { + return contains(o) ? 0 : -1; + } + + @Override + public ListIterator listIterator() { + return new SingleEntryListIterator(entry); + } + + @Override + public ListIterator listIterator(int index) { + if (index != 0) { + throw new IndexOutOfBoundsException(); + } + return listIterator(); + } + + @Override + public List subList(int fromIndex, int toIndex) { + if (fromIndex == 0) { + if (toIndex == 0) { + return Collections.emptyList(); + } else if (toIndex == 1) { + return this; + } else { + throw new IndexOutOfBoundsException(); + } + } else if (fromIndex == 1 && toIndex == 1) { + return Collections.emptyList(); + } else { + throw new IndexOutOfBoundsException(); + } + } + } + + static final class SingleEntryMap implements Map { + + final K key; + final V value; + + SingleEntryMap(K key, V value) { + this.key = key; + this.value = value; + } + + @Override + public int size() { + return 1; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean containsKey(Object key) { + if (this.key == null) { + return key == null; + } + return this.key.equals(key); + } + + @Override + public boolean containsValue(Object value) { + if (this.value == null) { + return value == null; + } + return this.value.equals(value); + } + + @Override + public V get(Object key) { + if (this.key == null) { + return key == null ? this.value : null; + } + return this.key.equals(key) ? this.value : null; + } + + @Override + public V put(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public Set keySet() { + return new SingleEntrySet(this.key); + } + + @Override + public Collection values() { + return new SingleEntrySet(this.value); + } + + @Override + public Set> entrySet() { + return new SingleEntrySet>(new Map.Entry() { + + @Override + public K getKey() { + return key; + } + + @Override + public V getValue() { + return value; + } + + @Override + public V setValue(V value) { + throw new UnsupportedOperationException(); + } + }); + } + } } diff --git a/src/main/java/net/helenus/support/Mutable.java b/src/main/java/net/helenus/support/Mutable.java index 622b1d3..9a44d99 100644 --- a/src/main/java/net/helenus/support/Mutable.java +++ b/src/main/java/net/helenus/support/Mutable.java @@ -17,17 +17,17 @@ package net.helenus.support; public final class Mutable { - private volatile T value; + private volatile T value; - public Mutable(T initialValue) { - this.value = initialValue; - } + public Mutable(T initialValue) { + this.value = initialValue; + } - public T get() { - return value; - } + public T get() { + return value; + } - public void set(T value) { - this.value = value; - } + public void set(T value) { + this.value = value; + } } diff --git a/src/main/java/net/helenus/support/PackageUtil.java b/src/main/java/net/helenus/support/PackageUtil.java index 83b4ffa..1b8fc8a 100644 --- a/src/main/java/net/helenus/support/PackageUtil.java +++ b/src/main/java/net/helenus/support/PackageUtil.java @@ -25,117 +25,114 @@ import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PackageUtil { - private static final Logger log = LoggerFactory.getLogger(PackageUtil.class); + public static final String JAR_URL_SEPARATOR = "!/"; + private static final Logger log = LoggerFactory.getLogger(PackageUtil.class); - public static final String JAR_URL_SEPARATOR = "!/"; + private static void doFetchInPath(Set> classes, File directory, String packageName, + ClassLoader classLoader) throws ClassNotFoundException { + File[] dirContents = directory.listFiles(); + if (dirContents == null) { + throw new ClassNotFoundException("invalid directory " + directory.getAbsolutePath()); + } + for (File file : dirContents) { + String fileName = file.getName(); + if (file.isDirectory()) { + doFetchInPath(classes, file, packageName + "." + fileName, classLoader); + } else if (fileName.endsWith(".class")) { + classes.add(classLoader.loadClass(packageName + '.' + fileName.substring(0, fileName.length() - 6))); + } + } + } - private static void doFetchInPath( - Set> classes, File directory, String packageName, ClassLoader classLoader) - throws ClassNotFoundException { - File[] dirContents = directory.listFiles(); - if (dirContents == null) { - throw new ClassNotFoundException("invalid directory " + directory.getAbsolutePath()); - } - for (File file : dirContents) { - String fileName = file.getName(); - if (file.isDirectory()) { - doFetchInPath(classes, file, packageName + "." + fileName, classLoader); - } else if (fileName.endsWith(".class")) { - classes.add( - classLoader.loadClass( - packageName + '.' + fileName.substring(0, fileName.length() - 6))); - } - } - } + public static Set> getClasses(String packagePath) throws ClassNotFoundException, IOException { + Set> classes = new HashSet>(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + throw new ClassNotFoundException("class loader not found for current thread"); + } + Enumeration resources = null; + try { + resources = classLoader.getResources(packagePath.replace('.', '/')); + } catch (IOException e) { + throw new ClassNotFoundException("invalid package " + packagePath, e); + } + while (resources.hasMoreElements()) { + URL url = resources.nextElement(); + if (url == null) { + throw new ClassNotFoundException(packagePath + " - package not found"); + } + String dirPath = fastReplace(url.getFile(), "%20", " "); + int jarSeparator = dirPath.indexOf(JAR_URL_SEPARATOR); + if (jarSeparator == -1) { + File directory = new File(dirPath); + if (!directory.exists()) { + throw new ClassNotFoundException(packagePath + " - invalid package"); + } + doFetchInPath(classes, directory, packagePath, classLoader); + } else { + String rootEntry = dirPath.substring(jarSeparator + JAR_URL_SEPARATOR.length()); + if (!"".equals(rootEntry) && !rootEntry.endsWith("/")) { + rootEntry = rootEntry + "/"; + } + JarFile jarFile = null; + try { + URLConnection con = url.openConnection(); + if (con instanceof JarURLConnection) { + JarURLConnection jarCon = (JarURLConnection) con; + jarCon.setUseCaches(false); + jarFile = jarCon.getJarFile(); + } else { + String jarName = dirPath.substring(0, jarSeparator); + jarName = fastReplace(jarName, " ", "%20"); + jarFile = new JarFile(jarName); + } + for (Enumeration entries = jarFile.entries(); entries.hasMoreElements();) { + JarEntry entry = entries.nextElement(); + String fileName = entry.getName(); + if (fileName.startsWith(rootEntry) && fileName.endsWith(".class")) { + fileName = fileName.replace('/', '.'); + try { + classes.add(classLoader.loadClass(fileName.substring(0, fileName.length() - 6))); + } catch (ClassNotFoundException e) { + log.error("class load fail", e); + } + } + } + } catch (IOException e) { + throw new ClassNotFoundException("jar fail", e); + } finally { + if (jarFile != null) + jarFile.close(); + } + } + } + return classes; + } - public static Set> getClasses(String packagePath) - throws ClassNotFoundException, IOException { - Set> classes = new HashSet>(); - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - throw new ClassNotFoundException("class loader not found for current thread"); - } - Enumeration resources = null; - try { - resources = classLoader.getResources(packagePath.replace('.', '/')); - } catch (IOException e) { - throw new ClassNotFoundException("invalid package " + packagePath, e); - } - while (resources.hasMoreElements()) { - URL url = resources.nextElement(); - if (url == null) { - throw new ClassNotFoundException(packagePath + " - package not found"); - } - String dirPath = fastReplace(url.getFile(), "%20", " "); - int jarSeparator = dirPath.indexOf(JAR_URL_SEPARATOR); - if (jarSeparator == -1) { - File directory = new File(dirPath); - if (!directory.exists()) { - throw new ClassNotFoundException(packagePath + " - invalid package"); - } - doFetchInPath(classes, directory, packagePath, classLoader); - } else { - String rootEntry = dirPath.substring(jarSeparator + JAR_URL_SEPARATOR.length()); - if (!"".equals(rootEntry) && !rootEntry.endsWith("/")) { - rootEntry = rootEntry + "/"; - } - JarFile jarFile = null; - try { - URLConnection con = url.openConnection(); - if (con instanceof JarURLConnection) { - JarURLConnection jarCon = (JarURLConnection) con; - jarCon.setUseCaches(false); - jarFile = jarCon.getJarFile(); - } else { - String jarName = dirPath.substring(0, jarSeparator); - jarName = fastReplace(jarName, " ", "%20"); - jarFile = new JarFile(jarName); - } - for (Enumeration entries = jarFile.entries(); entries.hasMoreElements(); ) { - JarEntry entry = entries.nextElement(); - String fileName = entry.getName(); - if (fileName.startsWith(rootEntry) && fileName.endsWith(".class")) { - fileName = fileName.replace('/', '.'); - try { - classes.add(classLoader.loadClass(fileName.substring(0, fileName.length() - 6))); - } catch (ClassNotFoundException e) { - log.error("class load fail", e); - } - } - } - } catch (IOException e) { - throw new ClassNotFoundException("jar fail", e); - } finally { - if (jarFile != null) jarFile.close(); - } - } - } - return classes; - } - - public static String fastReplace(String inString, String oldPattern, String newPattern) { - if (inString == null) { - return null; - } - if (oldPattern == null || newPattern == null) { - return inString; - } - StringBuilder sbuf = new StringBuilder(); - int pos = 0; - int index = inString.indexOf(oldPattern); - int patLen = oldPattern.length(); - while (index >= 0) { - sbuf.append(inString.substring(pos, index)); - sbuf.append(newPattern); - pos = index + patLen; - index = inString.indexOf(oldPattern, pos); - } - sbuf.append(inString.substring(pos)); - return sbuf.toString(); - } + public static String fastReplace(String inString, String oldPattern, String newPattern) { + if (inString == null) { + return null; + } + if (oldPattern == null || newPattern == null) { + return inString; + } + StringBuilder sbuf = new StringBuilder(); + int pos = 0; + int index = inString.indexOf(oldPattern); + int patLen = oldPattern.length(); + while (index >= 0) { + sbuf.append(inString.substring(pos, index)); + sbuf.append(newPattern); + pos = index + patLen; + index = inString.indexOf(oldPattern, pos); + } + sbuf.append(inString.substring(pos)); + return sbuf.toString(); + } } diff --git a/src/main/java/net/helenus/support/Requires.java b/src/main/java/net/helenus/support/Requires.java index 51543fa..cc8e4bf 100644 --- a/src/main/java/net/helenus/support/Requires.java +++ b/src/main/java/net/helenus/support/Requires.java @@ -20,13 +20,14 @@ import java.util.Objects; public final class Requires { - private Requires() {} + private Requires() { + } - public static void nonNullArray(T[] arr) { - Objects.requireNonNull(arr, "array is null"); - int len = Array.getLength(arr); - for (int i = 0; i != len; ++i) { - Objects.requireNonNull(Array.get(arr, i), "element " + i + " is empty in array"); - } - } + public static void nonNullArray(T[] arr) { + Objects.requireNonNull(arr, "array is null"); + int len = Array.getLength(arr); + for (int i = 0; i != len; ++i) { + Objects.requireNonNull(Array.get(arr, i), "element " + i + " is empty in array"); + } + } } diff --git a/src/main/java/net/helenus/support/Timeuuid.java b/src/main/java/net/helenus/support/Timeuuid.java index 45f9497..072f8a7 100644 --- a/src/main/java/net/helenus/support/Timeuuid.java +++ b/src/main/java/net/helenus/support/Timeuuid.java @@ -21,66 +21,55 @@ import java.util.UUID; public final class Timeuuid { - private static class Holder { - static final SecureRandom numberGenerator = new SecureRandom(); - } + private Timeuuid() { + } - private Timeuuid() {} + public static UUID of(long timestampMillis, int clockSequence, long node) { + return new UuidBuilder().addVersion(1).addTimestampMillis(timestampMillis).addClockSequence(clockSequence) + .addNode(node).build(); + } - public static UUID of(long timestampMillis, int clockSequence, long node) { - return new UuidBuilder() - .addVersion(1) - .addTimestampMillis(timestampMillis) - .addClockSequence(clockSequence) - .addNode(node) - .build(); - } + public static UUID of(Date date, int clockSequence, long node) { + return of(date.getTime(), clockSequence, node); + } - public static UUID of(Date date, int clockSequence, long node) { - return of(date.getTime(), clockSequence, node); - } + public static UUID of(long timestampMillis) { + return of(timestampMillis, randomClockSequence(), randomNode()); + } - public static UUID of(long timestampMillis) { - return of(timestampMillis, randomClockSequence(), randomNode()); - } + public static UUID of(Date date) { + return of(date.getTime()); + } - public static UUID of(Date date) { - return of(date.getTime()); - } + public static UUID minOf(long timestampMillis) { + return new UuidBuilder().addVersion(1).addTimestampMillis(timestampMillis).setMinClockSeqAndNode().build(); + } - public static UUID minOf(long timestampMillis) { - return new UuidBuilder() - .addVersion(1) - .addTimestampMillis(timestampMillis) - .setMinClockSeqAndNode() - .build(); - } + public static UUID minOf(Date date) { + return minOf(date.getTime()); + } - public static UUID minOf(Date date) { - return minOf(date.getTime()); - } + public static UUID maxOf(long timestampMillis) { + return new UuidBuilder().addVersion(1).addTimestampMillis(timestampMillis).setMaxClockSeqAndNode().build(); + } - public static UUID maxOf(long timestampMillis) { - return new UuidBuilder() - .addVersion(1) - .addTimestampMillis(timestampMillis) - .setMaxClockSeqAndNode() - .build(); - } + public static UUID maxOf(Date date) { + return maxOf(date.getTime()); + } - public static UUID maxOf(Date date) { - return maxOf(date.getTime()); - } + public static int randomClockSequence() { + return Holder.numberGenerator.nextInt(0x3fff); + } - public static int randomClockSequence() { - return Holder.numberGenerator.nextInt(0x3fff); - } + public static long randomNode() { + return Holder.numberGenerator.nextLong() & 0xFFFFFFFFFFFFL; + } - public static long randomNode() { - return Holder.numberGenerator.nextLong() & 0xFFFFFFFFFFFFL; - } + public static long getTimestampMillis(UUID uuid) { + return UuidBuilder.getTimestampMillis(uuid); + } - public static long getTimestampMillis(UUID uuid) { - return UuidBuilder.getTimestampMillis(uuid); - } + private static class Holder { + static final SecureRandom numberGenerator = new SecureRandom(); + } } diff --git a/src/main/java/net/helenus/support/Transformers.java b/src/main/java/net/helenus/support/Transformers.java index dd62ddf..2b21ca3 100644 --- a/src/main/java/net/helenus/support/Transformers.java +++ b/src/main/java/net/helenus/support/Transformers.java @@ -15,66 +15,68 @@ */ package net.helenus.support; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import java.util.*; import java.util.function.Function; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + public final class Transformers { - private Transformers() {} + private Transformers() { + } - public static Set transformSet(Set inputSet, Function func) { - Set set = Sets.newHashSet(); - for (I in : inputSet) { - set.add(func.apply(in)); - } - return set; - } + public static Set transformSet(Set inputSet, Function func) { + Set set = Sets.newHashSet(); + for (I in : inputSet) { + set.add(func.apply(in)); + } + return set; + } - public static List transformList(List inputList, Function func) { - return new TransformedImmutableList(inputList, func); - } + public static List transformList(List inputList, Function func) { + return new TransformedImmutableList(inputList, func); + } - public static Map transformMapKey(Map inputMap, Function func) { - Map map = Maps.newHashMap(); - for (Map.Entry e : inputMap.entrySet()) { - map.put(func.apply(e.getKey()), e.getValue()); - } - return map; - } + public static Map transformMapKey(Map inputMap, Function func) { + Map map = Maps.newHashMap(); + for (Map.Entry e : inputMap.entrySet()) { + map.put(func.apply(e.getKey()), e.getValue()); + } + return map; + } - public static Map transformMapValue(Map inputMap, Function func) { - return Maps.transformValues(inputMap, func::apply); - } + public static Map transformMapValue(Map inputMap, Function func) { + return Maps.transformValues(inputMap, func::apply); + } - public static Map transformMap( - Map inputMap, Function funcKey, Function funcValue) { - Map map = Maps.newHashMap(); - for (Map.Entry e : inputMap.entrySet()) { - map.put(funcKey.apply(e.getKey()), funcValue.apply(e.getValue())); - } - return map; - } + public static Map transformMap(Map inputMap, Function funcKey, + Function funcValue) { + Map map = Maps.newHashMap(); + for (Map.Entry e : inputMap.entrySet()) { + map.put(funcKey.apply(e.getKey()), funcValue.apply(e.getValue())); + } + return map; + } - static final class TransformedImmutableList extends AbstractList implements List { + static final class TransformedImmutableList extends AbstractList implements List { - final List inputList; - final Function func; + final List inputList; + final Function func; - TransformedImmutableList(List inputList, Function func) { - this.inputList = Objects.requireNonNull(inputList, "inputList is null"); - this.func = Objects.requireNonNull(func, "func is null"); - } + TransformedImmutableList(List inputList, Function func) { + this.inputList = Objects.requireNonNull(inputList, "inputList is null"); + this.func = Objects.requireNonNull(func, "func is null"); + } - @Override - public O get(int index) { - return func.apply(inputList.get(index)); - } + @Override + public O get(int index) { + return func.apply(inputList.get(index)); + } - @Override - public int size() { - return inputList.size(); - } - } + @Override + public int size() { + return inputList.size(); + } + } } diff --git a/src/main/java/net/helenus/support/UuidBuilder.java b/src/main/java/net/helenus/support/UuidBuilder.java index 9bbabf5..36fee8a 100644 --- a/src/main/java/net/helenus/support/UuidBuilder.java +++ b/src/main/java/net/helenus/support/UuidBuilder.java @@ -19,76 +19,76 @@ import java.util.UUID; public final class UuidBuilder { - public static final long NUM_100NS_IN_MILLISECOND = 10000L; + public static final long NUM_100NS_IN_MILLISECOND = 10000L; - public static final long NUM_100NS_SINCE_UUID_EPOCH = 0x01b21dd213814000L; + public static final long NUM_100NS_SINCE_UUID_EPOCH = 0x01b21dd213814000L; - private static final long MIN_CLOCK_SEQ_AND_NODE = 0x8080808080808080L; - private static final long MAX_CLOCK_SEQ_AND_NODE = 0x7f7f7f7f7f7f7f7fL; + private static final long MIN_CLOCK_SEQ_AND_NODE = 0x8080808080808080L; + private static final long MAX_CLOCK_SEQ_AND_NODE = 0x7f7f7f7f7f7f7f7fL; - private long leastSigBits = 0x8000000000000000L; + private long leastSigBits = 0x8000000000000000L; - private long mostSigBits = 0L; + private long mostSigBits = 0L; - public long getLeastSignificantBits() { - return leastSigBits; - } + public static long getTimestampMillis(UUID uuid) { + return (uuid.timestamp() - NUM_100NS_SINCE_UUID_EPOCH) / NUM_100NS_IN_MILLISECOND; + } - public long getMostSignificantBits() { - return mostSigBits; - } + public long getLeastSignificantBits() { + return leastSigBits; + } - public UUID build() { - return new UUID(mostSigBits, leastSigBits); - } + public long getMostSignificantBits() { + return mostSigBits; + } - public UuidBuilder addVersion(int version) { - if (version < 1 || version > 4) { - throw new IllegalArgumentException("unsupported version " + version); - } + public UUID build() { + return new UUID(mostSigBits, leastSigBits); + } - mostSigBits |= ((long) (version & 0x0f)) << 12; + public UuidBuilder addVersion(int version) { + if (version < 1 || version > 4) { + throw new IllegalArgumentException("unsupported version " + version); + } - return this; - } + mostSigBits |= ((long) (version & 0x0f)) << 12; - public UuidBuilder addTimestamp100Nanos(long uuid100Nanos) { + return this; + } - long timeLow = uuid100Nanos & 0xffffffffL; - long timeMid = uuid100Nanos & 0xffff00000000L; - long timeHi = uuid100Nanos & 0xfff000000000000L; + public UuidBuilder addTimestamp100Nanos(long uuid100Nanos) { - mostSigBits |= (timeLow << 32) | (timeMid >> 16) | (timeHi >> 48); + long timeLow = uuid100Nanos & 0xffffffffL; + long timeMid = uuid100Nanos & 0xffff00000000L; + long timeHi = uuid100Nanos & 0xfff000000000000L; - return this; - } + mostSigBits |= (timeLow << 32) | (timeMid >> 16) | (timeHi >> 48); - public UuidBuilder addTimestampMillis(long milliseconds) { - long uuid100Nanos = milliseconds * NUM_100NS_IN_MILLISECOND + NUM_100NS_SINCE_UUID_EPOCH; - return addTimestamp100Nanos(uuid100Nanos); - } + return this; + } - public UuidBuilder addClockSequence(int clockSequence) { - leastSigBits |= ((long) (clockSequence & 0x3fff)) << 48; - return this; - } + public UuidBuilder addTimestampMillis(long milliseconds) { + long uuid100Nanos = milliseconds * NUM_100NS_IN_MILLISECOND + NUM_100NS_SINCE_UUID_EPOCH; + return addTimestamp100Nanos(uuid100Nanos); + } - public UuidBuilder addNode(long node) { - leastSigBits |= node & 0xffffffffffffL; - return this; - } + public UuidBuilder addClockSequence(int clockSequence) { + leastSigBits |= ((long) (clockSequence & 0x3fff)) << 48; + return this; + } - public UuidBuilder setMinClockSeqAndNode() { - this.leastSigBits = MIN_CLOCK_SEQ_AND_NODE; - return this; - } + public UuidBuilder addNode(long node) { + leastSigBits |= node & 0xffffffffffffL; + return this; + } - public UuidBuilder setMaxClockSeqAndNode() { - this.leastSigBits = MAX_CLOCK_SEQ_AND_NODE; - return this; - } + public UuidBuilder setMinClockSeqAndNode() { + this.leastSigBits = MIN_CLOCK_SEQ_AND_NODE; + return this; + } - public static long getTimestampMillis(UUID uuid) { - return (uuid.timestamp() - NUM_100NS_SINCE_UUID_EPOCH) / NUM_100NS_IN_MILLISECOND; - } + public UuidBuilder setMaxClockSeqAndNode() { + this.leastSigBits = MAX_CLOCK_SEQ_AND_NODE; + return this; + } } diff --git a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java index e838ad3..bd1ac60 100644 --- a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java +++ b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -51,7 +52,7 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { } @Test - public void testSetCRUID() { + public void testSetCRUID() throws TimeoutException { UUID id = UUID.randomUUID(); @@ -148,7 +149,7 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { } @Test - public void testListCRUID() { + public void testListCRUID() throws TimeoutException { UUID id = UUID.randomUUID(); @@ -278,7 +279,7 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { } @Test - public void testMapCRUID() { + public void testMapCRUID() throws TimeoutException { UUID id = UUID.randomUUID(); diff --git a/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java b/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java index 9b8d4a2..b1c8c0f 100644 --- a/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java +++ b/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.counter; import static net.helenus.core.Query.eq; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -42,7 +43,7 @@ public class CounterTest extends AbstractEmbeddedCassandraTest { } @Test - public void testCounter() { + public void testCounter() throws TimeoutException { boolean exists = session.select(page::hits).where(page::alias, eq("index")).sync().findFirst().isPresent(); diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java index dce32b3..f5073bf 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java @@ -4,6 +4,7 @@ import static net.helenus.core.Query.eq; import java.util.Optional; import java.util.Random; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -35,7 +36,7 @@ public class HierarchyTest extends AbstractEmbeddedCassandraTest { } @Test - public void testCounter() { + public void testCounter() throws TimeoutException { session .insert() @@ -58,7 +59,7 @@ public class HierarchyTest extends AbstractEmbeddedCassandraTest { } @Test - public void testDefaultMethod() { + public void testDefaultMethod() throws TimeoutException { session .insert() .value(cat::id, rnd.nextInt()) diff --git a/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java b/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java index a302ba0..5882d8f 100644 --- a/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java +++ b/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java @@ -15,6 +15,7 @@ */ package net.helenus.test.integration.core.index; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -36,7 +37,7 @@ public class SecondaryIndexTest extends AbstractEmbeddedCassandraTest { } @Test - public void test() throws Exception { + public void test() throws TimeoutException { session .insert() diff --git a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java index da7997d..0a94e2b 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java +++ b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java @@ -19,6 +19,7 @@ import static net.helenus.core.Query.eq; import com.datastax.driver.core.ResultSet; import java.util.*; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Operator; @@ -234,7 +235,7 @@ public class SimpleUserTest extends AbstractEmbeddedCassandraTest { Assert.assertEquals(0L, cnt); } - public void testZipkin() throws Exception { + public void testZipkin() throws TimeoutException { session .update() .set(user::name, null) diff --git a/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java b/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java index b863ace..c4bd403 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java +++ b/src/test/java/net/helenus/test/integration/core/simple/StaticColumnTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.simple; import java.util.Date; import java.util.List; +import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; @@ -82,7 +83,7 @@ public class StaticColumnTest extends AbstractEmbeddedCassandraTest { } @Test - public void testCRUID() { + public void testCRUID() throws TimeoutException { MessageImpl msg = new MessageImpl(); msg.id = 123; diff --git a/src/test/java/net/helenus/test/integration/core/simple/User.java b/src/test/java/net/helenus/test/integration/core/simple/User.java index bf3cd69..f2375e1 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/User.java +++ b/src/test/java/net/helenus/test/integration/core/simple/User.java @@ -21,7 +21,6 @@ import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; @Table("simple_users") -@Cacheable public interface User { @PartitionKey diff --git a/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java b/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java index ac9b613..500689b 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java @@ -15,6 +15,7 @@ */ package net.helenus.test.integration.core.tuple; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -41,7 +42,7 @@ public class InnerTupleTest extends AbstractEmbeddedCassandraTest { } @Test - public void testCruid() { + public void testCruid() throws TimeoutException { Photo photo = new Photo() { diff --git a/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java b/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java index ae99255..5fbe1b7 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java @@ -20,6 +20,7 @@ import static net.helenus.core.Query.eq; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TupleType; import com.datastax.driver.core.TupleValue; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -46,7 +47,7 @@ public class TupleTest extends AbstractEmbeddedCassandraTest { } @Test - public void testCruid() { + public void testCruid() throws TimeoutException { AlbumInformation info = new AlbumInformation() { @@ -119,7 +120,7 @@ public class TupleTest extends AbstractEmbeddedCassandraTest { } @Test - public void testNoMapping() { + public void testNoMapping() throws TimeoutException { TupleType tupleType = session.getMetadata().newTupleType(DataType.text(), DataType.text()); TupleValue info = tupleType.newValue(); diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java index db84f09..b5501e3 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class TupleKeyMapTest extends TupleCollectionTest { @Test - public void testKeyMapCRUID() { + public void testKeyMapCRUID() throws TimeoutException { int id = 888; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java index a47e701..c09685d 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class TupleListTest extends TupleCollectionTest { @Test - public void testListCRUID() { + public void testListCRUID() throws TimeoutException { int id = 777; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java index a77276d..ef95e1f 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class TupleMapTest extends TupleCollectionTest { @Test - public void testMapCRUID() { + public void testMapCRUID() throws TimeoutException { int id = 333; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java index 26bb3db..24c1da5 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class TupleSetTest extends TupleCollectionTest { @Test - public void testSetCRUID() { + public void testSetCRUID() throws TimeoutException { int id = 555; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java index e19e472..c0de2a3 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class TupleValueMapTest extends TupleCollectionTest { @Test - public void testValueMapCRUID() { + public void testValueMapCRUID() throws TimeoutException { int id = 999; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java index a6bc35c..c6d55e3 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java @@ -20,13 +20,14 @@ import static net.helenus.core.Query.get; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeoutException; import org.junit.Assert; import org.junit.Test; public class UDTKeyMapTest extends UDTCollectionTest { @Test - public void testKeyMapCRUID() { + public void testKeyMapCRUID() throws TimeoutException { int id = 888; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java index bb42087..378d559 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.udtcollection; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class UDTListTest extends UDTCollectionTest { @Test - public void testListCRUID() { + public void testListCRUID() throws TimeoutException { int id = 777; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java index 604972c..b563202 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.udtcollection; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class UDTMapTest extends UDTCollectionTest { @Test - public void testMapCRUID() { + public void testMapCRUID() throws TimeoutException { int id = 333; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java index 098436e..7a23687 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.udtcollection; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.TimeoutException; import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; @@ -24,7 +25,7 @@ import org.junit.Test; public class UDTSetTest extends UDTCollectionTest { @Test - public void testSetCRUID() { + public void testSetCRUID() throws TimeoutException { int id = 555; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java index d495b3e..e1b50f0 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java @@ -20,13 +20,14 @@ import static net.helenus.core.Query.get; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeoutException; import org.junit.Assert; import org.junit.Test; public class UDTValueMapTest extends UDTCollectionTest { @Test - public void testValueMapCRUID() { + public void testValueMapCRUID() throws TimeoutException { int id = 999; diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java index 4e45fff..27e86bb 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java @@ -25,6 +25,7 @@ import net.helenus.core.HelenusSession; import net.helenus.core.UnitOfWork; import net.helenus.core.annotation.Cacheable; import net.helenus.mapping.annotation.Column; +import net.helenus.mapping.annotation.Index; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -39,6 +40,7 @@ interface Widget { UUID id(); @Column + @Index String name(); } @@ -55,7 +57,7 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { @Test public void testSelectAfterSelect() throws Exception { - Widget w1, w2; + Widget w1, w2, w3; UUID key = UUIDs.timeBased(); // This should inserted Widget, but not cache it. @@ -67,13 +69,15 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { try (UnitOfWork uow = session.begin()) { + uow.setPurpose("testSelectAfterSelect"); + // This should read from the database and return a Widget. w1 = session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); // This should read from the cache and get the same instance of a Widget. w2 = - session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); + session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); uow.commit() .andThen( @@ -81,6 +85,9 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { Assert.assertEquals(w1, w2); }); } + + w3 = session.select(widget).where(widget::name, eq(w1.name())).single().sync().orElse(null); + Assert.assertEquals(w1, w3); } @Test @@ -141,6 +148,46 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { }); } } + + @Test + public void testSelectViaIndexAfterSelect() throws Exception { + Widget w1, w2; + UUID key = UUIDs.timeBased(); + + try (UnitOfWork uow = session.begin()) { + // This should insert and cache Widget in the uow. + session + .insert(widget) + .value(widget::id, key) + .value(widget::name, RandomString.make(20)) + .sync(uow); + + // This should read from the database and return a Widget. + w1 = + session + .select(widget) + .where(widget::id, eq(key)) + .single() + .sync(uow) + .orElse(null); + + // This should read from the cache and get the same instance of a Widget. + w2 = + session + .select(widget) + .where(widget::name, eq(w1.name())) + .single() + .sync(uow) + .orElse(null); + + uow.commit() + .andThen( + () -> { + Assert.assertEquals(w1, w2); + }); + } + } + /* @Test public void testSelectAfterInsertProperlyCachesEntity() throws Exception { diff --git a/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java b/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java index 116b08f..bb0a287 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java @@ -18,6 +18,7 @@ package net.helenus.test.integration.core.usertype; import com.google.common.collect.Sets; import java.util.Set; import java.util.UUID; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -56,7 +57,7 @@ public class InnerUserDefinedTypeTest extends AbstractEmbeddedCassandraTest { } @Test - public void testCrud() { + public void testCrud() throws TimeoutException { UUID id = UUID.randomUUID(); diff --git a/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java b/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java index ca65a38..b5e5ef9 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java @@ -18,6 +18,7 @@ package net.helenus.test.integration.core.usertype; import com.datastax.driver.core.UDTValue; import com.datastax.driver.core.UserType; import java.util.Set; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -103,7 +104,7 @@ public class UserDefinedTypeTest extends AbstractEmbeddedCassandraTest { } @Test - public void testMappingCRUID() { + public void testMappingCRUID() throws TimeoutException { AddressImpl addr = new AddressImpl(); addr.street = "1 st"; @@ -174,7 +175,7 @@ public class UserDefinedTypeTest extends AbstractEmbeddedCassandraTest { } @Test - public void testNoMapping() { + public void testNoMapping() throws TimeoutException { String ks = getSession().getLoggedKeyspace(); UserType addressType = diff --git a/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java b/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java index 02b414c..555155f 100644 --- a/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java +++ b/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java @@ -2,7 +2,6 @@ package net.helenus.test.integration.core.views; import java.util.Date; import java.util.UUID; - import net.helenus.mapping.OrderingDirection; import net.helenus.mapping.annotation.*; diff --git a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java index a8df217..a733c1e 100644 --- a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java +++ b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java @@ -20,6 +20,7 @@ import static net.helenus.core.Query.eq; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -29,6 +30,7 @@ import org.junit.Test; // See: https://docs.datastax.com/en/cql/3.3/cql/cql_using/useCreateMV.html // https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlCreateMaterializedView.html // https://www.datastax.com/dev/blog/materialized-view-performance-in-cassandra-3-x +// https://cassandra-zone.com/materialized-views/ public class MaterializedViewTest extends AbstractEmbeddedCassandraTest { static Cyclist cyclist; @@ -55,22 +57,21 @@ public class MaterializedViewTest extends AbstractEmbeddedCassandraTest { .get(); cyclist = session.dsl(Cyclist.class); - session - .insert(cyclist) - .value(cyclist::cid, UUID.randomUUID()) - .value(cyclist::age, 18) - .value(cyclist::birthday, dateFromString("1997-02-08")) - .value(cyclist::country, "Netherlands") - .value(cyclist::name, "Pascal EENKHOORN") - .sync(); + //try { + session + .insert(cyclist) + .value(cyclist::cid, UUID.randomUUID()) + .value(cyclist::age, 18) + .value(cyclist::birthday, dateFromString("1997-02-08")) + .value(cyclist::country, "Netherlands") + .value(cyclist::name, "Pascal EENKHOORN") + .sync(); + //} catch (TimeoutException e) { + //} } @Test - public void testMv() throws Exception { - session - .select(Cyclist.class) - .from(CyclistsByAge.class) - .where(cyclist::age, eq(18)) - .sync(); + public void testMv() throws TimeoutException { + session.select(Cyclist.class).from(CyclistsByAge.class).where(cyclist::age, eq(18)).sync(); } }