diff --git a/src/main/java/com/noorq/casser/core/CasserValidator.java b/src/main/java/com/noorq/casser/core/CasserValidator.java index dd048a3..234aa0b 100644 --- a/src/main/java/com/noorq/casser/core/CasserValidator.java +++ b/src/main/java/com/noorq/casser/core/CasserValidator.java @@ -23,13 +23,11 @@ import com.noorq.casser.mapping.CasserProperty; import com.noorq.casser.support.CasserException; import com.noorq.casser.support.CasserMappingException; -public final class CasserValidator { +public enum CasserValidator implements PropertyValueValidator { - private CasserValidator() { - - } + INSTANCE; - public static void validate(CasserProperty prop, Object value) { + public void validate(CasserProperty prop, Object value) { for (ConstraintValidator validator : prop.getValidators()) { @@ -46,7 +44,7 @@ public final class CasserValidator { } if (!valid) { - throw new CasserException("wrong value type '" + value + "' for " + prop); + throw new CasserException("wrong value '" + value + "' for " + prop); } } diff --git a/src/main/java/com/noorq/casser/core/PropertyValueValidator.java b/src/main/java/com/noorq/casser/core/PropertyValueValidator.java new file mode 100644 index 0000000..00410a4 --- /dev/null +++ b/src/main/java/com/noorq/casser/core/PropertyValueValidator.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 Noorq, Inc. + * + * 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 com.noorq.casser.core; + +import com.noorq.casser.mapping.CasserProperty; + +public interface PropertyValueValidator { + + void validate(CasserProperty prop, Object value); + +} diff --git a/src/main/java/com/noorq/casser/core/operation/UpdateOperation.java b/src/main/java/com/noorq/casser/core/operation/UpdateOperation.java index 9ddc2b4..92c88d7 100644 --- a/src/main/java/com/noorq/casser/core/operation/UpdateOperation.java +++ b/src/main/java/com/noorq/casser/core/operation/UpdateOperation.java @@ -29,6 +29,7 @@ import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Update; import com.noorq.casser.core.AbstractSessionOperations; +import com.noorq.casser.core.CasserValidator; import com.noorq.casser.core.Filter; import com.noorq.casser.core.Getter; import com.noorq.casser.core.reflect.CasserPropertyNode; diff --git a/src/main/java/com/noorq/casser/mapping/CasserMappingEntity.java b/src/main/java/com/noorq/casser/mapping/CasserMappingEntity.java index 8251357..015f500 100644 --- a/src/main/java/com/noorq/casser/mapping/CasserMappingEntity.java +++ b/src/main/java/com/noorq/casser/mapping/CasserMappingEntity.java @@ -235,48 +235,7 @@ public final class CasserMappingEntity implements CasserEntity { .append(":\n"); for (CasserProperty prop : getOrderedProperties()) { - String columnName = prop.getColumnName().getName(); - str.append(" "); - str.append(prop.getDataType()); - str.append(" "); - str.append(prop.getPropertyName()); - str.append("("); - if (!columnName.equals(prop.getPropertyName())) { - str.append(columnName); - } - str.append(") "); - - ColumnType type = prop.getColumnType(); - - switch(type) { - - case PARTITION_KEY: - str.append("partition_key["); - str.append(prop.getOrdinal()); - str.append("] "); - break; - - case CLUSTERING_COLUMN: - str.append("clustering_column["); - str.append(prop.getOrdinal()); - str.append("] "); - OrderingDirection od = prop.getOrdering(); - if (od != null) { - str.append(od.name().toLowerCase()).append(" "); - } - break; - - case STATIC_COLUMN: - str.append("static "); - break; - - } - - Optional idx = prop.getIndexName(); - if (idx.isPresent()) { - str.append("index(").append(idx.get().getName()).append(") "); - } - + str.append(prop.toString()); str.append("\n"); } return str.toString(); diff --git a/src/main/java/com/noorq/casser/mapping/CasserMappingProperty.java b/src/main/java/com/noorq/casser/mapping/CasserMappingProperty.java index cae7b7c..1ecc1df 100644 --- a/src/main/java/com/noorq/casser/mapping/CasserMappingProperty.java +++ b/src/main/java/com/noorq/casser/mapping/CasserMappingProperty.java @@ -141,5 +141,58 @@ public final class CasserMappingProperty implements CasserProperty { return validators; } + @Override + public String toString() { + + StringBuilder str = new StringBuilder(); + + 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(") "); + + ColumnType type = this.getColumnType(); + + switch(type) { + + case PARTITION_KEY: + str.append("partition_key["); + str.append(this.getOrdinal()); + str.append("] "); + 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 STATIC_COLUMN: + str.append("static "); + break; + + case COLUMN: + break; + + } + + Optional idx = this.getIndexName(); + if (idx.isPresent()) { + str.append("index(").append(idx.get().getName()).append(") "); + } + + return str.toString(); + } + } diff --git a/src/main/java/com/noorq/casser/mapping/value/StatementColumnValuePreparer.java b/src/main/java/com/noorq/casser/mapping/value/StatementColumnValuePreparer.java index 84816fc..c4e158d 100644 --- a/src/main/java/com/noorq/casser/mapping/value/StatementColumnValuePreparer.java +++ b/src/main/java/com/noorq/casser/mapping/value/StatementColumnValuePreparer.java @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.function.Function; import com.datastax.driver.core.querybuilder.BindMarker; +import com.noorq.casser.core.CasserValidator; import com.noorq.casser.core.SessionRepository; import com.noorq.casser.mapping.CasserProperty; @@ -34,12 +35,14 @@ public final class StatementColumnValuePreparer implements ColumnValuePreparer { @Override public Object prepareColumnValue(Object value, CasserProperty prop) { + if (value instanceof BindMarker) { + return value; + } + + CasserValidator.INSTANCE.validate(prop, value); + if (value != null) { - if (value instanceof BindMarker) { - return value; - } - Optional> converter = prop.getWriteConverter(repository); if (converter.isPresent()) { diff --git a/src/main/java/com/noorq/casser/mapping/value/TupleColumnValuePreparer.java b/src/main/java/com/noorq/casser/mapping/value/TupleColumnValuePreparer.java index 2fa566d..5472b2a 100644 --- a/src/main/java/com/noorq/casser/mapping/value/TupleColumnValuePreparer.java +++ b/src/main/java/com/noorq/casser/mapping/value/TupleColumnValuePreparer.java @@ -22,6 +22,7 @@ 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 com.noorq.casser.core.CasserValidator; import com.noorq.casser.core.SessionRepository; import com.noorq.casser.mapping.CasserProperty; @@ -38,12 +39,14 @@ public final class TupleColumnValuePreparer implements ColumnValuePreparer { @Override public Object prepareColumnValue(Object value, CasserProperty prop) { + if (value instanceof BindMarker) { + return value; + } + + CasserValidator.INSTANCE.validate(prop, value); + if (value != null) { - if (value instanceof BindMarker) { - return value; - } - Optional> converter = prop.getWriteConverter(repository); if (converter.isPresent()) { diff --git a/src/main/java/com/noorq/casser/mapping/value/UDTColumnValuePreparer.java b/src/main/java/com/noorq/casser/mapping/value/UDTColumnValuePreparer.java index c7bec19..8c54927 100644 --- a/src/main/java/com/noorq/casser/mapping/value/UDTColumnValuePreparer.java +++ b/src/main/java/com/noorq/casser/mapping/value/UDTColumnValuePreparer.java @@ -22,6 +22,7 @@ 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 com.noorq.casser.core.CasserValidator; import com.noorq.casser.core.SessionRepository; import com.noorq.casser.mapping.CasserProperty; @@ -38,12 +39,14 @@ public final class UDTColumnValuePreparer implements ColumnValuePreparer { @Override public Object prepareColumnValue(Object value, CasserProperty prop) { + if (value instanceof BindMarker) { + return value; + } + + CasserValidator.INSTANCE.validate(prop, value); + if (value != null) { - if (value instanceof BindMarker) { - return value; - } - Optional> converter = prop.getWriteConverter(repository); if (converter.isPresent()) { diff --git a/src/test/java/com/noorq/casser/test/integration/core/CasserValidatorTest.java b/src/test/java/com/noorq/casser/test/integration/core/CasserValidatorTest.java index 21d3fef..34b14ef 100644 --- a/src/test/java/com/noorq/casser/test/integration/core/CasserValidatorTest.java +++ b/src/test/java/com/noorq/casser/test/integration/core/CasserValidatorTest.java @@ -39,16 +39,16 @@ public class CasserValidatorTest { @Test(expected=CasserMappingException.class) public void testWrongType() { - CasserValidator.validate(prop, Integer.valueOf(123)); + CasserValidator.INSTANCE.validate(prop, Integer.valueOf(123)); } @Test(expected=CasserException.class) public void testWrongValue() { - CasserValidator.validate(prop, "123"); + CasserValidator.INSTANCE.validate(prop, "123"); } public void testOk() { - CasserValidator.validate(prop, "a@b.c"); + CasserValidator.INSTANCE.validate(prop, "a@b.c"); } } diff --git a/src/test/java/com/noorq/casser/test/integration/core/simple/User.java b/src/test/java/com/noorq/casser/test/integration/core/simple/User.java index 699f3c4..8def2ec 100644 --- a/src/test/java/com/noorq/casser/test/integration/core/simple/User.java +++ b/src/test/java/com/noorq/casser/test/integration/core/simple/User.java @@ -16,6 +16,7 @@ package com.noorq.casser.test.integration.core.simple; import com.noorq.casser.mapping.annotation.Column; +import com.noorq.casser.mapping.annotation.Constraints; import com.noorq.casser.mapping.annotation.PartitionKey; import com.noorq.casser.mapping.annotation.Table; @@ -25,6 +26,7 @@ public interface User { @PartitionKey Long id(); + @Constraints.LowerCase @Column("override_name") String name();