From 99b832c8bd0941a28665d1730724d95cfaae5dd2 Mon Sep 17 00:00:00 2001 From: SaifJerbi Date: Sat, 27 Jan 2018 14:51:46 +0100 Subject: [PATCH 1/7] start working on displayAllFiels Initial commit adding the new annotation display the unannotated field --- .../io/asfjava/ui/core/form/DisplayAllFields.java | 13 +++++++++++++ .../ui/core/schema/UiFormSchemaGenerator.java | 14 ++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/io/asfjava/ui/core/form/DisplayAllFields.java diff --git a/src/main/java/io/asfjava/ui/core/form/DisplayAllFields.java b/src/main/java/io/asfjava/ui/core/form/DisplayAllFields.java new file mode 100644 index 0000000..daac57b --- /dev/null +++ b/src/main/java/io/asfjava/ui/core/form/DisplayAllFields.java @@ -0,0 +1,13 @@ +package io.asfjava.ui.core.form; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(TYPE) +public @interface DisplayAllFields { + +} diff --git a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java index 7e1e678..5b57bfd 100644 --- a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java +++ b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java @@ -15,6 +15,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -26,6 +27,7 @@ import io.asfjava.ui.core.FormDefinitionGeneratorFactory; import io.asfjava.ui.core.form.Action; import io.asfjava.ui.core.form.ActionsGroup; +import io.asfjava.ui.core.form.DisplayAllFields; import io.asfjava.ui.core.form.FieldSet; import io.asfjava.ui.core.form.Index; import io.asfjava.ui.core.form.Tab; @@ -62,11 +64,23 @@ public UiForm generate(Class formDto) throws JsonMapping tabbedFields.ifPresent(formDefinition::add); sortedNodes.entrySet().stream().forEach(nodesElement -> formDefinition.add(nodesElement.getValue())); + if (formDto.getDeclaredAnnotation(DisplayAllFields.class) != null) { + // check if fields is not handled and haven't jackson json ignore annotation + List unannotatedFiedls = Arrays.stream(declaredFields) + .filter(field -> !nodes.containsKey(field) && !field.isAnnotationPresent(JsonIgnore.class)) + .collect(Collectors.toList()); + handleUnAnnotatedFields(formDefinition, unannotatedFiedls); + } + handleActionsAnnotation(mapper, formDto, formDefinition); return new UiForm(schema, formDefinition); } + private void handleUnAnnotatedFields(ArrayNode formDefinition, List unannotatedFiedls) { + unannotatedFiedls.stream().forEach(field -> formDefinition.add(field.getName())); + } + private void handleActionsAnnotation(ObjectMapper mapper, Class formDto, ArrayNode formDefinition) { ObjectNode groupedActionsNode = mapper.createObjectNode(); From 2959ba23a1eb11c5e5b5c4ece2a0aaa940dee10c Mon Sep 17 00:00:00 2001 From: SaifJerbi Date: Sat, 27 Jan 2018 15:39:07 +0100 Subject: [PATCH 2/7] adding allfieldsDisplay support #75 cleaner solution --- demo/pom.xml | 2 +- .../ui/demo/renderer/UiDemoRenderer.java | 3 +- .../io/asfjava/ui/demo/screen/dto/Event.java | 46 +++++++++++++++++++ .../asfjava/ui/demo/screen/dto/Speaker.java | 31 +++++++++++++ pom.xml | 2 +- .../ui/core/schema/UiFormSchemaGenerator.java | 35 +++++++------- 6 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 demo/src/main/java/io/asfjava/ui/demo/screen/dto/Event.java create mode 100644 demo/src/main/java/io/asfjava/ui/demo/screen/dto/Speaker.java diff --git a/demo/pom.xml b/demo/pom.xml index a6d6ae9..0338a6a 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -38,7 +38,7 @@ io.sfjava.ui sf-java-ui - 1.0.0 + 1.1.0-SNAPSHOT diff --git a/demo/src/main/java/io/asfjava/ui/demo/renderer/UiDemoRenderer.java b/demo/src/main/java/io/asfjava/ui/demo/renderer/UiDemoRenderer.java index 85f2662..ff6fec1 100644 --- a/demo/src/main/java/io/asfjava/ui/demo/renderer/UiDemoRenderer.java +++ b/demo/src/main/java/io/asfjava/ui/demo/renderer/UiDemoRenderer.java @@ -6,11 +6,12 @@ import io.asfjava.ui.core.schema.UiFormSchemaGenerator; import io.asfjava.ui.demo.screen.DemoForm; +import io.asfjava.ui.demo.screen.dto.Event; import io.asfjava.ui.dto.UiForm; @Service public class UiDemoRenderer { public UiForm renderForm() throws JsonMappingException { - return UiFormSchemaGenerator.get().generate(DemoForm.class); + return UiFormSchemaGenerator.get().generate(Event.class); } } diff --git a/demo/src/main/java/io/asfjava/ui/demo/screen/dto/Event.java b/demo/src/main/java/io/asfjava/ui/demo/screen/dto/Event.java new file mode 100644 index 0000000..c0a3fb6 --- /dev/null +++ b/demo/src/main/java/io/asfjava/ui/demo/screen/dto/Event.java @@ -0,0 +1,46 @@ +package io.asfjava.ui.demo.screen.dto; + +import java.io.Serializable; + +import io.asfjava.ui.core.form.DisplayAllFields; +import io.asfjava.ui.core.form.Index; +import io.asfjava.ui.core.form.TextField; + +@DisplayAllFields +public class Event implements Serializable { + + @Index(0) + @TextField(title = "Title", placeHolder = "Event's title") + private String title; + + @Index(2) + @TextField(title = "Location", placeHolder = "Event's location") + private String location; + + @Index(1) + private Speaker speaker; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public Speaker getSpeaker() { + return speaker; + } + + public void setSpeaker(Speaker speaker) { + this.speaker = speaker; + } +} diff --git a/demo/src/main/java/io/asfjava/ui/demo/screen/dto/Speaker.java b/demo/src/main/java/io/asfjava/ui/demo/screen/dto/Speaker.java new file mode 100644 index 0000000..e05bc23 --- /dev/null +++ b/demo/src/main/java/io/asfjava/ui/demo/screen/dto/Speaker.java @@ -0,0 +1,31 @@ +package io.asfjava.ui.demo.screen.dto; + +public class Speaker { + private String fullName; + private String nationality; + private String description; + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getNationality() { + return nationality; + } + + public void setNationality(String nationality) { + this.nationality = nationality; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/pom.xml b/pom.xml index 9d359f7..56f5c3d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ io.sfjava.ui sf-java-ui - 1.0.1-SNAPSHOT + 1.1.0-SNAPSHOT jar sf-java-ui diff --git a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java index 5b57bfd..7ee519b 100644 --- a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java +++ b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java @@ -13,7 +13,6 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.function.Predicate; -import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonMappingException; @@ -62,25 +61,21 @@ public UiForm generate(Class formDto) throws JsonMapping ArrayNode formDefinition = mapper.createArrayNode(); tabbedFields.ifPresent(formDefinition::add); - sortedNodes.entrySet().stream().forEach(nodesElement -> formDefinition.add(nodesElement.getValue())); - - if (formDto.getDeclaredAnnotation(DisplayAllFields.class) != null) { - // check if fields is not handled and haven't jackson json ignore annotation - List unannotatedFiedls = Arrays.stream(declaredFields) - .filter(field -> !nodes.containsKey(field) && !field.isAnnotationPresent(JsonIgnore.class)) - .collect(Collectors.toList()); - handleUnAnnotatedFields(formDefinition, unannotatedFiedls); - } + + sortedNodes.entrySet().stream().forEach(nodesElement -> { + if (nodesElement.getValue() != null) { + formDefinition.add(nodesElement.getValue()); + } else if (formDto.getDeclaredAnnotation(DisplayAllFields.class) != null) { + // if no definition it must be added as key to the form definition + formDefinition.add(nodesElement.getKey().getName()); + } + }); handleActionsAnnotation(mapper, formDto, formDefinition); return new UiForm(schema, formDefinition); } - private void handleUnAnnotatedFields(ArrayNode formDefinition, List unannotatedFiedls) { - unannotatedFiedls.stream().forEach(field -> formDefinition.add(field.getName())); - } - private void handleActionsAnnotation(ObjectMapper mapper, Class formDto, ArrayNode formDefinition) { ObjectNode groupedActionsNode = mapper.createObjectNode(); @@ -180,6 +175,12 @@ private Map initFieldsFormDefinition(ObjectMapper mapper, Field Arrays.stream(declaredFields).forEach(field -> buildFormDefinition(nodes, mapper, field)); + // check if fields is not handled and haven't jackson json ignore annotation it + // must be added + Arrays.stream(declaredFields) + .filter(field -> !nodes.containsKey(field) && !field.isAnnotationPresent(JsonIgnore.class)) + .forEach(field -> nodes.put(field, null)); + return nodes; } @@ -229,9 +230,9 @@ private Map reorderFieldsBasedOnIndex(Map node field2Index != null ? field2Index.value() : Integer.MAX_VALUE); }; - return nodes.entrySet().stream().sorted(tabIndexComparator).collect(Collectors.toMap(Map.Entry::getKey, - Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); - + return nodes.entrySet().stream().sorted(tabIndexComparator).collect(LinkedHashMap::new, + (result, currentElement) -> result.put(currentElement.getKey(), currentElement.getValue()), + Map::putAll); } public static UiFormSchemaGenerator get() { From 1a9a127b013d81393c435b5995ff54ed11c13c6c Mon Sep 17 00:00:00 2001 From: almirus Date: Sun, 11 Mar 2018 21:48:13 +0300 Subject: [PATCH 3/7] remove code duplication add $ref support (external resource) for ComboBox --- .../io/asfjava/ui/core/form/ComboBox.java | 4 +- .../ui/core/generators/CheckBoxGenerator.java | 34 ++-------------- .../ui/core/generators/ComboBoxGenerator.java | 37 +++--------------- .../ui/core/generators/ListGenerator.java | 39 +++++++++++++++++++ 4 files changed, 51 insertions(+), 63 deletions(-) create mode 100644 src/main/java/io/asfjava/ui/core/generators/ListGenerator.java diff --git a/src/main/java/io/asfjava/ui/core/form/ComboBox.java b/src/main/java/io/asfjava/ui/core/form/ComboBox.java index 9d57f0b..816c5aa 100644 --- a/src/main/java/io/asfjava/ui/core/form/ComboBox.java +++ b/src/main/java/io/asfjava/ui/core/form/ComboBox.java @@ -38,7 +38,9 @@ boolean required() default false; int size() default 1; - + + String refURL() default ""; + Class titleMap() default ValuesContainer.class; } diff --git a/src/main/java/io/asfjava/ui/core/generators/CheckBoxGenerator.java b/src/main/java/io/asfjava/ui/core/generators/CheckBoxGenerator.java index f396c1c..3d62da7 100644 --- a/src/main/java/io/asfjava/ui/core/generators/CheckBoxGenerator.java +++ b/src/main/java/io/asfjava/ui/core/generators/CheckBoxGenerator.java @@ -12,7 +12,7 @@ import io.asfjava.ui.core.form.ValuesContainer; import io.asfjava.ui.core.logging.ASFUILogger; -public class CheckBoxGenerator implements FormDefinitionGenerator{ +public class CheckBoxGenerator extends ListGenerator implements FormDefinitionGenerator{ @Override public void generate(ObjectNode fieldFormDefinition, Field field) { @@ -25,39 +25,11 @@ public void generate(ObjectNode fieldFormDefinition, Field field) { ArrayNode titlesMap = checkBoxMapper.createArrayNode(); if (annotation.values().length > 0) { Arrays.stream(annotation.values()).forEach(value -> buildValueDefinition(checkBoxMapper, titlesMap, value)); - fieldFormDefinition.set("titleMap", titlesMap); } else if (!annotation.titleMap().equals(ValuesContainer.class)) { - - try { - Map map = (annotation.titleMap()).newInstance().getValues(); - map.entrySet().stream().forEach(mapEntry -> { - ObjectNode entryNode = checkBoxMapper.createObjectNode(); - entryNode.put("name", mapEntry.getKey()); - entryNode.putPOJO("value", mapEntry.getValue()); - titlesMap.add(entryNode); - }); - fieldFormDefinition.set("titleMap", titlesMap); - } catch (InstantiationException | IllegalAccessException e) { - ASFUILogger.getLogger().error(e.getMessage()); - throw new RuntimeException(e); - } - } - } - - private void buildValueDefinition(ObjectMapper checkBoxMapper, ArrayNode titlesMap, String value) { - ObjectNode entry = checkBoxMapper.createObjectNode(); - String upperCasedValue = value.toUpperCase(); - String lowerCasedValue = value.toLowerCase(); - if (value.equals(upperCasedValue)) { - entry.put("name", value.toLowerCase()); - } else if (value.equals(lowerCasedValue)) { - entry.put("name", value.replace(value.substring(0, 1), value.substring(0, 1).toUpperCase())); - } else { - entry.put("name", value); + buildValues(checkBoxMapper, titlesMap, annotation.titleMap()); + fieldFormDefinition.set("titleMap", titlesMap); } - entry.put("value", value); - titlesMap.add(entry); } @Override diff --git a/src/main/java/io/asfjava/ui/core/generators/ComboBoxGenerator.java b/src/main/java/io/asfjava/ui/core/generators/ComboBoxGenerator.java index cdf8a13..2761d6c 100644 --- a/src/main/java/io/asfjava/ui/core/generators/ComboBoxGenerator.java +++ b/src/main/java/io/asfjava/ui/core/generators/ComboBoxGenerator.java @@ -12,7 +12,7 @@ import io.asfjava.ui.core.form.ValuesContainer; import io.asfjava.ui.core.logging.ASFUILogger; -public class ComboBoxGenerator implements FormDefinitionGenerator { +public class ComboBoxGenerator extends ListGenerator implements FormDefinitionGenerator { @Override public void generate(ObjectNode fieldFormDefinition, Field field) { @@ -24,47 +24,22 @@ public void generate(ObjectNode fieldFormDefinition, Field field) { fieldFormDefinition.put("multiple", annotation.multiple()); fieldFormDefinition.put("required", annotation.required()); fieldFormDefinition.put("size", annotation.size()); + if (!annotation.refURL().isEmpty()) { + fieldFormDefinition.put("$ref", annotation.refURL()); + } ObjectMapper comboMapper = new ObjectMapper(); ArrayNode titlesMap = comboMapper.createArrayNode(); if (annotation.values().length != 0) { Arrays.stream(annotation.values()).forEach(value -> buildValueDefinition(comboMapper, titlesMap, value)); - fieldFormDefinition.set("titleMap", titlesMap); } else if (!annotation.titleMap().equals(ValuesContainer.class)) { - - try { - Map map = (annotation.titleMap()).newInstance().getValues(); - map.entrySet().stream().forEach(mapEntry -> { - ObjectNode entryNode = comboMapper.createObjectNode(); - entryNode.put("name", mapEntry.getKey()); - entryNode.putPOJO("value", mapEntry.getValue()); - titlesMap.add(entryNode); - }); - fieldFormDefinition.set("titleMap", titlesMap); - } catch (InstantiationException | IllegalAccessException e) { - ASFUILogger.getLogger().error(e.getMessage()); - throw new RuntimeException(e); - } + buildValues(comboMapper, titlesMap, annotation.titleMap()); + fieldFormDefinition.set("titleMap", titlesMap); } } - private void buildValueDefinition(ObjectMapper comboMapper, ArrayNode titlesMap, String value) { - ObjectNode entry = comboMapper.createObjectNode(); - String upperCasedValue = value.toUpperCase(); - String lowerCasedValue = value.toLowerCase(); - if (value.equals(upperCasedValue)) { - entry.put("name", value.toLowerCase()); - } else if (value.equals(lowerCasedValue)) { - entry.put("name", value.replace(value.substring(0, 1), value.substring(0, 1).toUpperCase())); - } else { - entry.put("name", value); - } - entry.put("value", value); - titlesMap.add(entry); - } - @Override public String getAnnotation() { return ComboBox.class.getName(); diff --git a/src/main/java/io/asfjava/ui/core/generators/ListGenerator.java b/src/main/java/io/asfjava/ui/core/generators/ListGenerator.java new file mode 100644 index 0000000..feeb402 --- /dev/null +++ b/src/main/java/io/asfjava/ui/core/generators/ListGenerator.java @@ -0,0 +1,39 @@ +package io.asfjava.ui.core.generators; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.asfjava.ui.core.form.ValuesContainer; +import io.asfjava.ui.core.logging.ASFUILogger; + +public class ListGenerator { + + protected void buildValueDefinition(ObjectMapper listMapper, ArrayNode titlesMap, String value) { + ObjectNode entry = listMapper.createObjectNode(); + String upperCasedValue = value.toUpperCase(); + String lowerCasedValue = value.toLowerCase(); + if (value.equals(upperCasedValue)) { + entry.put("name", value.toLowerCase()); + } else if (value.equals(lowerCasedValue)) { + entry.put("name", value.replace(value.substring(0, 1), value.substring(0, 1).toUpperCase())); + } else { + entry.put("name", value); + } + entry.put("value", value); + titlesMap.add(entry); + } + + protected void buildValues(ObjectMapper listMapper, ArrayNode titlesMap, Class valuesContainer) { + try { + valuesContainer.newInstance().getValues().forEach((key, value) -> { + ObjectNode entryNode = listMapper.createObjectNode(); + entryNode.put("name", key); + entryNode.putPOJO("value", value); + titlesMap.add(entryNode); + }); + } catch (InstantiationException | IllegalAccessException e) { + ASFUILogger.getLogger().error(e.getMessage()); + throw new RuntimeException(e); + } + } +} From 3b53beed5b9149347f911fead2b86f7ac901f83f Mon Sep 17 00:00:00 2001 From: Imed Ben Heni Date: Thu, 26 Apr 2018 16:43:51 +0100 Subject: [PATCH 4/7] Move classes inside the test classes --- .../ui/core/schema/CheckBoxFormTest.java | 25 +++---- .../ui/core/schema/ComboBoxFormTest.java | 29 ++++---- .../ui/core/schema/NumberFormTest.java | 70 +++++++++---------- .../ui/core/schema/PasswordFormTest.java | 40 +++++------ .../ui/core/schema/RadioBoxFormTest.java | 15 ++-- .../ui/core/schema/TabbedFormTest.java | 35 +++++----- .../ui/core/schema/TextAreaFormTest.java | 41 +++++------ .../ui/core/schema/TextFieldFormTest.java | 44 +++++------- 8 files changed, 141 insertions(+), 158 deletions(-) diff --git a/src/test/java/io/asfjava/ui/core/schema/CheckBoxFormTest.java b/src/test/java/io/asfjava/ui/core/schema/CheckBoxFormTest.java index 063cdef..f775e62 100644 --- a/src/test/java/io/asfjava/ui/core/schema/CheckBoxFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/CheckBoxFormTest.java @@ -65,24 +65,25 @@ public void testGenerate_CheckBox_WithCustomValuesContainer() throws JsonProcess Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='color')].titleMap[?(@.name=='Green')].value", hasItem("green"))); } -} -class CheckBoxForm implements Serializable { + private class CheckBoxForm implements Serializable { - @CheckBox(title = "Color", values = { "red", "blue", "green" }, defaultvalue = "red", required = true) - private String color; + @CheckBox(title = "Color", values = { "red", "blue", "green" }, defaultvalue = "red", required = true) + private String color; - public String getColor() { - return color; + public String getColor() { + return color; + } } -} -class CheckBoxForm2 implements Serializable { + private class CheckBoxForm2 implements Serializable { - @CheckBox(title = "Color", titleMap = MyCheckBoxValues.class, defaultvalue = "red", multiple = true) - private String color; + @CheckBox(title = "Color", titleMap = MyCheckBoxValues.class, defaultvalue = "red", multiple = true) + private String color; - public String getColor() { - return color; + public String getColor() { + return color; + } } } + diff --git a/src/test/java/io/asfjava/ui/core/schema/ComboBoxFormTest.java b/src/test/java/io/asfjava/ui/core/schema/ComboBoxFormTest.java index 14d04da..8095da0 100644 --- a/src/test/java/io/asfjava/ui/core/schema/ComboBoxFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/ComboBoxFormTest.java @@ -49,7 +49,6 @@ public void testGenerate_ComboBox() throws JsonProcessingException { hasJsonPath("$.form[?(@.key=='currency')].titleMap[?(@.name=='Euro')].value", hasItem("euro"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='currency')].titleMap[?(@.name=='Dollar')].value", hasItem("dollar"))); - } @Test @@ -67,28 +66,28 @@ public void testGenerate_ComboBox_WithCustomValuesContainer() throws JsonProcess hasJsonPath("$.form[?(@.key=='gender')].titleMap[?(@.name=='Male')].value", hasItem("male"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='gender')].titleMap[?(@.name=='Female')].value", hasItem("female"))); - } -} - -class ComboBoxForm implements Serializable { + private class ComboBoxForm implements Serializable { - @ComboBox(title = "Currency", values = { "euro", "dollar" }, required = true) - private String currency; + @ComboBox(title = "Currency", values = { "euro", "dollar" }, required = true) + private String currency; - public String getCurrency() { - return currency; + public String getCurrency() { + return currency; + } } -} -class ComboBoxForm2 implements Serializable { + private class ComboBoxForm2 implements Serializable { - @ComboBox(title = "Gender", titleMap = GenderTitleMap.class) - private String gender; + @ComboBox(title = "Gender", titleMap = GenderTitleMap.class) + private String gender; - public String getGender() { - return gender; + public String getGender() { + return gender; + } } } + + diff --git a/src/test/java/io/asfjava/ui/core/schema/NumberFormTest.java b/src/test/java/io/asfjava/ui/core/schema/NumberFormTest.java index a6f5931..1075ae8 100644 --- a/src/test/java/io/asfjava/ui/core/schema/NumberFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/NumberFormTest.java @@ -49,7 +49,6 @@ public void testGenerate_Number_For_Integer() throws JsonProcessingException { Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].type", hasItem("number"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].notitle", hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].readonly", hasItem(true))); - } @Test @@ -67,7 +66,6 @@ public void testGenerate_Number_For_Long() throws JsonProcessingException { Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].type", hasItem("number"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].notitle", hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].readonly", hasItem(true))); - } @@ -86,7 +84,6 @@ public void testGenerate_Number_For_Double() throws JsonProcessingException { Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].type", hasItem("number"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].notitle", hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].readonly", hasItem(true))); - } @Test @@ -102,7 +99,6 @@ public void testGenerate_Number_WithRightAddon() throws JsonProcessingException Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].notitle",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].readonly",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].fieldAddonRight",hasItem("@"))); - } @Test @@ -118,56 +114,56 @@ public void testGenerate_Number_WithLeftAddon() throws JsonProcessingException { Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].notitle",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].readonly",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='number')].fieldAddonLeft",hasItem("@"))); - } -} - -class IntegerNumberForm implements Serializable { + private class IntegerNumberForm implements Serializable { - @Number(title = "Integer Number", placeHolder = "Integer Number PlaceHolder", description = "This is an integer number", noTitle = true, validationMessage = "this is a validation msg for an integer value", readOnly = true) - private Integer number; + @Number(title = "Integer Number", placeHolder = "Integer Number PlaceHolder", description = "This is an integer number", noTitle = true, validationMessage = "this is a validation msg for an integer value", readOnly = true) + private Integer number; - public Integer getNumber() { - return number; + public Integer getNumber() { + return number; + } } -} -class NumberFormRight implements Serializable { + private class NumberFormRight implements Serializable { - @Number(title = "Number of children", placeHolder = "Number of children", fieldAddonRight = "@", description = "This is a number", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private Integer number; + @Number(title = "Number of children", placeHolder = "Number of children", fieldAddonRight = "@", description = "This is a number", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private Integer number; - public Integer getNumber() { - return number; - } -} + public Integer getNumber() { + return number; + } + } -class LongNumberForm implements Serializable { + private class LongNumberForm implements Serializable { - @Number(title = "Long Number", placeHolder = "Long Number PlaceHolder", description = "This is a long number", noTitle = true, validationMessage = "this is a validation msg for long value", readOnly = true) - private Long number; + @Number(title = "Long Number", placeHolder = "Long Number PlaceHolder", description = "This is a long number", noTitle = true, validationMessage = "this is a validation msg for long value", readOnly = true) + private Long number; - public Long getNumber() { - return number; + public Long getNumber() { + return number; + } } -} -class NumberFormLeft implements Serializable { + private class NumberFormLeft implements Serializable { - @Number(title = "Number of children", placeHolder = "Number of children", fieldAddonLeft = "@", description = "This is a number", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private Integer number; + @Number(title = "Number of children", placeHolder = "Number of children", fieldAddonLeft = "@", description = "This is a number", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private Integer number; - public Integer getNumber() { - return number; + public Integer getNumber() { + return number; + } } -} -class DoubleNumberForm implements Serializable { - @Number(title = "Double Number", placeHolder = "Double Number PlaceHolder", description = "This is a double number", noTitle = true, validationMessage = "this is a validation msg for double value", readOnly = true) - private Double number; + private class DoubleNumberForm implements Serializable { + + @Number(title = "Double Number", placeHolder = "Double Number PlaceHolder", description = "This is a double number", noTitle = true, validationMessage = "this is a validation msg for double value", readOnly = true) + private Double number; - public Double getNumber() { - return number; + public Double getNumber() { + return number; + } } } + diff --git a/src/test/java/io/asfjava/ui/core/schema/PasswordFormTest.java b/src/test/java/io/asfjava/ui/core/schema/PasswordFormTest.java index 296d940..cd15a8e 100644 --- a/src/test/java/io/asfjava/ui/core/schema/PasswordFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/PasswordFormTest.java @@ -67,7 +67,6 @@ public void testGenerate_Password_WithFieldAddonLeft() throws JsonProcessingExce Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='password')].notitle",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='password')].readonly",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='password')].fieldAddonLeft",hasItem("@"))); - } @Test @@ -85,37 +84,36 @@ public void testGenerate_Password_WithFieldAddonRight() throws JsonProcessingExc Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='password')].notitle",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='password')].readonly",hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='password')].fieldAddonRight",hasItem("@"))); - } -} - -class PasswordForm implements Serializable { + private class PasswordForm implements Serializable { - @Password(title = "Password", placeHolder = "Please set you password", pattern = "[a-z]", description = "This is password", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private String password; + @Password(title = "Password", placeHolder = "Please set you password", pattern = "[a-z]", description = "This is password", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private String password; - public String getPassword() { - return password; + public String getPassword() { + return password; + } } -} -class PasswordForm2 implements Serializable { + private class PasswordForm2 implements Serializable { - @Password(title = "Password", placeHolder = "Please set you password", pattern = "[a-z]",minLenght=6,maxLenght=10, fieldAddonRight = "@", description = "This is password", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private String password; + @Password(title = "Password", placeHolder = "Please set you password", pattern = "[a-z]",minLenght=6,maxLenght=10, fieldAddonRight = "@", description = "This is password", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private String password; - public String getPassword() { - return password; + public String getPassword() { + return password; + } } -} -class PasswordForm3 implements Serializable { + private class PasswordForm3 implements Serializable { - @Password(title = "Password", placeHolder = "Please set you password", pattern = "[a-z]",minLenght=6,maxLenght=10, fieldAddonLeft = "@", description = "This is password", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private String password; + @Password(title = "Password", placeHolder = "Please set you password", pattern = "[a-z]",minLenght=6,maxLenght=10, fieldAddonLeft = "@", description = "This is password", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private String password; - public String getPassword() { - return password; + public String getPassword() { + return password; + } } } + diff --git a/src/test/java/io/asfjava/ui/core/schema/RadioBoxFormTest.java b/src/test/java/io/asfjava/ui/core/schema/RadioBoxFormTest.java index 7a0bb47..57267b0 100644 --- a/src/test/java/io/asfjava/ui/core/schema/RadioBoxFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/RadioBoxFormTest.java @@ -47,17 +47,16 @@ public void testGenerate_RadioBox() throws JsonProcessingException { hasJsonPath("$.form[?(@.key=='civilState')].titleMap[?(@.name=='Single')].value", hasItem("HAPPY"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='civilState')].titleMap[?(@.name=='Divorced')].value", hasItem("RELEASED"))); - } -} - -class RadioBoxForm implements Serializable { + private class RadioBoxForm implements Serializable { - @RadioBox(title = "Civil State", titleMap = CivilStateValues.class) - private String civilState; + @RadioBox(title = "Civil State", titleMap = CivilStateValues.class) + private String civilState; - public String getCivilState() { - return civilState; + public String getCivilState() { + return civilState; + } } } + diff --git a/src/test/java/io/asfjava/ui/core/schema/TabbedFormTest.java b/src/test/java/io/asfjava/ui/core/schema/TabbedFormTest.java index 6cd0588..85f4ab1 100644 --- a/src/test/java/io/asfjava/ui/core/schema/TabbedFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/TabbedFormTest.java @@ -47,23 +47,22 @@ public void testGenerate_TabbedFormed() throws JsonProcessingException{ Assert.assertThat(json, hasJsonPath("$.form[?(@.tabs)].tabs[?(@.title=='Contact')].items[*]",hasSize(1))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='webSite')]")); } -} -class TabbedForm implements Serializable{ - - @Tab(title = "Info", index = 1) - @TextField(title = "First Name", placeHolder = "Your first name", description = "This is a description for your first name field") - private String firstName; - - @Tab(title = "Info", index = 1) - @TextField(title = "Last Name", placeHolder = "Your last name") - private String lastName; - - @Tab(title = "Contact", index = 2) - @TextField(title = "eMail", placeHolder = "Your email", pattern = "^\\S+@\\S+$", validationMessage = "Your mail must be in this format jhondoe@example.com", description = "This is Text Field with pattern and validation message") - private String email; - - @TextField(title = "Pesonal Website",fieldAddonLeft="http://", description = "This is TextField with fieldAddonLeft") - private String webSite; -} + private class TabbedForm implements Serializable{ + @Tab(title = "Info", index = 1) + @TextField(title = "First Name", placeHolder = "Your first name", description = "This is a description for your first name field") + private String firstName; + + @Tab(title = "Info", index = 1) + @TextField(title = "Last Name", placeHolder = "Your last name") + private String lastName; + + @Tab(title = "Contact", index = 2) + @TextField(title = "eMail", placeHolder = "Your email", pattern = "^\\S+@\\S+$", validationMessage = "Your mail must be in this format jhondoe@example.com", description = "This is Text Field with pattern and validation message") + private String email; + + @TextField(title = "Pesonal Website",fieldAddonLeft="http://", description = "This is TextField with fieldAddonLeft") + private String webSite; + } +} diff --git a/src/test/java/io/asfjava/ui/core/schema/TextAreaFormTest.java b/src/test/java/io/asfjava/ui/core/schema/TextAreaFormTest.java index f4cfd59..a71ae75 100644 --- a/src/test/java/io/asfjava/ui/core/schema/TextAreaFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/TextAreaFormTest.java @@ -50,7 +50,6 @@ public void testGenerate_TextArea() throws JsonProcessingException { // hasJsonPath("$.form[?(@.key=='password')].type",hasItem("textArea"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='address')].notitle", hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='address')].readonly", hasItem(true))); - } public void testGenerate_TextArea_WithFieldAddOnLeft() throws JsonProcessingException { @@ -71,8 +70,6 @@ public void testGenerate_TextArea_WithFieldAddOnLeft() throws JsonProcessingExce Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='address')].notitle", hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='address')].readonly", hasItem(true))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='address')].fieldAddonLeft", hasItem("@"))); - - } public void testGenerate_TextArea_WithFieldAddOnRight() throws JsonProcessingException { @@ -93,34 +90,34 @@ public void testGenerate_TextArea_WithFieldAddOnRight() throws JsonProcessingExc Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='address')].fieldAddonRight", hasItem("@"))); } -} - -class TextAreaForm2 implements Serializable { + private class TextAreaForm2 implements Serializable { - @TextArea(title = "Address", placeHolder = "Fill your address please", fieldAddonLeft = "@",minLenght=6,maxLenght=10, description = "This is textarea", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private String address; + @TextArea(title = "Address", placeHolder = "Fill your address please", fieldAddonLeft = "@",minLenght=6,maxLenght=10, description = "This is textarea", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private String address; - public String getAddress() { - return address; + public String getAddress() { + return address; + } } -} -class TextAreaForm3 implements Serializable { + private class TextAreaForm3 implements Serializable { - @TextArea(title = "Address", placeHolder = "Fill your address please",fieldAddonRight = "@",minLenght=6,maxLenght=10, description = "This is textarea", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private String address; + @TextArea(title = "Address", placeHolder = "Fill your address please",fieldAddonRight = "@",minLenght=6,maxLenght=10, description = "This is textarea", noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private String address; - public String getAddress() { - return address; + public String getAddress() { + return address; + } } -} -class TextAreaForm implements Serializable { + private class TextAreaForm implements Serializable { - @TextArea(title = "Address", placeHolder = "Fill your address please", description = "This is textarea",minLenght=6,maxLenght=10, noTitle = true, validationMessage = "this is a validation msg", readOnly = true) - private String address; + @TextArea(title = "Address", placeHolder = "Fill your address please", description = "This is textarea",minLenght=6,maxLenght=10, noTitle = true, validationMessage = "this is a validation msg", readOnly = true) + private String address; - public String getAddress() { - return address; + public String getAddress() { + return address; + } } } + diff --git a/src/test/java/io/asfjava/ui/core/schema/TextFieldFormTest.java b/src/test/java/io/asfjava/ui/core/schema/TextFieldFormTest.java index 8763a83..6e5c5eb 100644 --- a/src/test/java/io/asfjava/ui/core/schema/TextFieldFormTest.java +++ b/src/test/java/io/asfjava/ui/core/schema/TextFieldFormTest.java @@ -51,7 +51,6 @@ public void testGenerate_textField() throws JsonProcessingException { hasJsonPath("$.form[?(@.key=='firstName')].validationMessage", hasItem("this is a validation msg"))); // Assert.assertThat(json, // hasJsonPath("$.form[?(@.key=='firstName')].type",hasItem("textField"))); - } @Test @@ -70,7 +69,6 @@ public void testGenerate_textField_WithFieldAddonRight() throws JsonProcessingEx Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].validationMessage", hasItem("this is a validation msg"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].fieldAddonRight", hasItem("@"))); - } @Test @@ -87,42 +85,38 @@ public void testGenerate_textField_WithFieldAddonLeft() throws JsonProcessingExc Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].validationMessage", hasItem("this is a validation msg"))); Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].fieldAddonLeft", hasItem("@"))); - } -} - -class TextFieldForm implements Serializable { + private class TextFieldForm implements Serializable { - @TextField(title = "First Name", placeHolder = "Your first name", pattern = "[a-z]",minLenght=6,maxLenght=10, noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field", readOnly = true) - private String firstName; + @TextField(title = "First Name", placeHolder = "Your first name", pattern = "[a-z]",minLenght=6,maxLenght=10, noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field", readOnly = true) + private String firstName; - public String getFirstName() { - return firstName; + public String getFirstName() { + return firstName; + } } -} + private class TextFieldFormRight implements Serializable { -class TextFieldFormRight implements Serializable { + @TextField(title = "First Name", placeHolder = "Your first name", fieldAddonRight = "@", pattern = "[a-z]",minLenght=6,maxLenght=10, noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field") + private String firstName; - @TextField(title = "First Name", placeHolder = "Your first name", fieldAddonRight = "@", pattern = "[a-z]",minLenght=6,maxLenght=10, noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field") - private String firstName; - - public String getFirstName() { - return firstName; + public String getFirstName() { + return firstName; + } } -} - -class TextFieldFormLeft implements Serializable { + private class TextFieldFormLeft implements Serializable { - @TextField(title = "First Name", placeHolder = "Your first name", fieldAddonLeft = "@", pattern = "[a-z]", noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field") - private String firstName; + @TextField(title = "First Name", placeHolder = "Your first name", fieldAddonLeft = "@", pattern = "[a-z]", noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field") + private String firstName; - public String getFirstName() { - return firstName; + public String getFirstName() { + return firstName; + } } - } + From 9bd9c6ae73ce32dd72869c2ed1d4d984a8480e43 Mon Sep 17 00:00:00 2001 From: Imed Date: Sun, 29 Apr 2018 18:12:37 +0100 Subject: [PATCH 5/7] reorder singleton instances --- .../core/FormDefinitionGeneratorFactory.java | 26 +++++----- .../ui/core/GeneratorFactoryInitializer.java | 2 +- .../ui/core/GeneratorFactoryLoader.java | 49 ++++++++---------- .../java/io/asfjava/ui/core/SFJavaUi.java | 5 +- .../ui/core/SchemaDecoratorFactory.java | 29 ++++++----- .../ui/core/SchemaDecoratorLoader.java | 50 ++++++++----------- 6 files changed, 73 insertions(+), 88 deletions(-) diff --git a/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java b/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java index 278c5d4..26ac79e 100644 --- a/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java +++ b/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java @@ -9,25 +9,23 @@ public final class FormDefinitionGeneratorFactory { - public Optional getGenerator(String annotationName) { - return Optional.ofNullable(GENERATORS.get(annotationName)); - } - - void register(Supplier annotationName, FormDefinitionGenerator generator) { - GENERATORS.put(annotationName.get(), generator); - } + private static FormDefinitionGeneratorFactory instance; public static FormDefinitionGeneratorFactory getInstance() { - if (instance == null) { - instance = new FormDefinitionGeneratorFactory(); - } - return instance; + return (instance == null) + ? instance = new FormDefinitionGeneratorFactory() + : instance; } - private static final Map GENERATORS = new ConcurrentHashMap<>(); + private final Map generators = new ConcurrentHashMap<>(); - private static FormDefinitionGeneratorFactory instance; + private FormDefinitionGeneratorFactory() {} - private FormDefinitionGeneratorFactory() { + public Optional getGenerator(String annotationName) { + return Optional.ofNullable(generators.get(annotationName)); + } + + void register(Supplier annotationName, FormDefinitionGenerator generator) { + generators.put(annotationName.get(), generator); } } diff --git a/src/main/java/io/asfjava/ui/core/GeneratorFactoryInitializer.java b/src/main/java/io/asfjava/ui/core/GeneratorFactoryInitializer.java index 7ea57d6..391bc44 100644 --- a/src/main/java/io/asfjava/ui/core/GeneratorFactoryInitializer.java +++ b/src/main/java/io/asfjava/ui/core/GeneratorFactoryInitializer.java @@ -14,6 +14,6 @@ public final void contextInitialized(final ServletContextEvent sce) { @Override public final void contextDestroyed(final ServletContextEvent sce) { - // to implement it + // TODO to implement } } diff --git a/src/main/java/io/asfjava/ui/core/GeneratorFactoryLoader.java b/src/main/java/io/asfjava/ui/core/GeneratorFactoryLoader.java index fe00f59..e234b4f 100644 --- a/src/main/java/io/asfjava/ui/core/GeneratorFactoryLoader.java +++ b/src/main/java/io/asfjava/ui/core/GeneratorFactoryLoader.java @@ -1,23 +1,34 @@ package io.asfjava.ui.core; +import io.asfjava.ui.core.generators.FormDefinitionGenerator; +import io.asfjava.ui.core.logging.ASFUILogger; +import org.reflections.Reflections; + import static io.asfjava.ui.core.logging.ErrorCode.ASF01; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; +final class GeneratorFactoryLoader { -import org.reflections.Reflections; + private static final String[] PACKAGES_TO_SCAN = { + "io.asfjava.ui.core.generators", + "io.asfjava.ui.addons.generators" + }; + private static Reflections reflections = new Reflections(PACKAGES_TO_SCAN); + private static GeneratorFactoryLoader instance; -import io.asfjava.ui.core.generators.FormDefinitionGenerator; -import io.asfjava.ui.core.logging.ASFUILogger; + static GeneratorFactoryLoader getInstance() { + return (instance == null) + ? instance = new GeneratorFactoryLoader() + : instance; + } -final class GeneratorFactoryLoader { - private static final List PACKAGESCAN = Stream - .of("io.asfjava.ui.core.generators", "io.asfjava.ui.addons.generators").collect(Collectors.toList()); - private static Reflections reflections = new Reflections(PACKAGESCAN); + private GeneratorFactoryLoader() {} void load() { - reflections.getSubTypesOf(FormDefinitionGenerator.class).forEach(instance::register); + reflections.getSubTypesOf(FormDefinitionGenerator.class).forEach(this::register); + } + + void unload() { + ASFUILogger.getLogger().info("I'm unloader"); } private void register(Class subType) { @@ -29,20 +40,4 @@ private void register(Class subType) { ASFUILogger.getLogger().error(ASF01, e); } } - - void unload() { - ASFUILogger.getLogger().info("I'm unloader"); - } - - static GeneratorFactoryLoader getInstance() { - if (instance == null) - instance = new GeneratorFactoryLoader(); - return instance; - } - - private static GeneratorFactoryLoader instance; - - private GeneratorFactoryLoader() { - } - } diff --git a/src/main/java/io/asfjava/ui/core/SFJavaUi.java b/src/main/java/io/asfjava/ui/core/SFJavaUi.java index 4b2c73c..02c4706 100644 --- a/src/main/java/io/asfjava/ui/core/SFJavaUi.java +++ b/src/main/java/io/asfjava/ui/core/SFJavaUi.java @@ -6,7 +6,6 @@ public static void initialize(){ GeneratorFactoryLoader.getInstance().load(); SchemaDecoratorLoader.getInstance().load(); } - - private SFJavaUi() { - } + + private SFJavaUi() {} } diff --git a/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java b/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java index 553c817..d264678 100644 --- a/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java +++ b/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java @@ -1,32 +1,31 @@ package io.asfjava.ui.core; +import io.asfjava.ui.core.schema.decorators.SchemaDecorator; + import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; -import io.asfjava.ui.core.schema.decorators.SchemaDecorator; - public final class SchemaDecoratorFactory { - public Optional getDecorator(String annotationName) { - return Optional.ofNullable(decorators.get(annotationName)); - } - void register(Supplier annotationName, SchemaDecorator generator) { - decorators.put(annotationName.get(), generator); - } + private static SchemaDecoratorFactory instance; public static SchemaDecoratorFactory getInstance() { - if (instance == null) { - instance = new SchemaDecoratorFactory(); - } - return instance; + return (instance == null) + ? instance = new SchemaDecoratorFactory() + : instance; } - private static final Map decorators = new ConcurrentHashMap<>(); + private final Map decorators = new ConcurrentHashMap<>(); - private static SchemaDecoratorFactory instance; + private SchemaDecoratorFactory() {} - private SchemaDecoratorFactory() { + public Optional getDecorator(String annotationName) { + return Optional.ofNullable(decorators.get(annotationName)); + } + + void register(Supplier annotationName, SchemaDecorator generator) { + decorators.put(annotationName.get(), generator); } } diff --git a/src/main/java/io/asfjava/ui/core/SchemaDecoratorLoader.java b/src/main/java/io/asfjava/ui/core/SchemaDecoratorLoader.java index 1cf515a..5ee19e6 100644 --- a/src/main/java/io/asfjava/ui/core/SchemaDecoratorLoader.java +++ b/src/main/java/io/asfjava/ui/core/SchemaDecoratorLoader.java @@ -1,25 +1,34 @@ package io.asfjava.ui.core; -import static io.asfjava.ui.core.logging.ErrorCode.ASF01; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.reflections.Reflections; - import io.asfjava.ui.core.logging.ASFUILogger; import io.asfjava.ui.core.schema.decorators.SchemaDecorator; +import org.reflections.Reflections; + +import static io.asfjava.ui.core.logging.ErrorCode.ASF01; final class SchemaDecoratorLoader { - private static final List PACKAGESCAN = Stream - .of("io.asfjava.ui.core.schema.decorators", "io.asfjava.ui.addons.schema.decorators") - .collect(Collectors.toList()); - private static Reflections reflections = new Reflections(PACKAGESCAN); + private static final String[] PACKAGES_TO_SCAN = { + "io.asfjava.ui.core.schema.decorators", + "io.asfjava.ui.addons.schema.decorators" + }; + private static Reflections reflections = new Reflections(PACKAGES_TO_SCAN); + private static SchemaDecoratorLoader instance; + + static SchemaDecoratorLoader getInstance() { + return (instance == null) + ? instance = new SchemaDecoratorLoader() + : instance; + } + + private SchemaDecoratorLoader() {} void load() { - reflections.getSubTypesOf(SchemaDecorator.class).forEach(instance::register); + reflections.getSubTypesOf(SchemaDecorator.class).forEach(this::register); + } + + void unload() { + ASFUILogger.getLogger().info("I'm unloader"); } private void register(Class subType) { @@ -30,19 +39,4 @@ private void register(Class subType) { ASFUILogger.getLogger().error(ASF01, e); } } - - void unload() { - ASFUILogger.getLogger().info("I'm unloader"); - } - - static SchemaDecoratorLoader getInstance() { - if (instance == null) - instance = new SchemaDecoratorLoader(); - return instance; - } - - private static SchemaDecoratorLoader instance; - - private SchemaDecoratorLoader() { - } } From 453d6ac9c21b9993d9b49978c3ebdd028926a099 Mon Sep 17 00:00:00 2001 From: Imed Ben Heni Date: Mon, 30 Apr 2018 10:43:42 +0100 Subject: [PATCH 6/7] Create SimpleFactory to remove some duplication between existing factories --- .../core/FormDefinitionGeneratorFactory.java | 17 +---------------- .../ui/core/SchemaDecoratorFactory.java | 17 +---------------- .../io/asfjava/ui/core/SimpleFactory.java | 19 +++++++++++++++++++ .../ui/core/schema/SchemaDecoratorUtil.java | 2 +- .../ui/core/schema/UiFormSchemaGenerator.java | 2 +- 5 files changed, 23 insertions(+), 34 deletions(-) create mode 100644 src/main/java/io/asfjava/ui/core/SimpleFactory.java diff --git a/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java b/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java index 26ac79e..81f7416 100644 --- a/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java +++ b/src/main/java/io/asfjava/ui/core/FormDefinitionGeneratorFactory.java @@ -1,13 +1,8 @@ package io.asfjava.ui.core; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; - import io.asfjava.ui.core.generators.FormDefinitionGenerator; -public final class FormDefinitionGeneratorFactory { +public final class FormDefinitionGeneratorFactory extends SimpleFactory { private static FormDefinitionGeneratorFactory instance; @@ -17,15 +12,5 @@ public static FormDefinitionGeneratorFactory getInstance() { : instance; } - private final Map generators = new ConcurrentHashMap<>(); - private FormDefinitionGeneratorFactory() {} - - public Optional getGenerator(String annotationName) { - return Optional.ofNullable(generators.get(annotationName)); - } - - void register(Supplier annotationName, FormDefinitionGenerator generator) { - generators.put(annotationName.get(), generator); - } } diff --git a/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java b/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java index d264678..52ca93a 100644 --- a/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java +++ b/src/main/java/io/asfjava/ui/core/SchemaDecoratorFactory.java @@ -2,12 +2,7 @@ import io.asfjava.ui.core.schema.decorators.SchemaDecorator; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; - -public final class SchemaDecoratorFactory { +public final class SchemaDecoratorFactory extends SimpleFactory { private static SchemaDecoratorFactory instance; @@ -17,15 +12,5 @@ public static SchemaDecoratorFactory getInstance() { : instance; } - private final Map decorators = new ConcurrentHashMap<>(); - private SchemaDecoratorFactory() {} - - public Optional getDecorator(String annotationName) { - return Optional.ofNullable(decorators.get(annotationName)); - } - - void register(Supplier annotationName, SchemaDecorator generator) { - decorators.put(annotationName.get(), generator); - } } diff --git a/src/main/java/io/asfjava/ui/core/SimpleFactory.java b/src/main/java/io/asfjava/ui/core/SimpleFactory.java new file mode 100644 index 0000000..f906222 --- /dev/null +++ b/src/main/java/io/asfjava/ui/core/SimpleFactory.java @@ -0,0 +1,19 @@ +package io.asfjava.ui.core; + +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; + +public abstract class SimpleFactory { + + private final Map map = new ConcurrentHashMap<>(); + + public Optional get(K key) { + return Optional.ofNullable(map.get(key)); + } + + void register(Supplier key, V value) { + map.put(key.get(), value); + } +} diff --git a/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java b/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java index 3309091..cff40b7 100644 --- a/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java +++ b/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java @@ -12,7 +12,7 @@ final class SchemaDecoratorUtil { void decorate(BeanProperty beanProperty, JsonSchema simpleTypeSchema) { Iterable it = beanProperty.getMember().annotations(); it.forEach( - annotation -> SchemaDecoratorFactory.getInstance().getDecorator(annotation.annotationType().getName()) + annotation -> SchemaDecoratorFactory.getInstance().get(annotation.annotationType().getName()) .ifPresent(decorator -> decorator.customizeSchema(beanProperty, simpleTypeSchema))); } diff --git a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java index 7ee519b..510234a 100644 --- a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java +++ b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java @@ -212,7 +212,7 @@ private void buildFormDefinition(Map nodes, ObjectMapper mapper private void buildFieldDefinition(Field field, Annotation annotation, ObjectMapper mapper, Map nodes) { ObjectNode fieldFormDefinition = mapper.createObjectNode(); - FormDefinitionGeneratorFactory.getInstance().getGenerator(annotation.annotationType().getName()) + FormDefinitionGeneratorFactory.getInstance().get(annotation.annotationType().getName()) .ifPresent(generator -> { generator.generate(fieldFormDefinition, field); nodes.put(field, fieldFormDefinition); From 5fee860ca293edaa57a7ec4704e0cef3b28a00e4 Mon Sep 17 00:00:00 2001 From: Imed Ben Heni Date: Mon, 30 Apr 2018 16:18:45 +0100 Subject: [PATCH 7/7] rename SchemaDecoratorUtil to SchemaDecoratorHandler and remove its Singleton --- .../ui/core/schema/CustomIntegerSchema.java | 9 +++++- .../core/schema/CustomJsonSchemaFactory.java | 13 ++++++-- .../ui/core/schema/CustomNumberSchema.java | 9 +++++- .../schema/CustomSchemaFactoryWrapper.java | 18 +++++++---- .../ui/core/schema/CustomStringSchema.java | 9 ++++-- .../core/schema/SchemaDecoratorHandler.java | 29 ++++++++++++++++++ .../ui/core/schema/SchemaDecoratorUtil.java | 30 ------------------- .../ui/core/schema/UiFormSchemaGenerator.java | 25 +++++++++------- 8 files changed, 88 insertions(+), 54 deletions(-) create mode 100644 src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorHandler.java delete mode 100644 src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java diff --git a/src/main/java/io/asfjava/ui/core/schema/CustomIntegerSchema.java b/src/main/java/io/asfjava/ui/core/schema/CustomIntegerSchema.java index 322ee02..bce8983 100644 --- a/src/main/java/io/asfjava/ui/core/schema/CustomIntegerSchema.java +++ b/src/main/java/io/asfjava/ui/core/schema/CustomIntegerSchema.java @@ -4,9 +4,16 @@ import com.fasterxml.jackson.module.jsonSchema.types.IntegerSchema; class CustomIntegerSchema extends IntegerSchema { + + private final SchemaDecoratorHandler schemaDecoratorHandler; + + CustomIntegerSchema(SchemaDecoratorHandler schemaDecoratorHandler) { + this.schemaDecoratorHandler = schemaDecoratorHandler; + } + @Override public void enrichWithBeanProperty(BeanProperty beanProperty) { super.enrichWithBeanProperty(beanProperty); - SchemaDecoratorUtil.get().decorate(beanProperty, this); + schemaDecoratorHandler.decorate(beanProperty, this); } } diff --git a/src/main/java/io/asfjava/ui/core/schema/CustomJsonSchemaFactory.java b/src/main/java/io/asfjava/ui/core/schema/CustomJsonSchemaFactory.java index 62c6b7d..41f7931 100644 --- a/src/main/java/io/asfjava/ui/core/schema/CustomJsonSchemaFactory.java +++ b/src/main/java/io/asfjava/ui/core/schema/CustomJsonSchemaFactory.java @@ -6,18 +6,25 @@ import com.fasterxml.jackson.module.jsonSchema.types.StringSchema; class CustomJsonSchemaFactory extends JsonSchemaFactory { + + private final SchemaDecoratorHandler schemaDecoratorHandler; + + CustomJsonSchemaFactory(SchemaDecoratorHandler schemaDecoratorHandler) { + this.schemaDecoratorHandler = schemaDecoratorHandler; + } + @Override public StringSchema stringSchema() { - return new CustomStringSchema(); + return new CustomStringSchema(schemaDecoratorHandler); } @Override public NumberSchema numberSchema() { - return new CustomNumberSchema(); + return new CustomNumberSchema(schemaDecoratorHandler); } @Override public IntegerSchema integerSchema() { - return new CustomIntegerSchema(); + return new CustomIntegerSchema(schemaDecoratorHandler); } } diff --git a/src/main/java/io/asfjava/ui/core/schema/CustomNumberSchema.java b/src/main/java/io/asfjava/ui/core/schema/CustomNumberSchema.java index cf6dbb7..cb274b2 100644 --- a/src/main/java/io/asfjava/ui/core/schema/CustomNumberSchema.java +++ b/src/main/java/io/asfjava/ui/core/schema/CustomNumberSchema.java @@ -4,9 +4,16 @@ import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema; class CustomNumberSchema extends NumberSchema { + + private final SchemaDecoratorHandler schemaDecoratorHandler; + + CustomNumberSchema(SchemaDecoratorHandler schemaDecoratorHandler) { + this.schemaDecoratorHandler = schemaDecoratorHandler; + } + @Override public void enrichWithBeanProperty(BeanProperty beanProperty) { super.enrichWithBeanProperty(beanProperty); - SchemaDecoratorUtil.get().decorate(beanProperty, this); + schemaDecoratorHandler.decorate(beanProperty, this); } } diff --git a/src/main/java/io/asfjava/ui/core/schema/CustomSchemaFactoryWrapper.java b/src/main/java/io/asfjava/ui/core/schema/CustomSchemaFactoryWrapper.java index ee82823..cf8881b 100644 --- a/src/main/java/io/asfjava/ui/core/schema/CustomSchemaFactoryWrapper.java +++ b/src/main/java/io/asfjava/ui/core/schema/CustomSchemaFactoryWrapper.java @@ -7,11 +7,22 @@ class CustomSchemaFactoryWrapper extends SchemaFactoryWrapper { + CustomSchemaFactoryWrapper(SchemaDecoratorHandler schemaDecoratorHandler) { + super(new SFSchemaFactoryWrapperFactory(schemaDecoratorHandler)); + schemaProvider = new CustomJsonSchemaFactory(schemaDecoratorHandler); + } + private static class SFSchemaFactoryWrapperFactory extends WrapperFactory { + private final SchemaDecoratorHandler schemaDecoratorHandler; + + private SFSchemaFactoryWrapperFactory(SchemaDecoratorHandler schemaDecoratorHandler) { + this.schemaDecoratorHandler = schemaDecoratorHandler; + } + @Override public SchemaFactoryWrapper getWrapper(SerializerProvider p, VisitorContext rvc) { - SchemaFactoryWrapper wrapper = new CustomSchemaFactoryWrapper(); + SchemaFactoryWrapper wrapper = new CustomSchemaFactoryWrapper(schemaDecoratorHandler); if (p != null) { wrapper.setProvider(p); } @@ -19,9 +30,4 @@ public SchemaFactoryWrapper getWrapper(SerializerProvider p, VisitorContext rvc) return wrapper; } } - - CustomSchemaFactoryWrapper() { - super(new SFSchemaFactoryWrapperFactory()); - schemaProvider = new CustomJsonSchemaFactory(); - } } \ No newline at end of file diff --git a/src/main/java/io/asfjava/ui/core/schema/CustomStringSchema.java b/src/main/java/io/asfjava/ui/core/schema/CustomStringSchema.java index 187a72b..e0aa077 100644 --- a/src/main/java/io/asfjava/ui/core/schema/CustomStringSchema.java +++ b/src/main/java/io/asfjava/ui/core/schema/CustomStringSchema.java @@ -5,10 +5,15 @@ class CustomStringSchema extends StringSchema { + private final SchemaDecoratorHandler schemaDecoratorHandler; + + CustomStringSchema(SchemaDecoratorHandler schemaDecoratorHandler) { + this.schemaDecoratorHandler = schemaDecoratorHandler; + } + @Override public void enrichWithBeanProperty(BeanProperty beanProperty) { super.enrichWithBeanProperty(beanProperty); - SchemaDecoratorUtil.get().decorate(beanProperty, this); + schemaDecoratorHandler.decorate(beanProperty, this); } - } diff --git a/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorHandler.java b/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorHandler.java new file mode 100644 index 0000000..9492848 --- /dev/null +++ b/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorHandler.java @@ -0,0 +1,29 @@ +package io.asfjava.ui.core.schema; + +import java.lang.annotation.Annotation; +import java.util.Optional; + +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.module.jsonSchema.JsonSchema; + +import io.asfjava.ui.core.SchemaDecoratorFactory; +import io.asfjava.ui.core.schema.decorators.SchemaDecorator; + +final class SchemaDecoratorHandler { + + SchemaDecoratorHandler() {} + + void decorate(BeanProperty beanProperty, JsonSchema simpleTypeSchema) { + beanProperty.getMember().annotations() + .forEach(annotation -> decorate(beanProperty, simpleTypeSchema, annotation)); + } + + private void decorate(BeanProperty beanProperty, JsonSchema simpleTypeSchema, Annotation annotation) { + getDecorator(annotation) + .ifPresent(decorator -> decorator.customizeSchema(beanProperty, simpleTypeSchema)); + } + + private Optional getDecorator(Annotation annotation) { + return SchemaDecoratorFactory.getInstance().get(annotation.annotationType().getName()); + } +} diff --git a/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java b/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java deleted file mode 100644 index cff40b7..0000000 --- a/src/main/java/io/asfjava/ui/core/schema/SchemaDecoratorUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.asfjava.ui.core.schema; - -import java.lang.annotation.Annotation; - -import com.fasterxml.jackson.databind.BeanProperty; -import com.fasterxml.jackson.module.jsonSchema.JsonSchema; - -import io.asfjava.ui.core.SchemaDecoratorFactory; - -final class SchemaDecoratorUtil { - - void decorate(BeanProperty beanProperty, JsonSchema simpleTypeSchema) { - Iterable it = beanProperty.getMember().annotations(); - it.forEach( - annotation -> SchemaDecoratorFactory.getInstance().get(annotation.annotationType().getName()) - .ifPresent(decorator -> decorator.customizeSchema(beanProperty, simpleTypeSchema))); - } - - static SchemaDecoratorUtil get() { - if (instance == null) { - instance = new SchemaDecoratorUtil(); - } - return instance; - } - - private static SchemaDecoratorUtil instance; - - private SchemaDecoratorUtil() { - } -} diff --git a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java index 510234a..3f2219d 100644 --- a/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java +++ b/src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java @@ -41,8 +41,21 @@ public final class UiFormSchemaGenerator { private static final String KEY_TITLE = "title"; private static final String KEY_TYPE = "type"; private static final String KEY_ITEMS = "items"; + private static UiFormSchemaGenerator instance; + public static UiFormSchemaGenerator get() { + return (instance == null) + ? instance = new UiFormSchemaGenerator() + : instance; + } + + private final SchemaDecoratorHandler schemaDecoratorHandler; + + private UiFormSchemaGenerator() { + schemaDecoratorHandler = new SchemaDecoratorHandler(); + } + public UiForm generate(Class formDto) throws JsonMappingException { Field[] declaredFields = formDto.getDeclaredFields(); ObjectMapper mapper = new ObjectMapper(); @@ -190,7 +203,7 @@ private JsonSchema generateSchema(Class formDto, JsonSch } private JsonSchemaGenerator initSchemaGen(ObjectMapper mapper) { - return new JsonSchemaGenerator(mapper, new CustomSchemaFactoryWrapper()); + return new JsonSchemaGenerator(mapper, new CustomSchemaFactoryWrapper(schemaDecoratorHandler)); } private void groupFieldsByTab(Map nodes, Field field, Map> groupedFields) { @@ -234,14 +247,4 @@ private Map reorderFieldsBasedOnIndex(Map node (result, currentElement) -> result.put(currentElement.getKey(), currentElement.getValue()), Map::putAll); } - - public static UiFormSchemaGenerator get() { - if (instance == null) { - instance = new UiFormSchemaGenerator(); - } - return instance; - } - - private UiFormSchemaGenerator() { - } }