From 243a1e2fe799ec2e4ff60a88c233926f354ba537 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Fri, 11 Jun 2021 17:14:14 +0200 Subject: [PATCH 1/5] feat: Implement DTO annotation --- .../fulib/builder/ReflectiveClassBuilder.java | 85 +++++++++++++------ .../java/org/fulib/builder/reflect/DTO.java | 13 +++ 2 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 src/main/java/org/fulib/builder/reflect/DTO.java diff --git a/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java b/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java index c9575f55..d3831eef 100644 --- a/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java +++ b/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java @@ -10,18 +10,34 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.fulib.builder.Type.MANY; -import static org.fulib.builder.Type.ONE; +import static org.fulib.builder.Type.*; class ReflectiveClassBuilder { private static final String ID_PATTERN = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"; private static final Pattern CLASS_PATTERN = Pattern.compile(ID_PATTERN + "(?:\\." + ID_PATTERN + ")*"); + private final ClassModelManager manager; - static Clazz load(Class classDef, ClassModelManager manager) + ReflectiveClassBuilder(ClassModelManager classModelManager) + { + this.manager = classModelManager; + } + + static Clazz load(Class classDef, ClassModelManager classModelManager) + { + return new ReflectiveClassBuilder(classModelManager).load(classDef); + } + + Clazz load(Class classDef) { final Clazz clazz = manager.haveClass(classDef.getSimpleName()); + final DTO dto = classDef.getAnnotation(DTO.class); + if (dto != null) + { + loadDto(dto, clazz); + } + final Class superClass = classDef.getSuperclass(); if (superClass != null && superClass != Object.class) { @@ -32,13 +48,22 @@ static Clazz load(Class classDef, ClassModelManager manager) for (final Field field : classDef.getDeclaredFields()) { - loadField(field, clazz, manager); + loadField(field, clazz, false); } return clazz; } - private static void loadField(Field field, Clazz clazz, ClassModelManager manager) + private void loadDto(DTO dto, Clazz clazz) + { + final Class model = dto.model(); + for (final Field field : model.getDeclaredFields()) + { + loadField(field, clazz, true); + } + } + + private void loadField(Field field, Clazz clazz, boolean dto) { if (field.isSynthetic()) { @@ -48,33 +73,40 @@ private static void loadField(Field field, Clazz clazz, ClassModelManager manage final Link link = field.getAnnotation(Link.class); if (link == null) { - loadAttribute(field, clazz, manager); + loadAttribute(field, clazz, false); + } + else if (dto) + { + loadAttribute(field, clazz, true); } else { - loadAssoc(field, link, clazz, manager); + loadAssoc(field, link, clazz); } } - private static void loadAttribute(Field field, Clazz clazz, ClassModelManager manager) + private void loadAttribute(Field field, Clazz clazz, boolean dto) { final String name = field.getName(); final CollectionType collectionType = getCollectionType(field.getType()); - final String type = getType(field, collectionType); + final String type = dto ? STRING : getType(field, collectionType); final Attribute attribute = manager.haveAttribute(clazz, name, type); attribute.setCollectionType(collectionType); attribute.setDescription(getDescription(field)); attribute.setSince(getSince(field)); - final InitialValue initialValue = field.getAnnotation(InitialValue.class); - if (initialValue != null) + if (!dto) { - attribute.setInitialization(initialValue.value()); + final InitialValue initialValue = field.getAnnotation(InitialValue.class); + if (initialValue != null) + { + attribute.setInitialization(initialValue.value()); + } } } - private static String getType(Field field, CollectionType collectionType) + private String getType(Field field, CollectionType collectionType) { final org.fulib.builder.reflect.Type type = field.getAnnotation(org.fulib.builder.reflect.Type.class); if (type != null) @@ -95,11 +127,11 @@ private static String getType(Field field, CollectionType collectionType) } throw new InvalidClassModelException( - String.format("%s.%s: cannot determine element type of %s", declaringClass.getSimpleName(), - field.getName(), field.getType().getSimpleName())); + String.format("%s.%s: cannot determine element type of %s", declaringClass.getSimpleName(), field.getName(), + field.getType().getSimpleName())); } - private static String toSource(Class base, Type type) + private String toSource(Class base, Type type) { final String input = type.getTypeName(); final Matcher matcher = CLASS_PATTERN.matcher(input); @@ -116,7 +148,7 @@ private static String toSource(Class base, Type type) return sb.toString(); } - private static void toSource(Class base, String className, StringBuilder out) + private void toSource(Class base, String className, StringBuilder out) { switch (className) { @@ -146,7 +178,8 @@ else if (resolvedPackage == base.getPackage()) { out.append(resolved.getSimpleName()); } - else if (resolved.getEnclosingClass() != null && ClassModelDecorator.class.isAssignableFrom(resolved.getEnclosingClass())) + else if (resolved.getEnclosingClass() != null && ClassModelDecorator.class.isAssignableFrom( + resolved.getEnclosingClass())) { // resolved is nested class within another GenModel out @@ -167,7 +200,7 @@ else if (resolved.getEnclosingClass() != null && ClassModelDecorator.class.isAss } } - private static CollectionType getCollectionType(Class type) + private CollectionType getCollectionType(Class type) { if (!Collection.class.isAssignableFrom(type)) { @@ -184,7 +217,7 @@ private static CollectionType getCollectionType(Class type) return CollectionType.of(collectionType); } - private static void loadAssoc(Field field, Link link, Clazz clazz, ClassModelManager manager) + private void loadAssoc(Field field, Link link, Clazz clazz) { final Class owner = field.getDeclaringClass(); final String name = field.getName(); @@ -214,7 +247,7 @@ private static void loadAssoc(Field field, Link link, Clazz clazz, ClassModelMan role.setSince(getSince(field)); } - private static void validateTargetClass(Class owner, String name, Class other) + private void validateTargetClass(Class owner, String name, Class other) { if (owner.getPackage() != other.getPackage()) { @@ -225,7 +258,7 @@ private static void validateTargetClass(Class owner, String name, Class ot } } - private static void validateLinkTarget(Class owner, String name, String otherName, Class other) + private void validateLinkTarget(Class owner, String name, String otherName, Class other) { final Field targetField; try @@ -265,7 +298,7 @@ private static void validateLinkTarget(Class owner, String name, String other } } - private static Class getOther(Field field, CollectionType collectionType) + private Class getOther(Field field, CollectionType collectionType) { final org.fulib.builder.reflect.Type type = field.getAnnotation(org.fulib.builder.reflect.Type.class); if (type != null) @@ -293,7 +326,7 @@ private static Class getOther(Field field, CollectionType collectionType) field.getName(), field.getType().getSimpleName())); } - private static Class getSiblingClass(Field field, String simpleSiblingName) + private Class getSiblingClass(Field field, String simpleSiblingName) { final Class declaringClass = field.getDeclaringClass(); final String name = declaringClass.getName(); @@ -312,13 +345,13 @@ private static Class getSiblingClass(Field field, String simpleSiblingName) } } - private static String getDescription(Field field) + private String getDescription(Field field) { final Description annotation = field.getAnnotation(Description.class); return annotation != null ? annotation.value() : null; } - private static String getSince(Field field) + private String getSince(Field field) { final Since annotation = field.getAnnotation(Since.class); return annotation != null ? annotation.value() : null; diff --git a/src/main/java/org/fulib/builder/reflect/DTO.java b/src/main/java/org/fulib/builder/reflect/DTO.java new file mode 100644 index 00000000..5d8f8502 --- /dev/null +++ b/src/main/java/org/fulib/builder/reflect/DTO.java @@ -0,0 +1,13 @@ +package org.fulib.builder.reflect; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface DTO +{ + Class model(); +} From efcc77ed555b85f3b9db50d27d29ee62e0c1189b Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Fri, 11 Jun 2021 17:42:39 +0200 Subject: [PATCH 2/5] feat: Implement DTO pick and omit --- .../org/fulib/builder/ReflectiveClassBuilder.java | 14 +++++++++++++- src/main/java/org/fulib/builder/reflect/DTO.java | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java b/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java index d3831eef..948acb99 100644 --- a/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java +++ b/src/main/java/org/fulib/builder/ReflectiveClassBuilder.java @@ -6,9 +6,14 @@ import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static org.fulib.builder.Type.*; @@ -57,9 +62,16 @@ Clazz load(Class classDef) private void loadDto(DTO dto, Clazz clazz) { final Class model = dto.model(); + final Set include = new HashSet<>(Arrays.asList(dto.pick())); + final Set exclude = new HashSet<>(Arrays.asList(dto.omit())); + for (final Field field : model.getDeclaredFields()) { - loadField(field, clazz, true); + final String name = field.getName(); + if ((include.isEmpty() || include.contains(name)) && !exclude.contains(name)) + { + loadField(field, clazz, true); + } } } diff --git a/src/main/java/org/fulib/builder/reflect/DTO.java b/src/main/java/org/fulib/builder/reflect/DTO.java index 5d8f8502..93c17226 100644 --- a/src/main/java/org/fulib/builder/reflect/DTO.java +++ b/src/main/java/org/fulib/builder/reflect/DTO.java @@ -10,4 +10,14 @@ public @interface DTO { Class model(); + + /** + * @return the names of fields that should be included. Ignored if empty. + */ + String[] pick() default {}; + + /** + * @return the names of fields that should be excluded + */ + String[] omit() default {}; } From 90861b0745c04ea21bdd279aa5ae736d43feb828 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Fri, 11 Jun 2021 17:53:28 +0200 Subject: [PATCH 3/5] test: Add @DTO tests --- .../builder/ReflectiveClassBuilderTest.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/test/java/org/fulib/builder/ReflectiveClassBuilderTest.java b/src/test/java/org/fulib/builder/ReflectiveClassBuilderTest.java index 46560d3d..4a77aeac 100644 --- a/src/test/java/org/fulib/builder/ReflectiveClassBuilderTest.java +++ b/src/test/java/org/fulib/builder/ReflectiveClassBuilderTest.java @@ -317,4 +317,61 @@ public void invalidLinkClassPackage() assertThat(ex.getMessage(), equalTo( "InvalidLinkClassPackage.student: invalid link: target class Student (org.fulib.builder.model) must be in the same package (org.fulib.builder)")); } + + @DTO(model = Person.class) + class PersonDto + {} + + @Test + public void dto() + { + final ClassModelManager cmm = new ClassModelManager(); + final Clazz personDto = ReflectiveClassBuilder.load(PersonDto.class, cmm); + + assertThat(personDto.getRole("links"), nullValue()); + + final Attribute name = personDto.getAttribute("name"); + assertThat(name.getType(), is(Type.STRING)); + + final Attribute friends = personDto.getAttribute("friends"); + assertThat(friends.getType(), is(Type.STRING)); + assertThat(friends.getCollectionType(), is(CollectionType.ArrayList)); + + final Attribute dateOfBirth = personDto.getAttribute("dateOfBirth"); + assertThat(dateOfBirth.getType(), is("import(java.util.Date)")); + } + + @DTO(model = Person.class, pick = { "friends" }) + class PersonLinksDto + {} + + @DTO(model = Person.class, omit = { "friends" }) + class PersonAttributesDto + {} + + @Test + public void dtoPickOmit() + { + final ClassModelManager cmm = new ClassModelManager(); + final Clazz personLinksDto = ReflectiveClassBuilder.load(PersonLinksDto.class, cmm); + + assertThat(personLinksDto.getAttribute("name"), nullValue()); + assertThat(personLinksDto.getAttribute("dateOfBirth"), nullValue()); + assertThat(personLinksDto.getRole("links"), nullValue()); + + final Attribute friends = personLinksDto.getAttribute("friends"); + assertThat(friends.getType(), is(Type.STRING)); + assertThat(friends.getCollectionType(), is(CollectionType.ArrayList)); + + final Clazz personAttributesDto = ReflectiveClassBuilder.load(PersonAttributesDto.class, cmm); + + final Attribute name = personAttributesDto.getAttribute("name"); + assertThat(name.getType(), is(Type.STRING)); + + final Attribute dateOfBirth = personAttributesDto.getAttribute("dateOfBirth"); + assertThat(dateOfBirth.getType(), is("import(java.util.Date)")); + + assertThat(personAttributesDto.getAttribute("links"), nullValue()); + assertThat(personAttributesDto.getRole("links"), nullValue()); + } } From 0a1771dd300309acab8fe3ff7e4e3c2505ace7bd Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sat, 12 Jun 2021 13:56:01 +0200 Subject: [PATCH 4/5] docs: Add DTO docs --- docs/definitions/10-dtos.md | 430 ++++++++++++++++++ docs/definitions/README.md | 1 + .../src/gen/java/org/fulib/docs/GenModel.java | 7 +- .../java/org/fulib/docs/dtos/dto/GenDtos.java | 28 ++ .../org/fulib/docs/dtos/model/GenModel.java | 33 ++ .../org/fulib/docs/dtos/dto/AddressDto.java | 42 ++ .../java/org/fulib/docs/dtos/dto/UserDto.java | 42 ++ .../org/fulib/docs/dtos/dto/classDiagram.png | Bin 0 -> 3591 bytes .../org/fulib/docs/dtos/dto/classModel.yaml | 66 +++ .../org/fulib/docs/dtos/model/Address.java | 133 ++++++ .../java/org/fulib/docs/dtos/model/User.java | 112 +++++ .../fulib/docs/dtos/model/classDiagram.png | Bin 0 -> 4743 bytes .../org/fulib/docs/dtos/model/classModel.yaml | 97 ++++ 13 files changed, 986 insertions(+), 5 deletions(-) create mode 100644 docs/definitions/10-dtos.md create mode 100644 test/src/gen/java/org/fulib/docs/dtos/dto/GenDtos.java create mode 100644 test/src/gen/java/org/fulib/docs/dtos/model/GenModel.java create mode 100644 test/src/main/java/org/fulib/docs/dtos/dto/AddressDto.java create mode 100644 test/src/main/java/org/fulib/docs/dtos/dto/UserDto.java create mode 100644 test/src/main/java/org/fulib/docs/dtos/dto/classDiagram.png create mode 100644 test/src/main/java/org/fulib/docs/dtos/dto/classModel.yaml create mode 100644 test/src/main/java/org/fulib/docs/dtos/model/Address.java create mode 100644 test/src/main/java/org/fulib/docs/dtos/model/User.java create mode 100644 test/src/main/java/org/fulib/docs/dtos/model/classDiagram.png create mode 100644 test/src/main/java/org/fulib/docs/dtos/model/classModel.yaml diff --git a/docs/definitions/10-dtos.md b/docs/definitions/10-dtos.md new file mode 100644 index 00000000..843d1c36 --- /dev/null +++ b/docs/definitions/10-dtos.md @@ -0,0 +1,430 @@ +# DTOs + +Fulib makes it easy to generate DTOs (Data Transfer Objects) from existing model classes without a lot of duplication. +We recommend putting all DTOs into a package and `GenDtos` class that are separate from your model. +Here's an example: + +`src/gen/java/org/example/dtos/model/GenModel`: + + +```java +public class GenModel implements ClassModelDecorator +{ + public class User + { + String id; + String name; + @Link("user") + Address address; + } + + public class Address + { + String id; + String city; + String street; + @Link("address") + User user; + } + + @Override + public void decorate(ClassModelManager m) + { + m.haveNestedClasses(GenModel.class); + } +} +``` + + +`src/gen/java/org/example/dtos/dto/GenDtos`: + + +```java +public class GenDtos implements ClassModelDecorator +{ + @DTO(model = GenModel.User.class, omit = { "id" }) + class UserDto + {} + + @DTO(model = GenModel.Address.class, pick = { "city", "street" }) + class AddressDto + {} + + @Override + public void decorate(ClassModelManager m) + { + // This omits PropertyChangeListeners etc. from the generated code + m.getClassModel().setDefaultPropertyStyle(Type.POJO); + m.haveNestedClasses(GenDtos.class); + } +} +``` + + +The example shows the basic usage of the `@DTO` annotation. + +* `model` sets the model class we want to copy fields from. +* `omit` is optional and specifies which fields should **not** be copied to the DTO class. +* `pick` is optional and specifies which fields **should** be copied to the DTO class. If `pick` is provided, all other fields will be ignored. + +Let's take a look at the generated code: + +
+ + src/main/java/org/example/dtos/dto/UserDto.java + + + ```java + public class UserDto + { + public static final String PROPERTY_NAME = "name"; + public static final String PROPERTY_ADDRESS = "address"; + private String name; + private String address; + + public String getName() + { + return this.name; + } + + public UserDto setName(String value) + { + this.name = value; + return this; + } + + public String getAddress() + { + return this.address; + } + + public UserDto setAddress(String value) + { + this.address = value; + return this; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getName()); + result.append(' ').append(this.getAddress()); + return result.substring(1); + } + } + ``` + +
+ +
+ + src/main/java/org/example/dtos/dto/AddressDto.java + + + + ```java + public class AddressDto + { + public static final String PROPERTY_CITY = "city"; + public static final String PROPERTY_STREET = "street"; + private String city; + private String street; + + public String getCity() + { + return this.city; + } + + public AddressDto setCity(String value) + { + this.city = value; + return this; + } + + public String getStreet() + { + return this.street; + } + + public AddressDto setStreet(String value) + { + this.street = value; + return this; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getCity()); + result.append(' ').append(this.getStreet()); + return result.substring(1); + } + } + ``` + +
+ +In the `UserDto` class, we can see that all attributes from `User` were copied over except for `id`, because it was specified in `omit`. +The `address` association in `User` was converted to a `String` field, which can hold the Address ID in our DTO. + +The `AddressDto` class contains only the `city` and `street` attributes, thanks to the `pick` array. + +For completeness, here is the generated code for the `User` and `Address` model classes. +Note how these use the default `Bean` property style, which generates PropertyChange support. + +
+ + src/main/java/org/example/dtos/model/User.java + + + + ```java + public class User + { + public static final String PROPERTY_ID = "id"; + public static final String PROPERTY_NAME = "name"; + public static final String PROPERTY_ADDRESS = "address"; + private String id; + private String name; + private Address address; + protected PropertyChangeSupport listeners; + + public String getId() + { + return this.id; + } + + public User setId(String value) + { + if (Objects.equals(value, this.id)) + { + return this; + } + + final String oldValue = this.id; + this.id = value; + this.firePropertyChange(PROPERTY_ID, oldValue, value); + return this; + } + + public String getName() + { + return this.name; + } + + public User setName(String value) + { + if (Objects.equals(value, this.name)) + { + return this; + } + + final String oldValue = this.name; + this.name = value; + this.firePropertyChange(PROPERTY_NAME, oldValue, value); + return this; + } + + public Address getAddress() + { + return this.address; + } + + public User setAddress(Address value) + { + if (this.address == value) + { + return this; + } + + final Address oldValue = this.address; + if (this.address != null) + { + this.address = null; + oldValue.setUser(null); + } + this.address = value; + if (value != null) + { + value.setUser(this); + } + this.firePropertyChange(PROPERTY_ADDRESS, oldValue, value); + return this; + } + + public boolean firePropertyChange(String propertyName, Object oldValue, Object newValue) + { + if (this.listeners != null) + { + this.listeners.firePropertyChange(propertyName, oldValue, newValue); + return true; + } + return false; + } + + public PropertyChangeSupport listeners() + { + if (this.listeners == null) + { + this.listeners = new PropertyChangeSupport(this); + } + return this.listeners; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getId()); + result.append(' ').append(this.getName()); + return result.substring(1); + } + + public void removeYou() + { + this.setAddress(null); + } + } + ``` + +
+ +
+ + src/main/java/org/example/dtos/model/Address.java + + + + ```java + public class Address + { + public static final String PROPERTY_ID = "id"; + public static final String PROPERTY_CITY = "city"; + public static final String PROPERTY_STREET = "street"; + public static final String PROPERTY_USER = "user"; + private String id; + private String city; + private String street; + private User user; + protected PropertyChangeSupport listeners; + + public String getId() + { + return this.id; + } + + public Address setId(String value) + { + if (Objects.equals(value, this.id)) + { + return this; + } + + final String oldValue = this.id; + this.id = value; + this.firePropertyChange(PROPERTY_ID, oldValue, value); + return this; + } + + public String getCity() + { + return this.city; + } + + public Address setCity(String value) + { + if (Objects.equals(value, this.city)) + { + return this; + } + + final String oldValue = this.city; + this.city = value; + this.firePropertyChange(PROPERTY_CITY, oldValue, value); + return this; + } + + public String getStreet() + { + return this.street; + } + + public Address setStreet(String value) + { + if (Objects.equals(value, this.street)) + { + return this; + } + + final String oldValue = this.street; + this.street = value; + this.firePropertyChange(PROPERTY_STREET, oldValue, value); + return this; + } + + public User getUser() + { + return this.user; + } + + public Address setUser(User value) + { + if (this.user == value) + { + return this; + } + + final User oldValue = this.user; + if (this.user != null) + { + this.user = null; + oldValue.setAddress(null); + } + this.user = value; + if (value != null) + { + value.setAddress(this); + } + this.firePropertyChange(PROPERTY_USER, oldValue, value); + return this; + } + + public boolean firePropertyChange(String propertyName, Object oldValue, Object newValue) + { + if (this.listeners != null) + { + this.listeners.firePropertyChange(propertyName, oldValue, newValue); + return true; + } + return false; + } + + public PropertyChangeSupport listeners() + { + if (this.listeners == null) + { + this.listeners = new PropertyChangeSupport(this); + } + return this.listeners; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getId()); + result.append(' ').append(this.getCity()); + result.append(' ').append(this.getStreet()); + return result.substring(1); + } + + public void removeYou() + { + this.setUser(null); + } + } + ``` + +
diff --git a/docs/definitions/README.md b/docs/definitions/README.md index 11cdecb6..1d84f457 100644 --- a/docs/definitions/README.md +++ b/docs/definitions/README.md @@ -11,3 +11,4 @@ This chapter explains the various options for defining class models. * [Inheritance](7-inheritance.md) * [Methods](8-methods.md) * [EMF and Ecore files](9-emf-ecore.md) +* [DTOs](10-dtos.md) diff --git a/test/src/gen/java/org/fulib/docs/GenModel.java b/test/src/gen/java/org/fulib/docs/GenModel.java index d0a65386..07cfa560 100644 --- a/test/src/gen/java/org/fulib/docs/GenModel.java +++ b/test/src/gen/java/org/fulib/docs/GenModel.java @@ -3,15 +3,12 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; import org.fulib.builder.ClassModelDecorator; import org.fulib.builder.ClassModelManager; -import org.fulib.builder.reflect.Type; -import org.fulib.builder.reflect.Description; -import org.fulib.builder.reflect.InitialValue; -import org.fulib.builder.reflect.Link; -import org.fulib.builder.reflect.Since; +import org.fulib.builder.reflect.*; import java.util.ArrayList; import java.util.List; +@SuppressWarnings({ "unused", "InnerClassMayBeStatic" }) public class GenModel implements ClassModelDecorator { // start_code_fragment: docs.GenModel.Person diff --git a/test/src/gen/java/org/fulib/docs/dtos/dto/GenDtos.java b/test/src/gen/java/org/fulib/docs/dtos/dto/GenDtos.java new file mode 100644 index 00000000..f1b8d5e2 --- /dev/null +++ b/test/src/gen/java/org/fulib/docs/dtos/dto/GenDtos.java @@ -0,0 +1,28 @@ +package org.fulib.docs.dtos.dto; + +import org.fulib.builder.ClassModelDecorator; +import org.fulib.builder.ClassModelManager; +import org.fulib.builder.Type; +import org.fulib.builder.reflect.DTO; +import org.fulib.docs.dtos.model.GenModel; + +// start_code_fragment: docs.dtos.GenDtos +public class GenDtos implements ClassModelDecorator +{ + @DTO(model = GenModel.User.class, omit = { "id" }) + class UserDto + {} + + @DTO(model = GenModel.Address.class, pick = { "city", "street" }) + class AddressDto + {} + + @Override + public void decorate(ClassModelManager m) + { + // This omits PropertyChangeListeners etc. from the generated code + m.getClassModel().setDefaultPropertyStyle(Type.POJO); + m.haveNestedClasses(GenDtos.class); + } +} +// end_code_fragment: diff --git a/test/src/gen/java/org/fulib/docs/dtos/model/GenModel.java b/test/src/gen/java/org/fulib/docs/dtos/model/GenModel.java new file mode 100644 index 00000000..df61399c --- /dev/null +++ b/test/src/gen/java/org/fulib/docs/dtos/model/GenModel.java @@ -0,0 +1,33 @@ +package org.fulib.docs.dtos.model; + +import org.fulib.builder.ClassModelDecorator; +import org.fulib.builder.ClassModelManager; +import org.fulib.builder.reflect.Link; + +// start_code_fragment: docs.dtos.GenModel +public class GenModel implements ClassModelDecorator +{ + public class User + { + String id; + String name; + @Link("user") + Address address; + } + + public class Address + { + String id; + String city; + String street; + @Link("address") + User user; + } + + @Override + public void decorate(ClassModelManager m) + { + m.haveNestedClasses(GenModel.class); + } +} +// end_code_fragment: diff --git a/test/src/main/java/org/fulib/docs/dtos/dto/AddressDto.java b/test/src/main/java/org/fulib/docs/dtos/dto/AddressDto.java new file mode 100644 index 00000000..e40f5e1e --- /dev/null +++ b/test/src/main/java/org/fulib/docs/dtos/dto/AddressDto.java @@ -0,0 +1,42 @@ +package org.fulib.docs.dtos.dto; + +// start_code_fragment: docs.dtos.AddressDto +public class AddressDto +{ + public static final String PROPERTY_CITY = "city"; + public static final String PROPERTY_STREET = "street"; + private String city; + private String street; + + public String getCity() + { + return this.city; + } + + public AddressDto setCity(String value) + { + this.city = value; + return this; + } + + public String getStreet() + { + return this.street; + } + + public AddressDto setStreet(String value) + { + this.street = value; + return this; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getCity()); + result.append(' ').append(this.getStreet()); + return result.substring(1); + } +} +// end_code_fragment: diff --git a/test/src/main/java/org/fulib/docs/dtos/dto/UserDto.java b/test/src/main/java/org/fulib/docs/dtos/dto/UserDto.java new file mode 100644 index 00000000..8d4c481e --- /dev/null +++ b/test/src/main/java/org/fulib/docs/dtos/dto/UserDto.java @@ -0,0 +1,42 @@ +package org.fulib.docs.dtos.dto; + +// start_code_fragment: docs.dtos.UserDto +public class UserDto +{ + public static final String PROPERTY_NAME = "name"; + public static final String PROPERTY_ADDRESS = "address"; + private String name; + private String address; + + public String getName() + { + return this.name; + } + + public UserDto setName(String value) + { + this.name = value; + return this; + } + + public String getAddress() + { + return this.address; + } + + public UserDto setAddress(String value) + { + this.address = value; + return this; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getName()); + result.append(' ').append(this.getAddress()); + return result.substring(1); + } +} +// end_code_fragment: diff --git a/test/src/main/java/org/fulib/docs/dtos/dto/classDiagram.png b/test/src/main/java/org/fulib/docs/dtos/dto/classDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..dc3d3919898874d890552d61b2888c1ed653e42f GIT binary patch literal 3591 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 Glm7x8XYsKB literal 0 HcmV?d00001 diff --git a/test/src/main/java/org/fulib/docs/dtos/dto/classModel.yaml b/test/src/main/java/org/fulib/docs/dtos/dto/classModel.yaml new file mode 100644 index 00000000..44c274c8 --- /dev/null +++ b/test/src/main/java/org/fulib/docs/dtos/dto/classModel.yaml @@ -0,0 +1,66 @@ +- c: org.fulib.classmodel.ClassModel + classes: addressDto userDto + defaultCollectionType: c1 + defaultPropertyStyle: POJO + defaultRoleType: "java.util.ArrayList<%s>" + mainJavaDir: "src/main/java" + packageName: org.fulib.docs.dtos.dto + packageSrcFolder: "src/main/java/org/fulib/docs/dtos/dto" + +- addressDto: org.fulib.classmodel.Clazz + attributes: addressDto_city addressDto_street + model: c + modified: false + name: AddressDto + propertyStyle: POJO + +- userDto: org.fulib.classmodel.Clazz + attributes: userDto_name userDto_address + model: c + modified: false + name: UserDto + propertyStyle: POJO + +- c1: org.fulib.classmodel.CollectionType + implClass: class java.util.ArrayList + implTemplate: "java.util.ArrayList<%s>" + itf: org.fulib.classmodel.CollectionInterface.List + qualifiedImplName: java.util.ArrayList + simpleImplName: ArrayList + +- addressDto_city: org.fulib.classmodel.Attribute + clazz: addressDto + id: AddressDto_city + modified: false + name: city + propertyStyle: POJO + type: String + typeSignature: String + +- addressDto_street: org.fulib.classmodel.Attribute + clazz: addressDto + id: AddressDto_street + modified: false + name: street + propertyStyle: POJO + type: String + typeSignature: String + +- userDto_name: org.fulib.classmodel.Attribute + clazz: userDto + id: UserDto_name + modified: false + name: name + propertyStyle: POJO + type: String + typeSignature: String + +- userDto_address: org.fulib.classmodel.Attribute + clazz: userDto + id: UserDto_address + modified: false + name: address + propertyStyle: POJO + type: String + typeSignature: String + diff --git a/test/src/main/java/org/fulib/docs/dtos/model/Address.java b/test/src/main/java/org/fulib/docs/dtos/model/Address.java new file mode 100644 index 00000000..1b1d0454 --- /dev/null +++ b/test/src/main/java/org/fulib/docs/dtos/model/Address.java @@ -0,0 +1,133 @@ +package org.fulib.docs.dtos.model; +import java.util.Objects; +import java.beans.PropertyChangeSupport; + +// start_code_fragment: docs.dtos.Address +public class Address +{ + public static final String PROPERTY_ID = "id"; + public static final String PROPERTY_CITY = "city"; + public static final String PROPERTY_STREET = "street"; + public static final String PROPERTY_USER = "user"; + private String id; + private String city; + private String street; + private User user; + protected PropertyChangeSupport listeners; + + public String getId() + { + return this.id; + } + + public Address setId(String value) + { + if (Objects.equals(value, this.id)) + { + return this; + } + + final String oldValue = this.id; + this.id = value; + this.firePropertyChange(PROPERTY_ID, oldValue, value); + return this; + } + + public String getCity() + { + return this.city; + } + + public Address setCity(String value) + { + if (Objects.equals(value, this.city)) + { + return this; + } + + final String oldValue = this.city; + this.city = value; + this.firePropertyChange(PROPERTY_CITY, oldValue, value); + return this; + } + + public String getStreet() + { + return this.street; + } + + public Address setStreet(String value) + { + if (Objects.equals(value, this.street)) + { + return this; + } + + final String oldValue = this.street; + this.street = value; + this.firePropertyChange(PROPERTY_STREET, oldValue, value); + return this; + } + + public User getUser() + { + return this.user; + } + + public Address setUser(User value) + { + if (this.user == value) + { + return this; + } + + final User oldValue = this.user; + if (this.user != null) + { + this.user = null; + oldValue.setAddress(null); + } + this.user = value; + if (value != null) + { + value.setAddress(this); + } + this.firePropertyChange(PROPERTY_USER, oldValue, value); + return this; + } + + public boolean firePropertyChange(String propertyName, Object oldValue, Object newValue) + { + if (this.listeners != null) + { + this.listeners.firePropertyChange(propertyName, oldValue, newValue); + return true; + } + return false; + } + + public PropertyChangeSupport listeners() + { + if (this.listeners == null) + { + this.listeners = new PropertyChangeSupport(this); + } + return this.listeners; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getId()); + result.append(' ').append(this.getCity()); + result.append(' ').append(this.getStreet()); + return result.substring(1); + } + + public void removeYou() + { + this.setUser(null); + } +} +// end_code_fragment: diff --git a/test/src/main/java/org/fulib/docs/dtos/model/User.java b/test/src/main/java/org/fulib/docs/dtos/model/User.java new file mode 100644 index 00000000..69945085 --- /dev/null +++ b/test/src/main/java/org/fulib/docs/dtos/model/User.java @@ -0,0 +1,112 @@ +package org.fulib.docs.dtos.model; +import java.util.Objects; +import java.beans.PropertyChangeSupport; + +// start_code_fragment: docs.dtos.User +public class User +{ + public static final String PROPERTY_ID = "id"; + public static final String PROPERTY_NAME = "name"; + public static final String PROPERTY_ADDRESS = "address"; + private String id; + private String name; + private Address address; + protected PropertyChangeSupport listeners; + + public String getId() + { + return this.id; + } + + public User setId(String value) + { + if (Objects.equals(value, this.id)) + { + return this; + } + + final String oldValue = this.id; + this.id = value; + this.firePropertyChange(PROPERTY_ID, oldValue, value); + return this; + } + + public String getName() + { + return this.name; + } + + public User setName(String value) + { + if (Objects.equals(value, this.name)) + { + return this; + } + + final String oldValue = this.name; + this.name = value; + this.firePropertyChange(PROPERTY_NAME, oldValue, value); + return this; + } + + public Address getAddress() + { + return this.address; + } + + public User setAddress(Address value) + { + if (this.address == value) + { + return this; + } + + final Address oldValue = this.address; + if (this.address != null) + { + this.address = null; + oldValue.setUser(null); + } + this.address = value; + if (value != null) + { + value.setUser(this); + } + this.firePropertyChange(PROPERTY_ADDRESS, oldValue, value); + return this; + } + + public boolean firePropertyChange(String propertyName, Object oldValue, Object newValue) + { + if (this.listeners != null) + { + this.listeners.firePropertyChange(propertyName, oldValue, newValue); + return true; + } + return false; + } + + public PropertyChangeSupport listeners() + { + if (this.listeners == null) + { + this.listeners = new PropertyChangeSupport(this); + } + return this.listeners; + } + + @Override + public String toString() + { + final StringBuilder result = new StringBuilder(); + result.append(' ').append(this.getId()); + result.append(' ').append(this.getName()); + return result.substring(1); + } + + public void removeYou() + { + this.setAddress(null); + } +} +// end_code_fragment: diff --git a/test/src/main/java/org/fulib/docs/dtos/model/classDiagram.png b/test/src/main/java/org/fulib/docs/dtos/model/classDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..a3f54b3b92d2951728040cb25aec14ab6dcb0e2d GIT binary patch literal 4743 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 literal 0 HcmV?d00001 diff --git a/test/src/main/java/org/fulib/docs/dtos/model/classModel.yaml b/test/src/main/java/org/fulib/docs/dtos/model/classModel.yaml new file mode 100644 index 00000000..ee46ad9f --- /dev/null +++ b/test/src/main/java/org/fulib/docs/dtos/model/classModel.yaml @@ -0,0 +1,97 @@ +- c: org.fulib.classmodel.ClassModel + classes: address user + defaultCollectionType: c1 + defaultPropertyStyle: Bean + defaultRoleType: "java.util.ArrayList<%s>" + mainJavaDir: "src/main/java" + packageName: org.fulib.docs.dtos.model + packageSrcFolder: "src/main/java/org/fulib/docs/dtos/model" + +- address: org.fulib.classmodel.Clazz + attributes: address_id address_city address_street + model: c + modified: false + name: Address + propertyStyle: Bean + roles: address_user + +- user: org.fulib.classmodel.Clazz + attributes: user_id user_name + model: c + modified: false + name: User + propertyStyle: Bean + roles: user_address + +- c1: org.fulib.classmodel.CollectionType + implClass: class java.util.ArrayList + implTemplate: "java.util.ArrayList<%s>" + itf: org.fulib.classmodel.CollectionInterface.List + qualifiedImplName: java.util.ArrayList + simpleImplName: ArrayList + +- address_id: org.fulib.classmodel.Attribute + clazz: address + id: Address_id + modified: false + name: id + propertyStyle: Bean + type: String + typeSignature: String + +- address_city: org.fulib.classmodel.Attribute + clazz: address + id: Address_city + modified: false + name: city + propertyStyle: Bean + type: String + typeSignature: String + +- address_street: org.fulib.classmodel.Attribute + clazz: address + id: Address_street + modified: false + name: street + propertyStyle: Bean + type: String + typeSignature: String + +- address_user: org.fulib.classmodel.AssocRole + aggregation: false + cardinality: 1 + clazz: address + id: Address_user + modified: false + name: user + other: user_address + propertyStyle: Bean + +- user_id: org.fulib.classmodel.Attribute + clazz: user + id: User_id + modified: false + name: id + propertyStyle: Bean + type: String + typeSignature: String + +- user_name: org.fulib.classmodel.Attribute + clazz: user + id: User_name + modified: false + name: name + propertyStyle: Bean + type: String + typeSignature: String + +- user_address: org.fulib.classmodel.AssocRole + aggregation: false + cardinality: 1 + clazz: user + id: User_address + modified: false + name: address + other: address_user + propertyStyle: Bean + From 97ac422dbd6bf6211e5011aa46242b19c41ef64e Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sat, 12 Jun 2021 14:00:35 +0200 Subject: [PATCH 5/5] docs: Add DTO JavaDocs --- src/main/java/org/fulib/builder/reflect/DTO.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/fulib/builder/reflect/DTO.java b/src/main/java/org/fulib/builder/reflect/DTO.java index 93c17226..58baa5df 100644 --- a/src/main/java/org/fulib/builder/reflect/DTO.java +++ b/src/main/java/org/fulib/builder/reflect/DTO.java @@ -5,10 +5,19 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Allows creating Data Transfer Object (DTO) classes by copying attributes from a model class. + * Associations are automatically converted to String attributes meant for holding the ID of the link target. + * + * @since 1.6 + */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface DTO { + /** + * @return the model class to copy attributes from + */ Class model(); /**