From f9eb1b80655a2fbc5539a42e41ca6e2f57f5121e Mon Sep 17 00:00:00 2001 From: Gerolmed Date: Sun, 22 Sep 2019 17:29:35 +0200 Subject: [PATCH 1/7] Made variables optional --- .../net/endrealm/realmdrive/annotations/SaveVar.java | 1 + .../realmdrive/inst/SimpleConversionHandler.java | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java b/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java index 86ad546..979ab40 100644 --- a/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java +++ b/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java @@ -16,4 +16,5 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface SaveVar { + boolean optional() default true; } diff --git a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java index bf87677..9751171 100644 --- a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java +++ b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java @@ -102,18 +102,26 @@ public T transform(DriveObject statisticsObject, Class clazz) throws Clas T instance = constructor.newInstance(); for(Field field : ReflectionUtils.getAllAnnotatedFields(clazz, SaveVar.class)) { + SaveVar saveVar = field.getAnnotation(SaveVar.class); + boolean protection = field.isAccessible(); field.setAccessible(true); DriveElement value = statisticsObject.get(field.getName()); - if(value == null) + // Value not found in object + if(value == null) { + + // if this field is only optional skip it + if(saveVar.optional()) + continue; + throw new ClassCastException(String.format("Found unmapped field %s in %s!", field.getName(), field.getDeclaringClass().getName())); + } { Object object = getConvertedEndpoint(value, field.getType()); if(object != null) { - //noinspection unchecked field.set(instance, object); continue; } From f5ca1252ccdb3cce3fee877e9ae79d501bfabbc6 Mon Sep 17 00:00:00 2001 From: Gerolmed Date: Sun, 22 Sep 2019 18:10:41 +0200 Subject: [PATCH 2/7] Added null value support --- .../realmdrive/inst/SimpleConversionHandler.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java index 9751171..b02750c 100644 --- a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java +++ b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java @@ -243,11 +243,22 @@ public DriveObject transform(Object object) throws ClassCastException { statisticsObject.setPrimitive("className", object.getClass().getName()); for(Field field : fieldList) { + SaveVar saveVar = field.getAnnotation(SaveVar.class); + boolean protection = field.isAccessible(); field.setAccessible(true); Object value = field.get(object); + if(value == null) { + + // if this field is only optional skip it + if(saveVar.optional()) + continue; + + throw new ClassCastException(String.format("Found empty non optional field %s in %s!", field.getName(), field.getDeclaringClass().getName())); + } + DriveElement driveElement = getElementEndpoint(value, value.getClass()); if(driveElement != null) { statisticsObject.setObject(field.getName(), driveElement); From 414e7516f3b509bb3d15afb83d0c0ece3dc7dae5 Mon Sep 17 00:00:00 2001 From: Gerolmed Date: Mon, 30 Sep 2019 12:15:11 +0200 Subject: [PATCH 3/7] Fixed array --- src/main/java/net/endrealm/realmdrive/utils/BsonUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/endrealm/realmdrive/utils/BsonUtils.java b/src/main/java/net/endrealm/realmdrive/utils/BsonUtils.java index a830492..6e323a3 100644 --- a/src/main/java/net/endrealm/realmdrive/utils/BsonUtils.java +++ b/src/main/java/net/endrealm/realmdrive/utils/BsonUtils.java @@ -56,7 +56,7 @@ public static DriveObject unStringify(Document jsonObject, DriveObjectFactory ob array.addObject(unStringify((Document) obj, objectFactory)); //handle primitives } else - array.addPrimitive(element); + array.addPrimitive(obj); } statisticsObject.setObject(entry.getKey(), array); //handle primitives From 94a2d6bf73baeeb8ae13872fd2b49f0521a2eaf3 Mon Sep 17 00:00:00 2001 From: Gerolmed Date: Sat, 5 Oct 2019 13:38:28 +0200 Subject: [PATCH 4/7] Added and implemented new annotations --- .../realmdrive/annotations/IgnoreVar.java | 18 ++++ .../realmdrive/annotations/ReadOnly.java | 20 +++++ .../realmdrive/annotations/SaveAll.java | 23 ++++++ .../realmdrive/annotations/SaveTable.java | 20 +++++ .../realmdrive/annotations/SaveVar.java | 22 ++++- .../realmdrive/annotations/WriteOnly.java | 20 +++++ .../inst/SimpleConversionHandler.java | 49 ++++++++--- .../realmdrive/inst/SimpleDriveWriter.java | 23 +++++- .../realmdrive/utils/ReflectionUtils.java | 10 +++ .../utils/properties/ClassProperties.java | 12 +++ .../utils/properties/FieldProperties.java | 15 ++++ .../utils/properties/PropertyReader.java | 82 +++++++++++++++++++ 12 files changed, 297 insertions(+), 17 deletions(-) create mode 100644 src/main/java/net/endrealm/realmdrive/annotations/IgnoreVar.java create mode 100644 src/main/java/net/endrealm/realmdrive/annotations/ReadOnly.java create mode 100644 src/main/java/net/endrealm/realmdrive/annotations/SaveAll.java create mode 100644 src/main/java/net/endrealm/realmdrive/annotations/SaveTable.java create mode 100644 src/main/java/net/endrealm/realmdrive/annotations/WriteOnly.java create mode 100644 src/main/java/net/endrealm/realmdrive/utils/properties/ClassProperties.java create mode 100644 src/main/java/net/endrealm/realmdrive/utils/properties/FieldProperties.java create mode 100644 src/main/java/net/endrealm/realmdrive/utils/properties/PropertyReader.java diff --git a/src/main/java/net/endrealm/realmdrive/annotations/IgnoreVar.java b/src/main/java/net/endrealm/realmdrive/annotations/IgnoreVar.java new file mode 100644 index 0000000..aa6344d --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/annotations/IgnoreVar.java @@ -0,0 +1,18 @@ +package net.endrealm.realmdrive.annotations; + +import net.endrealm.realmdrive.inst.SimpleConversionHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks a field to not be saved. + * + * @see SimpleConversionHandler + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface IgnoreVar { +} diff --git a/src/main/java/net/endrealm/realmdrive/annotations/ReadOnly.java b/src/main/java/net/endrealm/realmdrive/annotations/ReadOnly.java new file mode 100644 index 0000000..d0bed11 --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/annotations/ReadOnly.java @@ -0,0 +1,20 @@ +package net.endrealm.realmdrive.annotations; + +import net.endrealm.realmdrive.inst.SimpleConversionHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks a field to only be loaded not saved. + * Do not use {@link WriteOnly} together with this. + * To enable both read and write use {@link SaveVar}. + * + * @see SimpleConversionHandler + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ReadOnly { +} diff --git a/src/main/java/net/endrealm/realmdrive/annotations/SaveAll.java b/src/main/java/net/endrealm/realmdrive/annotations/SaveAll.java new file mode 100644 index 0000000..ee0447b --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/annotations/SaveAll.java @@ -0,0 +1,23 @@ +package net.endrealm.realmdrive.annotations; + +import net.endrealm.realmdrive.inst.SimpleConversionHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks all fields as to be saved. This can be + * overwritten by {@link SaveVar} and {@link IgnoreVar} + * + * @see SimpleConversionHandler + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SaveAll { + /** + * @return field names to be ignored + */ + String[] ignored() default {}; +} diff --git a/src/main/java/net/endrealm/realmdrive/annotations/SaveTable.java b/src/main/java/net/endrealm/realmdrive/annotations/SaveTable.java new file mode 100644 index 0000000..4da741c --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/annotations/SaveTable.java @@ -0,0 +1,20 @@ +package net.endrealm.realmdrive.annotations; + +import net.endrealm.realmdrive.inst.SimpleConversionHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used to overwrite default table. Table specified in query will overwrite this behaviour. + * + * @see SimpleConversionHandler + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SaveTable { + + String tableName() default ""; +} diff --git a/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java b/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java index 979ab40..4e83f7e 100644 --- a/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java +++ b/src/main/java/net/endrealm/realmdrive/annotations/SaveVar.java @@ -8,13 +8,31 @@ import java.lang.annotation.Target; /** - * @author johannesjumpertz - * Used to mark fields to be saved into the drive system. If other objects are linked, they have to be registered as well. + * + * Used to mark fields to be saved into the drive system. If + * other objects are linked, they have to be registered as + * well. + * + * Fields with this annotation will be both read and written. + * To control this behaviour add {@link ReadOnly} or {@link WriteOnly}. * * @see SimpleConversionHandler */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface SaveVar { + /** + * @return name to save/load under + */ + String name() default ""; + + /** + * @return optional names to load from + */ + String[] aliases() default {}; + + /** + * @return if false exception will be thrown upon null value + */ boolean optional() default true; } diff --git a/src/main/java/net/endrealm/realmdrive/annotations/WriteOnly.java b/src/main/java/net/endrealm/realmdrive/annotations/WriteOnly.java new file mode 100644 index 0000000..cac0cd9 --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/annotations/WriteOnly.java @@ -0,0 +1,20 @@ +package net.endrealm.realmdrive.annotations; + +import net.endrealm.realmdrive.inst.SimpleConversionHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks a field to only be saved not loaded. + * Do not use {@link ReadOnly} together with this. + * To enable both read and write use {@link SaveVar}. + * + * @see SimpleConversionHandler + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface WriteOnly { +} diff --git a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java index 4e90738..1390f62 100644 --- a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java +++ b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java @@ -7,6 +7,9 @@ import net.endrealm.realmdrive.factory.DriveObjectFactory; import net.endrealm.realmdrive.interfaces.*; import net.endrealm.realmdrive.utils.ReflectionUtils; +import net.endrealm.realmdrive.utils.properties.ClassProperties; +import net.endrealm.realmdrive.utils.properties.FieldProperties; +import net.endrealm.realmdrive.utils.properties.PropertyReader; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -112,23 +115,41 @@ public T transform(DriveObject statisticsObject, Class clazz) throws Clas throw new ClassCastException(String.format("Failed to cast! %s is not registered!", clazz.getName())); } + ClassProperties classProperties = PropertyReader.readProperties(clazz); + try { Constructor constructor = clazz.getConstructor(); T instance = constructor.newInstance(); - for(Field field : ReflectionUtils.getAllAnnotatedFields(clazz, SaveVar.class)) { - SaveVar saveVar = field.getAnnotation(SaveVar.class); + for(Field field : ReflectionUtils.getAllFields(clazz)) { + FieldProperties fieldProperties = PropertyReader.readProperties(field, classProperties); + + if(!fieldProperties.isRead()) + continue; boolean protection = field.isAccessible(); field.setAccessible(true); - DriveElement value = statisticsObject.get(field.getName()); + DriveElement value = statisticsObject.get(fieldProperties.getName()); + //TODO read from aliases + + // Read from aliases + { + int i = 0; + while(value == null) { + if(i >= fieldProperties.getAliases().size()) + break; + + value = statisticsObject.get(fieldProperties.getAliases().get(i)); + i++; + } + } // Value not found in object if(value == null) { // if this field is only optional skip it - if(saveVar.optional()) + if(fieldProperties.isOptional()) continue; throw new ClassCastException(String.format("Found unmapped field %s in %s!", field.getName(), field.getDeclaringClass().getName())); @@ -243,10 +264,9 @@ public DriveObject transform(Object object) throws ClassCastException { if(!classes.contains(clazz)) throw new ClassCastException(String.format("Failed to cast! %s is not registered!", clazz.getName())); - List fieldList = ReflectionUtils.getAllAnnotatedFields(clazz, SaveVar.class); + List fieldList = ReflectionUtils.getAllFields(clazz); - if(fieldList.isEmpty()) - throw new ClassCastException(String.format("Class %s must contain at least one field annotated with SaveVar", clazz.getName())); + ClassProperties classProperties = PropertyReader.readProperties(clazz); DriveObject statisticsObject = objectFactory.createEmptyObject(); @@ -255,7 +275,10 @@ public DriveObject transform(Object object) throws ClassCastException { statisticsObject.setPrimitive("className", object.getClass().getName()); for(Field field : fieldList) { - SaveVar saveVar = field.getAnnotation(SaveVar.class); + FieldProperties fieldProperties = PropertyReader.readProperties(field, classProperties); + + if(!fieldProperties.isWrite()) + continue; boolean protection = field.isAccessible(); field.setAccessible(true); @@ -265,7 +288,7 @@ public DriveObject transform(Object object) throws ClassCastException { if(value == null) { // if this field is only optional skip it - if(saveVar.optional()) + if(fieldProperties.isOptional()) continue; throw new ClassCastException(String.format("Found empty non optional field %s in %s!", field.getName(), field.getDeclaringClass().getName())); @@ -273,10 +296,10 @@ public DriveObject transform(Object object) throws ClassCastException { DriveElement driveElement = getElementEndpoint(value, value.getClass()); if(driveElement != null) { - statisticsObject.setObject(field.getName(), driveElement); + statisticsObject.setObject(fieldProperties.getName(), driveElement); } else if(PRIMITIVE_CLASSES.contains(value.getClass())) - statisticsObject.setObject(field.getName(), objectFactory.createPrimitive(value)); + statisticsObject.setObject(fieldProperties.getName(), objectFactory.createPrimitive(value)); else if(List.class.isAssignableFrom(field.getType())) { DriveElementArray array = objectFactory.createEmptyArray(); for(Object obj : (List)value) { @@ -285,10 +308,10 @@ else if(List.class.isAssignableFrom(field.getType())) { else array.addObject(transform(obj)); } - statisticsObject.setObject(field.getName(), array); + statisticsObject.setObject(fieldProperties.getName(), array); } else { - statisticsObject.setObject(field.getName(), transform(value)); + statisticsObject.setObject(fieldProperties.getName(), transform(value)); } field.setAccessible(protection); diff --git a/src/main/java/net/endrealm/realmdrive/inst/SimpleDriveWriter.java b/src/main/java/net/endrealm/realmdrive/inst/SimpleDriveWriter.java index bfb1664..9cfbee2 100644 --- a/src/main/java/net/endrealm/realmdrive/inst/SimpleDriveWriter.java +++ b/src/main/java/net/endrealm/realmdrive/inst/SimpleDriveWriter.java @@ -5,6 +5,8 @@ import net.endrealm.realmdrive.interfaces.DriveWriter; import net.endrealm.realmdrive.query.Query; import net.endrealm.realmdrive.utils.ThreadUtils; +import net.endrealm.realmdrive.utils.properties.ClassProperties; +import net.endrealm.realmdrive.utils.properties.PropertyReader; import java.util.function.Consumer; @@ -33,12 +35,16 @@ public void writeAsync(DriveObject element, Runnable onFinish) { @Override public void write(Object object) { - write(object, new Query()); + Query query = new Query().build(); + applyQueryChanges(object, query); + write(object, query); } @Override public void writeAsync(Object object, Runnable onFinish) { - writeAsync(object, new Query().build(), onFinish); + Query query = new Query().build(); + applyQueryChanges(object, query); + writeAsync(object, query, onFinish); } @@ -59,6 +65,8 @@ public void writeAsync(DriveObject element, Query query, Runnable onFinish) { @Override public void write(Object object, Query query) { + applyQueryChanges(object, query); + write(driveService.getConversionHandler().transform(object), query); } @@ -66,6 +74,8 @@ public void write(Object object, Query query) { public void writeAsync(Object object, Query query, Runnable onFinish) { ThreadUtils.createNewThread( () -> { + applyQueryChanges(object, query); + write(object, query); onFinish.run(); } @@ -111,6 +121,7 @@ public void writeAsync(DriveObject element, boolean overwrite, Query queryDetail */ @Override public void write(Object object, boolean overwrite, Query queryDetails) { + applyQueryChanges(object, queryDetails); write(driveService.getConversionHandler().transform(object), overwrite, queryDetails); } @@ -126,6 +137,7 @@ public void write(Object object, boolean overwrite, Query queryDetails) { public void writeAsync(Object object, boolean overwrite, Query queryDetails, Runnable onFinish) { ThreadUtils.createNewThread( () -> { + applyQueryChanges(object, queryDetails); write(object, overwrite, queryDetails); onFinish.run(); } @@ -147,6 +159,7 @@ public void replaceAsync(DriveObject element, Query queryDetails, Runnable onFin @Override public void replace(Object object, Query queryDetails) { + applyQueryChanges(object, queryDetails); replace(driveService.getConversionHandler().transform(object), queryDetails); } @@ -197,4 +210,10 @@ public void deleteAsync(Query queryDetails, int amount, Runnable onFinish) { public void setService(DriveService service) { this.driveService = service; } + + private void applyQueryChanges(Object object, Query query) { + ClassProperties classProperties = PropertyReader.readProperties(object.getClass()); + if(classProperties.getTableName() != null) + query.setTableName(classProperties.getTableName()); + } } diff --git a/src/main/java/net/endrealm/realmdrive/utils/ReflectionUtils.java b/src/main/java/net/endrealm/realmdrive/utils/ReflectionUtils.java index 07c46a8..42024cf 100644 --- a/src/main/java/net/endrealm/realmdrive/utils/ReflectionUtils.java +++ b/src/main/java/net/endrealm/realmdrive/utils/ReflectionUtils.java @@ -26,6 +26,16 @@ private static List getAllFields(List fields, Class type) { return fields; } + /** + * Retrieves all fields of a class. + * Method searches super classes as well. Fields can be private, protected, public or package private. + * @param type class to scan + * @return list of fields + */ + public static List getAllFields(Class type) { + return getAllFields(new ArrayList<>(), type); + } + /** * Finds all fields with at least one of the specified annotations. * Method searches super classes as well. Fields can be private, protected, public or package private. diff --git a/src/main/java/net/endrealm/realmdrive/utils/properties/ClassProperties.java b/src/main/java/net/endrealm/realmdrive/utils/properties/ClassProperties.java new file mode 100644 index 0000000..635c8cc --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/utils/properties/ClassProperties.java @@ -0,0 +1,12 @@ +package net.endrealm.realmdrive.utils.properties; + +import lombok.Data; + +import java.util.List; + +@Data +public class ClassProperties { + private final String tableName; + private final List ignoredFields; + private final boolean saveAll; +} diff --git a/src/main/java/net/endrealm/realmdrive/utils/properties/FieldProperties.java b/src/main/java/net/endrealm/realmdrive/utils/properties/FieldProperties.java new file mode 100644 index 0000000..f5b6a2c --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/utils/properties/FieldProperties.java @@ -0,0 +1,15 @@ +package net.endrealm.realmdrive.utils.properties; + +import lombok.Data; + +import java.util.List; + +@Data +public class FieldProperties { + private final boolean write; + private final boolean read; + private final String name; + private final List aliases; + private final boolean optional; + +} diff --git a/src/main/java/net/endrealm/realmdrive/utils/properties/PropertyReader.java b/src/main/java/net/endrealm/realmdrive/utils/properties/PropertyReader.java new file mode 100644 index 0000000..a25215d --- /dev/null +++ b/src/main/java/net/endrealm/realmdrive/utils/properties/PropertyReader.java @@ -0,0 +1,82 @@ +package net.endrealm.realmdrive.utils.properties; + +import net.endrealm.realmdrive.annotations.*; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Reads drive properties from class and fields + */ +public class PropertyReader { + + + public static ClassProperties readProperties(Class clazz) { + + SaveAll saveAll = clazz.getAnnotation(SaveAll.class); + SaveTable saveTable = clazz.getAnnotation(SaveTable.class); + + String tableName = null; + List ignoredFields = new ArrayList<>(); + boolean saveAllVariables = false; + + if(saveAll != null) { + saveAllVariables = true; + ignoredFields.addAll(Arrays.asList(saveAll.ignored())); + } + + if(saveTable != null) { + tableName = saveTable.tableName().equals("") ? null : saveTable.tableName(); + } + + return new ClassProperties(tableName, ignoredFields, saveAllVariables); + } + + public static FieldProperties readProperties(Field field, ClassProperties classProperties) { + IgnoreVar ignoreVar = field.getAnnotation(IgnoreVar.class); + SaveVar saveVar = field.getAnnotation(SaveVar.class); + ReadOnly readOnly = field.getAnnotation(ReadOnly.class); + WriteOnly writeOnly = field.getAnnotation(WriteOnly.class); + + + + boolean write = false; + boolean read = false; + String name = field.getName(); + List aliases = new ArrayList<>(); + boolean optional = true; + + if(saveVar != null) { + name = saveVar.name().equals("") ? field.getName() : saveVar.name(); + aliases.addAll(Arrays.asList(saveVar.aliases())); + optional = saveVar.optional(); + + read = true; + write = true; + } + + if(classProperties.isSaveAll()) { + read = true; + write = true; + } + + if(readOnly != null) { + read = true; + write = false; + } + if(writeOnly != null) { + write = true; + read = false; + } + + // Field is blacklisted so ignore it + if(ignoreVar != null || classProperties.getIgnoredFields().contains(field.getName())) { + read = false; + write = false; + } + + return new FieldProperties(write, read, name, aliases, optional); + } +} From c75c1f1cba5cca31d68cc91b060f14bae6057f7e Mon Sep 17 00:00:00 2001 From: Gerolmed Date: Sat, 5 Oct 2019 13:44:17 +0200 Subject: [PATCH 5/7] Added simple junit test for SaveAll annotation --- .../realmdrive/inst/SimpleConversionHandler.java | 1 - .../java/net/endrealm/realmdrive/model/Foo.java | 13 ++++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java index 1390f62..f5f6a7b 100644 --- a/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java +++ b/src/main/java/net/endrealm/realmdrive/inst/SimpleConversionHandler.java @@ -131,7 +131,6 @@ public T transform(DriveObject statisticsObject, Class clazz) throws Clas field.setAccessible(true); DriveElement value = statisticsObject.get(fieldProperties.getName()); - //TODO read from aliases // Read from aliases { diff --git a/src/test/java/net/endrealm/realmdrive/model/Foo.java b/src/test/java/net/endrealm/realmdrive/model/Foo.java index 9845c68..d72a12e 100644 --- a/src/test/java/net/endrealm/realmdrive/model/Foo.java +++ b/src/test/java/net/endrealm/realmdrive/model/Foo.java @@ -2,6 +2,9 @@ import lombok.Data; import lombok.EqualsAndHashCode; +import net.endrealm.realmdrive.annotations.IgnoreVar; +import net.endrealm.realmdrive.annotations.SaveAll; +import net.endrealm.realmdrive.annotations.SaveTable; import net.endrealm.realmdrive.annotations.SaveVar; import java.util.ArrayList; @@ -10,19 +13,19 @@ @EqualsAndHashCode(callSuper = true) @Data +@SaveAll +@SaveTable(tableName = "fooTable") public class Foo extends Choo { - @SaveVar private int value2; - @SaveVar private long value3; - @SaveVar private float value4; - @SaveVar private double value5; - @SaveVar private List bar; + @IgnoreVar + private final String aConstValue = "Great Right?"; + public Foo() { } From c9cc0974fc0b2ef35ad7577d752ce4005252080b Mon Sep 17 00:00:00 2001 From: Gerolmed Date: Sat, 5 Oct 2019 14:02:33 +0200 Subject: [PATCH 6/7] Added annotation docs --- docs/annotations.md | 65 +++++++++++++++++++++++++++++++++++++++++++++ docs/usage.md | 30 +-------------------- 2 files changed, 66 insertions(+), 29 deletions(-) create mode 100644 docs/annotations.md diff --git a/docs/annotations.md b/docs/annotations.md new file mode 100644 index 0000000..aabe4cf --- /dev/null +++ b/docs/annotations.md @@ -0,0 +1,65 @@ +# Using the annotations API +First thing for anything to work is register the affected classes. +```java +//service is the implementation of DriveService +ConversionHandler conversion = service.getConversionHandler(); +conversion.registerClasses(GreatEntity.class); +``` +If you forget doing this errors will occur. +## Simple field saving +Now that you have your service you will probably want to start mapping your first classes. As an example we will map the class `GreatEntity` here. +```java +@SaveAll +public class GreatEntity { + + //No-Args constructor is required, when reading values + public GreatEntity() { + this.feet = 2; + } + + public GreatEntity(String entityName, int age, String[] addresses, int feet) { + this.entityName = entityName; + this.age = age; + this.addresses = addresses; + this.feet = feet; + } + + private String entityName; + private int age; + private String[] addresses; + + private int feet; +} +``` + +## Advanced annotation handling + +`@SaveVar(properties)` | scope = Field +properties: +* name: String | default "" || name field will be saved under and loaded from. Leave empty for fieldName- +* aliases: String[] | default {} || A list of aliases this fields value might be saved under. Used when name not found +* optional: Boolean | default true || Is the field optional. If not class cannot be loaded without the value being asigned +> Fields marked with this will be saved and loaded under this value + + +`@SaveTable(properties)` | scope = Class +properties: +* value: String | default "" || table name to save under, if query does not force other +> Should be used to save the entity under a specific table. This will pregenerate a table depending on the backend type + +`@SaveAll(properties)` | scope = Class +properties: +* ignore: String[] | default {} || field names to ignore +> This will tell the program to save all fields. Note: @SaveVar and @IgnoreVar will overwrite this behaviour + + +`@IgnoreVar()` | scope = Field +> Fields marked with this will be ignored when saving and loading + +`@WriteOnly()` | scope = Field +> Fields marked with this will only be saved, but not loaded. Requires @SaveVar to do something + +`@ReadOnly()` | scope = Field +> Fields marked with this will only be loaded, but not saved. Requires @SaveVar to do something + +> **Note:** Having both ReadOnly and WriteOnly on a field will lead to unexpected behaviour and should be replaced by SaveVar \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md index 97f6614..0e8045d 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -50,35 +50,7 @@ DriveService service = new DriveServiceFactory().getDriveService(settings); ``` #### Marking fields -Now that you have your service you will probably want to start mapping your first classes. As an example we will map the class `GreatEntity` here. -```java -public class GreatEntity { - - //No-Args constructor is required, when reading values - public GreatEntity() { - this.feet = 2; - } - - public GreatEntity(String entityName, int age, String[] addresses, int feet) { - this.entityName = entityName; - this.age = age; - this.addresses = addresses; - this.feet = feet; - } - - @SaveVar - private String entityName; - - @SaveVar - private int age; - - @SaveVar - private String[] addresses; - - private int feet; -} -``` -**Note** All variables, but `feet` are annotated with @SaveVar. Only those annotated will be saved and retrieved. +Read more about it [here](./annotations.md) #### Register classes Now we will want to go ahead and tell the conversion handler that this class can be saved. This is required to automatically transform database entries to classes. While you will not be able to store them directly into the database you can define serializers that will allow you using them as fields. ```java From 398fcc9410ac12087b4ed37f54ce8d335e11fe3c Mon Sep 17 00:00:00 2001 From: Gerolmed Date: Sat, 5 Oct 2019 14:04:28 +0200 Subject: [PATCH 7/7] Update annotations.md --- docs/annotations.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/annotations.md b/docs/annotations.md index aabe4cf..bd1038e 100644 --- a/docs/annotations.md +++ b/docs/annotations.md @@ -57,9 +57,9 @@ properties: > Fields marked with this will be ignored when saving and loading `@WriteOnly()` | scope = Field -> Fields marked with this will only be saved, but not loaded. Requires @SaveVar to do something +> Fields marked with this will only be saved, but not loaded. `@ReadOnly()` | scope = Field -> Fields marked with this will only be loaded, but not saved. Requires @SaveVar to do something +> Fields marked with this will only be loaded, but not saved. -> **Note:** Having both ReadOnly and WriteOnly on a field will lead to unexpected behaviour and should be replaced by SaveVar \ No newline at end of file +> **Note:** Having both ReadOnly and WriteOnly on a field will lead to unexpected behaviour and should be replaced by SaveVar