diff --git a/src/main/java/org/globsframework/metamodel/Field.java b/src/main/java/org/globsframework/metamodel/Field.java index 3cf7a39..19e53ae 100644 --- a/src/main/java/org/globsframework/metamodel/Field.java +++ b/src/main/java/org/globsframework/metamodel/Field.java @@ -96,6 +96,13 @@ default LongField asLongField() { return (LongField) this; } + default BigDecimalField asBigDecimalField() { + if (!(this instanceof BigDecimalField)) { + throw new RuntimeException(getFullName() + " is not a BigDecimalField but a " + getDataType()); + } + return (BigDecimalField) this; + } + default DateField asDateField() { if (!(this instanceof DateField)) { throw new RuntimeException(getFullName() + " is not a DateField but a " + getDataType()); diff --git a/src/main/java/org/globsframework/metamodel/GlobType.java b/src/main/java/org/globsframework/metamodel/GlobType.java index 66338af..e30adf5 100644 --- a/src/main/java/org/globsframework/metamodel/GlobType.java +++ b/src/main/java/org/globsframework/metamodel/GlobType.java @@ -1,6 +1,8 @@ package org.globsframework.metamodel; import org.globsframework.metamodel.fields.FieldVisitor; +import org.globsframework.metamodel.fields.FieldVisitorWithContext; +import org.globsframework.metamodel.impl.DefaultValuesFieldVisitor; import org.globsframework.metamodel.index.Index; import org.globsframework.metamodel.properties.PropertyHolder; import org.globsframework.model.GlobFactory; @@ -8,6 +10,7 @@ import org.globsframework.model.MutableGlob; import org.globsframework.utils.exceptions.ItemNotFound; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Optional; @@ -57,6 +60,26 @@ default MutableGlob instantiate() { return getGlobFactory().create(); } + default MutableGlob instantiateWithDefaults() { + MutableGlob glob = getGlobFactory().create(); + FieldVisitorWithContext visitor = new DefaultValuesFieldVisitor(); + Arrays.stream(this.getFields()).forEach(field -> { + try { + switch (field.getDataType()) { + case Boolean -> visitor.visitBoolean(field.asBooleanField(), glob); + case Double -> visitor.visitDouble(field.asDoubleField(), glob); + case Integer -> visitor.visitInteger(field.asIntegerField(), glob); + case Long -> visitor.visitLong(field.asLongField(), glob); + case String -> visitor.visitString(field.asStringField(), glob); + case BigDecimal -> visitor.visitBigDecimal(field.asBigDecimalField(), glob); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + return glob; + } + default T accept(T visitor) throws Exception { return getGlobFactory().accept(visitor); } diff --git a/src/main/java/org/globsframework/metamodel/annotations/DefaultBigDecimal.java b/src/main/java/org/globsframework/metamodel/annotations/DefaultBigDecimal.java new file mode 100644 index 0000000..47dc500 --- /dev/null +++ b/src/main/java/org/globsframework/metamodel/annotations/DefaultBigDecimal.java @@ -0,0 +1,15 @@ +package org.globsframework.metamodel.annotations; + +import org.globsframework.metamodel.GlobType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +@java.lang.annotation.Target({ElementType.FIELD}) +public @interface DefaultBigDecimal { + String value(); + + GlobType TYPE = DefaultBigDecimalAnnotationType.DESC; +} diff --git a/src/main/java/org/globsframework/metamodel/annotations/DefaultBigDecimalAnnotationType.java b/src/main/java/org/globsframework/metamodel/annotations/DefaultBigDecimalAnnotationType.java new file mode 100644 index 0000000..b96e7d3 --- /dev/null +++ b/src/main/java/org/globsframework/metamodel/annotations/DefaultBigDecimalAnnotationType.java @@ -0,0 +1,32 @@ +package org.globsframework.metamodel.annotations; + +import org.globsframework.metamodel.GlobType; +import org.globsframework.metamodel.GlobTypeLoader; +import org.globsframework.metamodel.GlobTypeLoaderFactory; +import org.globsframework.metamodel.fields.BigDecimalField; +import org.globsframework.metamodel.fields.DoubleField; +import org.globsframework.model.Glob; +import org.globsframework.model.Key; + +import java.math.BigDecimal; + +public class DefaultBigDecimalAnnotationType { + + public static GlobType DESC; + + @DefaultFieldValue + public static BigDecimalField DEFAULT_VALUE; + + @InitUniqueKey + public static Key UNIQUE_KEY; + + public static Glob create(String defaultBigDecimal) { + return DESC.instantiate().set(DEFAULT_VALUE, new BigDecimal(defaultBigDecimal)); + } + + static { + GlobTypeLoader loader = GlobTypeLoaderFactory.create(DefaultBigDecimalAnnotationType.class); + loader.register(GlobCreateFromAnnotation.class, annotation -> create(((DefaultBigDecimal)annotation).value())) + .load(); + } +} diff --git a/src/main/java/org/globsframework/metamodel/fields/impl/DefaultBigDecimalField.java b/src/main/java/org/globsframework/metamodel/fields/impl/DefaultBigDecimalField.java index 14fcd54..29741f7 100644 --- a/src/main/java/org/globsframework/metamodel/fields/impl/DefaultBigDecimalField.java +++ b/src/main/java/org/globsframework/metamodel/fields/impl/DefaultBigDecimalField.java @@ -8,7 +8,7 @@ import java.math.BigDecimal; public class DefaultBigDecimalField extends AbstractField implements BigDecimalField { - public DefaultBigDecimalField(String name, GlobType globType, int index, boolean isKeyField, int keyIndex, Long defaultValue) { + public DefaultBigDecimalField(String name, GlobType globType, int index, boolean isKeyField, int keyIndex, BigDecimal defaultValue) { super(name, globType, BigDecimal.class, index, keyIndex, isKeyField, defaultValue, DataType.BigDecimal); } diff --git a/src/main/java/org/globsframework/metamodel/impl/DefaultFieldFactory.java b/src/main/java/org/globsframework/metamodel/impl/DefaultFieldFactory.java index 15bb45c..ab0da84 100644 --- a/src/main/java/org/globsframework/metamodel/impl/DefaultFieldFactory.java +++ b/src/main/java/org/globsframework/metamodel/impl/DefaultFieldFactory.java @@ -16,6 +16,7 @@ import org.globsframework.model.Glob; import org.globsframework.model.Key; +import java.math.BigDecimal; import java.util.List; public class DefaultFieldFactory { @@ -92,8 +93,9 @@ public DefaultBooleanField addBoolean(String name, public DefaultBigDecimalField addBigDecimal(String name, boolean isKeyField, - int keyIndex, int index) { - return add(new DefaultBigDecimalField(name, type, index, isKeyField, keyIndex, null), false); + int keyIndex, int index, + BigDecimal defaultValue) { + return add(new DefaultBigDecimalField(name, type, index, isKeyField, keyIndex, defaultValue), false); } public DefaultBigDecimalArrayField addBigDecimalArray(String name, diff --git a/src/main/java/org/globsframework/metamodel/impl/DefaultGlobTypeBuilder.java b/src/main/java/org/globsframework/metamodel/impl/DefaultGlobTypeBuilder.java index e7e8242..14a9319 100644 --- a/src/main/java/org/globsframework/metamodel/impl/DefaultGlobTypeBuilder.java +++ b/src/main/java/org/globsframework/metamodel/impl/DefaultGlobTypeBuilder.java @@ -11,6 +11,7 @@ import org.globsframework.metamodel.utils.MutableAnnotations; import org.globsframework.model.Glob; +import java.math.BigDecimal; import java.util.Collection; import java.util.List; @@ -172,7 +173,8 @@ private DefaultDoubleArrayField createDoubleArrayField(String fieldName, Collect private DefaultBigDecimalField createBigDecimalField(String fieldName, Collection globAnnotations) { MutableAnnotations annotations = adaptAnnotation(globAnnotations); Glob key = annotations.findAnnotation(KeyAnnotationType.UNIQUE_KEY); - DefaultBigDecimalField bigDecimalField = factory.addBigDecimal(fieldName, key != null, getKeyId(key), index); + BigDecimal defaultValue = annotations.getValueOrDefault(DefaultBigDecimalAnnotationType.UNIQUE_KEY, DefaultBigDecimalAnnotationType.DEFAULT_VALUE, null); + DefaultBigDecimalField bigDecimalField = factory.addBigDecimal(fieldName, key != null, getKeyId(key), index, defaultValue); bigDecimalField.addAnnotations(annotations.streamAnnotations()); index++; return bigDecimalField; diff --git a/src/main/java/org/globsframework/metamodel/impl/DefaultValuesFieldVisitor.java b/src/main/java/org/globsframework/metamodel/impl/DefaultValuesFieldVisitor.java new file mode 100644 index 0000000..d7a4cd3 --- /dev/null +++ b/src/main/java/org/globsframework/metamodel/impl/DefaultValuesFieldVisitor.java @@ -0,0 +1,116 @@ +package org.globsframework.metamodel.impl; + +import org.globsframework.metamodel.annotations.*; +import org.globsframework.metamodel.fields.*; +import org.globsframework.model.MutableGlob; + +import java.math.BigDecimal; + +public class DefaultValuesFieldVisitor implements FieldVisitorWithContext { + @Override + public void visitInteger(IntegerField field, MutableGlob context) throws Exception { + if (field.hasAnnotation(DefaultIntegerAnnotationType.UNIQUE_KEY)) { + context.set(field.asIntegerField(), (int) field.getDefaultValue()); + } + } + + @Override + public void visitIntegerArray(IntegerArrayField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitDouble(DoubleField field, MutableGlob context) throws Exception { + if (field.hasAnnotation(DefaultDoubleAnnotationType.UNIQUE_KEY)) { + context.set(field.asDoubleField(), (double) field.getDefaultValue()); + } + } + + @Override + public void visitDoubleArray(DoubleArrayField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitString(StringField field, MutableGlob context) throws Exception { + if (field.hasAnnotation(DefaultStringAnnotationType.UNIQUE_KEY)) { + context.set(field.asStringField(), (String) field.getDefaultValue()); + } + } + + @Override + public void visitStringArray(StringArrayField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitBoolean(BooleanField field, MutableGlob context) throws Exception { + if (field.hasAnnotation(DefaultBooleanAnnotationType.UNIQUE_KEY)) { + context.set(field.asBooleanField(), (boolean) field.getDefaultValue()); + } + } + + @Override + public void visitBooleanArray(BooleanArrayField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitBigDecimal(BigDecimalField field, MutableGlob context) throws Exception { + if (field.hasAnnotation(DefaultBigDecimalAnnotationType.UNIQUE_KEY)) { + context.set(field.asBigDecimalField(), (BigDecimal) field.getDefaultValue()); + } + + } + + @Override + public void visitBigDecimalArray(BigDecimalArrayField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitLong(LongField field, MutableGlob context) throws Exception { + if (field.hasAnnotation(DefaultLongAnnotationType.UNIQUE_KEY)) { + context.set(field.asLongField(), (long) field.getDefaultValue()); + } + } + + @Override + public void visitLongArray(LongArrayField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitDate(DateField field, MutableGlob context) throws Exception { + } + + @Override + public void visitDateTime(DateTimeField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitBlob(BlobField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitGlob(GlobField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitGlobArray(GlobArrayField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitUnionGlob(GlobUnionField field, MutableGlob context) throws Exception { + + } + + @Override + public void visitUnionGlobArray(GlobArrayUnionField field, MutableGlob context) throws Exception { + + } +} diff --git a/src/main/java/org/globsframework/metamodel/impl/GlobTypeLoaderImpl.java b/src/main/java/org/globsframework/metamodel/impl/GlobTypeLoaderImpl.java index 9c245af..2ee95fe 100644 --- a/src/main/java/org/globsframework/metamodel/impl/GlobTypeLoaderImpl.java +++ b/src/main/java/org/globsframework/metamodel/impl/GlobTypeLoaderImpl.java @@ -20,6 +20,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Modifier; +import java.math.BigDecimal; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -309,7 +310,10 @@ else if (DateTimeField.class.isAssignableFrom(fieldClass)) { return fieldFactory.addDateTime(name, isKeyField, keyIndex, index); } else if (BigDecimalField.class.isAssignableFrom(fieldClass)) { - return fieldFactory.addBigDecimal(name, isKeyField, keyIndex, index); + DefaultBigDecimal defaultBigDecimal = field.getAnnotation(DefaultBigDecimal.class); + return fieldFactory.addBigDecimal(name, isKeyField, keyIndex, index, + defaultBigDecimal != null ? new BigDecimal(defaultBigDecimal.value()) : null + ); } else if (BigDecimalArrayField.class.isAssignableFrom(fieldClass)) { return fieldFactory.addBigDecimalArray(name, isKeyField, keyIndex, index); diff --git a/src/test/java/org/globsframework/metamodel/DummyObjectWithDefaultValues.java b/src/test/java/org/globsframework/metamodel/DummyObjectWithDefaultValues.java index 5fdf8bb..5495d40 100644 --- a/src/test/java/org/globsframework/metamodel/DummyObjectWithDefaultValues.java +++ b/src/test/java/org/globsframework/metamodel/DummyObjectWithDefaultValues.java @@ -13,6 +13,9 @@ public class DummyObjectWithDefaultValues { @DefaultInteger(7) public static IntegerField INTEGER; + @DefaultBigDecimal("1.61803398875") + public static BigDecimalField BIG_DECIMAL; + @DefaultLong(5l) public static LongField LONG; diff --git a/src/test/java/org/globsframework/metamodel/GlobTypeInstantiateWithDefaultsTest.java b/src/test/java/org/globsframework/metamodel/GlobTypeInstantiateWithDefaultsTest.java new file mode 100644 index 0000000..56bbb67 --- /dev/null +++ b/src/test/java/org/globsframework/metamodel/GlobTypeInstantiateWithDefaultsTest.java @@ -0,0 +1,35 @@ +package org.globsframework.metamodel; + +import org.globsframework.model.MutableGlob; +import org.junit.Test; + +import java.math.BigDecimal; + +import static org.junit.Assert.*; + +public class GlobTypeInstantiateWithDefaultsTest { + @Test + public void test() { + MutableGlob globWithDefaults = DummyObjectWithDefaultValues.TYPE.instantiateWithDefaults(); + + assertEquals(globWithDefaults.get(DummyObjectWithDefaultValues.STRING), "Hello"); + assertEquals(globWithDefaults.get(DummyObjectWithDefaultValues.DOUBLE), Double.valueOf(3.14159265)); + assertEquals(globWithDefaults.get(DummyObjectWithDefaultValues.INTEGER), Integer.valueOf(7)); + assertEquals(globWithDefaults.get(DummyObjectWithDefaultValues.LONG), Long.valueOf(5)); + assertEquals(globWithDefaults.get(DummyObjectWithDefaultValues.BIG_DECIMAL), new BigDecimal("1.61803398875")); + assertNull(globWithDefaults.get(DummyObjectWithDefaultValues.ID)); + assertNull(globWithDefaults.get(DummyObjectWithDefaultValues.LINK)); + assertTrue(globWithDefaults.get(DummyObjectWithDefaultValues.BOOLEAN)); + + MutableGlob glob = DummyObjectWithDefaultValues.TYPE.instantiate(); + assertNull(glob.get(DummyObjectWithDefaultValues.STRING)); + assertNull(glob.get(DummyObjectWithDefaultValues.DOUBLE)); + assertNull(glob.get(DummyObjectWithDefaultValues.INTEGER)); + assertNull(glob.get(DummyObjectWithDefaultValues.LONG)); + assertNull(glob.get(DummyObjectWithDefaultValues.BIG_DECIMAL)); + assertNull(glob.get(DummyObjectWithDefaultValues.ID)); + assertNull(glob.get(DummyObjectWithDefaultValues.LINK)); + assertNull(glob.get(DummyObjectWithDefaultValues.BOOLEAN)); + + } +}